logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: b1e75c25bd50180e715afde70c6e659e7509a3f3
parent 6649baaac94348bbf09015eeb2c8eeea714096db
Author: tusooa <tusooa@kazv.moe>
Date:   Sun, 22 Jan 2023 09:34:01 -0500

Merge remote-tracking branch 'upstream/develop' into birthdays

Diffstat:

M.babelrc2+-
M.gitignore1+
A.gitlab/issue_templates/Bug.md25+++++++++++++++++++++++++
A.gitlab/issue_templates/Suggestion.md11+++++++++++
A.gitlab/issue_templates/default.md7+++++++
A.gitlab/merge_request_templates/default.md30++++++++++++++++++++++++++++++
M.node-version2+-
M.stylelintrc.json28+++++++++++++++++++++++++---
MCHANGELOG.md51++++++++++++++++++++++++++++++++++++++-------------
MCONTRIBUTORS.md2++
MREADME.md27+++++++++++----------------
Mbuild/build.js7+++++++
Mbuild/dev-server.js27++++++++++++++++-----------
Abuild/update-emoji.js27+++++++++++++++++++++++++++
Mbuild/webpack.base.conf.js35+++++++++++++++++------------------
Mbuild/webpack.dev.conf.js2+-
Mbuild/webpack.prod.conf.js13++++++++-----
Mdocs/HACKING.md12+++++++++++-
Aimage-1.png0
Aimage.png0
Mindex.html1+
Mpackage.json155+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/App.js17+++++++++++++++++
Msrc/App.scss139++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/App.vue15++++++++++-----
Asrc/_mixins.scss18++++++++++++++++++
Msrc/_variables.scss14++++++++------
Asrc/assets/pleromatan_apology.png0
Asrc/assets/pleromatan_apology_fox.png0
Asrc/assets/pleromatan_apology_fox_mask.png0
Asrc/assets/pleromatan_apology_mask.png0
Msrc/boot/after_store.js9++++++++-
Msrc/boot/routes.js16++++++++++++++--
Msrc/components/about/about.vue3---
Msrc/components/account_actions/account_actions.js7++++++-
Msrc/components/account_actions/account_actions.vue11++++++++++-
Asrc/components/announcement/announcement.js108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/announcement/announcement.vue136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/announcement_editor/announcement_editor.js13+++++++++++++
Asrc/components/announcement_editor/announcement_editor.vue60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/announcements_page/announcements_page.js58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/announcements_page/announcements_page.vue80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/async_component_error/async_component_error.vue5+++--
Msrc/components/attachment/attachment.js7++++++-
Msrc/components/attachment/attachment.scss47+++++++++++++++++++++++++++--------------------
Msrc/components/attachment/attachment.vue5+++--
Msrc/components/autosuggest/autosuggest.vue4++--
Msrc/components/avatar_list/avatar_list.vue2+-
Msrc/components/basic_user_card/basic_user_card.js4+++-
Msrc/components/basic_user_card/basic_user_card.vue10++++------
Msrc/components/block_card/block_card.vue1+
Msrc/components/chat/chat.js10++++++----
Msrc/components/chat/chat.scss4++--
Msrc/components/chat/chat.vue4++--
Msrc/components/chat_list/chat_list.vue2+-
Msrc/components/chat_list_item/chat_list_item.scss9++++-----
Msrc/components/chat_list_item/chat_list_item.vue4++--
Msrc/components/chat_message/chat_message.scss94++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/components/chat_message/chat_message.vue4++--
Msrc/components/chat_new/chat_new.scss2+-
Msrc/components/chat_new/chat_new.vue4++--
Msrc/components/chat_title/chat_title.vue2+-
Msrc/components/checkbox/checkbox.vue16++++++++--------
Msrc/components/color_input/color_input.scss27++++++++++++++++-----------
Msrc/components/contrast_ratio/contrast_ratio.vue1-
Msrc/components/conversation/conversation.js22++++++++++++++++++++--
Msrc/components/conversation/conversation.vue99++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/components/desktop_nav/desktop_nav.scss35++++++++++++++++++++++++++++++++---
Msrc/components/desktop_nav/desktop_nav.vue5+++--
Msrc/components/dialog_modal/dialog_modal.vue10+++++-----
Asrc/components/edit_status_modal/edit_status_modal.js75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/edit_status_modal/edit_status_modal.vue49+++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/emoji_input/emoji_input.js196+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/components/emoji_input/emoji_input.vue228++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/components/emoji_input/suggestor.js45+++++++++++++++++++++++----------------------
Msrc/components/emoji_picker/emoji_picker.js341+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/components/emoji_picker/emoji_picker.scss88+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/components/emoji_picker/emoji_picker.vue213+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/components/emoji_reactions/emoji_reactions.vue87+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/components/extra_buttons/extra_buttons.js49++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/components/extra_buttons/extra_buttons.vue71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/components/favorite_button/favorite_button.js17++++++++++++++---
Msrc/components/favorite_button/favorite_button.vue63+++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/components/flash/flash.vue5+++--
Msrc/components/follow_card/follow_card.js4+++-
Msrc/components/follow_card/follow_card.vue14++++++++++++--
Msrc/components/follow_request_card/follow_request_card.vue4++--
Msrc/components/font_control/font_control.vue5++++-
Msrc/components/gallery/gallery.js1+
Msrc/components/gallery/gallery.vue101+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/components/global_notice_list/global_notice_list.vue9++++++---
Msrc/components/interactions/interactions.js5++++-
Msrc/components/interactions/interactions.vue9+++++++++
Msrc/components/link-preview/link-preview.vue5+++--
Msrc/components/list/list.vue2+-
Asrc/components/lists/lists.js27+++++++++++++++++++++++++++
Asrc/components/lists/lists.vue33+++++++++++++++++++++++++++++++++
Asrc/components/lists_card/lists_card.js16++++++++++++++++
Asrc/components/lists_card/lists_card.vue52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/lists_edit/lists_edit.js145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/lists_edit/lists_edit.vue228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/lists_menu/lists_menu_content.js22++++++++++++++++++++++
Asrc/components/lists_menu/lists_menu_content.vue12++++++++++++
Asrc/components/lists_timeline/lists_timeline.js36++++++++++++++++++++++++++++++++++++
Asrc/components/lists_timeline/lists_timeline.vue10++++++++++
Asrc/components/lists_user_search/lists_user_search.js51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/lists_user_search/lists_user_search.vue47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/login_form/login_form.vue7+++----
Msrc/components/media_modal/media_modal.js5+++++
Msrc/components/media_modal/media_modal.vue58++++++++++++++++++++++++++++++++--------------------------
Msrc/components/media_upload/media_upload.vue2+-
Msrc/components/mention_link/mention_link.js2++
Msrc/components/mention_link/mention_link.scss7++-----
Msrc/components/mention_link/mention_link.vue3+++
Msrc/components/mentions_line/mentions_line.scss2+-
Msrc/components/mobile_nav/mobile_nav.js32++++++++++++++++++++++++--------
Msrc/components/mobile_nav/mobile_nav.vue73++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/components/mobile_post_status_button/mobile_post_status_button.js3++-
Msrc/components/mobile_post_status_button/mobile_post_status_button.vue6+++---
Msrc/components/modal/modal.vue7++++---
Msrc/components/moderation_tools/moderation_tools.js16++++++++++++++--
Msrc/components/moderation_tools/moderation_tools.vue16+++++++++++-----
Msrc/components/mrf_transparency_panel/mrf_transparency_panel.scss14++++++++------
Msrc/components/mrf_transparency_panel/mrf_transparency_panel.vue4++--
Msrc/components/mute_card/mute_card.vue1+
Msrc/components/nav_panel/nav_panel.js87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/components/nav_panel/nav_panel.vue220+++++++++++++++++++++++++++++++++++--------------------------------------------
Asrc/components/navigation/filter.js19+++++++++++++++++++
Asrc/components/navigation/navigation.js82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/navigation/navigation_entry.js51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/navigation/navigation_entry.vue135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/navigation/navigation_pins.js94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/navigation/navigation_pins.vue75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/notification/notification.js20++++++++++++++------
Msrc/components/notification/notification.scss17+++++++++--------
Msrc/components/notification/notification.vue65++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/components/notifications/notification_filters.vue19-------------------
Msrc/components/notifications/notifications.js46++++++++++++++++++++++++++++++++++++++++++----
Msrc/components/notifications/notifications.scss25++++++++++++++++++++-----
Msrc/components/notifications/notifications.vue34++++++++++++++++++++++++++++++----
Asrc/components/optional_router_link/optional_router_link.vue23+++++++++++++++++++++++
Msrc/components/panel_loading/panel_loading.vue3++-
Msrc/components/password_reset/password_reset.vue2+-
Msrc/components/poll/poll.vue12+++++++++++-
Msrc/components/poll/poll_form.vue3++-
Msrc/components/popover/popover.js49+++++++++++++++++++++++++++++++++++++++++++++----
Msrc/components/popover/popover.vue50++++++++++++++++++++++++++++++++------------------
Msrc/components/post_status_form/post_status_form.js57+++++++++++++++++++++++++++++++++++++++++----------------
Msrc/components/post_status_form/post_status_form.vue85++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Asrc/components/quick_filter_settings/quick_filter_settings.js70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/quick_filter_settings/quick_filter_settings.vue88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/quick_view_settings/quick_view_settings.js69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/quick_view_settings/quick_view_settings.vue75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/react_button/react_button.js94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/components/react_button/react_button.vue65++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/components/registration/registration.vue10+++++-----
Msrc/components/remote_user_resolver/remote_user_resolver.vue3---
Asrc/components/remove_follower_button/remove_follower_button.js25+++++++++++++++++++++++++
Asrc/components/remove_follower_button/remove_follower_button.vue13+++++++++++++
Msrc/components/reply_button/reply_button.js15+++++++++++++--
Msrc/components/reply_button/reply_button.vue48++++++++++++++++++++++++++++++++++++++++--------
Asrc/components/report/report.js34++++++++++++++++++++++++++++++++++
Asrc/components/report/report.scss43+++++++++++++++++++++++++++++++++++++++++++
Asrc/components/report/report.vue74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/retweet_button/retweet_button.js17+++++++++++++++--
Msrc/components/retweet_button/retweet_button.vue63+++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/components/rich_content/rich_content.jsx15+++++++++------
Msrc/components/rich_content/rich_content.scss10+++++++---
Msrc/components/scope_selector/scope_selector.vue3+--
Msrc/components/search/search.js39++++++++++++++++++++++++++++++---------
Msrc/components/search/search.vue44+++++++++++++++++++++++++++++++++++---------
Msrc/components/search_bar/search_bar.vue4+++-
Msrc/components/select/select.vue7++-----
Msrc/components/selectable_list/selectable_list.vue3++-
Msrc/components/settings_modal/helpers/boolean_setting.js9+++++++++
Msrc/components/settings_modal/helpers/boolean_setting.vue7++++++-
Msrc/components/settings_modal/helpers/choice_setting.js3+++
Msrc/components/settings_modal/helpers/choice_setting.vue10++++------
Msrc/components/settings_modal/helpers/integer_setting.js3+++
Msrc/components/settings_modal/helpers/integer_setting.vue5++++-
Asrc/components/settings_modal/helpers/size_setting.js67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/settings_modal/helpers/size_setting.vue55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/settings_modal/settings_modal.scss51++++++++++++++++++++++++++++-----------------------
Msrc/components/settings_modal/settings_modal_content.scss8+++++---
Msrc/components/settings_modal/tabs/data_import_export_tab.vue10++++++++++
Msrc/components/settings_modal/tabs/filtering_tab.js18+++++++-----------
Msrc/components/settings_modal/tabs/general_tab.js21+++++++++++++++++++++
Msrc/components/settings_modal/tabs/general_tab.vue96+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/components/settings_modal/tabs/mutes_and_blocks_tab.scss44++++++++++++++++++++++----------------------
Msrc/components/settings_modal/tabs/mutes_and_blocks_tab.vue2+-
Msrc/components/settings_modal/tabs/profile_tab.js6+++---
Msrc/components/settings_modal/tabs/profile_tab.scss7++++---
Msrc/components/settings_modal/tabs/security_tab/mfa.vue11+++++++----
Msrc/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue3++-
Msrc/components/settings_modal/tabs/security_tab/security_tab.vue2+-
Msrc/components/settings_modal/tabs/theme_tab/preview.vue15++++++++-------
Msrc/components/settings_modal/tabs/theme_tab/theme_tab.js4++++
Msrc/components/settings_modal/tabs/theme_tab/theme_tab.scss120+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/components/shadow_control/shadow_control.vue40+++++++++++++++++++++++-----------------
Msrc/components/shout_panel/shout_panel.vue2+-
Msrc/components/side_drawer/side_drawer.js24++++++++++++++++++------
Msrc/components/side_drawer/side_drawer.vue64+++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/components/staff_panel/staff_panel.js4++--
Msrc/components/staff_panel/staff_panel.vue1-
Msrc/components/status/status.js10+++++++++-
Msrc/components/status/status.scss13+++++++------
Msrc/components/status/status.vue40+++++++++++++++++++++++++++++-----------
Msrc/components/status_body/status_body.scss13++++++-------
Msrc/components/status_content/status_content.vue1+
Asrc/components/status_history_modal/status_history_modal.js60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/status_history_modal/status_history_modal.vue47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/status_popover/status_popover.vue3+--
Msrc/components/sticker_picker/sticker_picker.vue7++++++-
Msrc/components/still-image/still-image.js28++++++++++++++++++++++++++--
Msrc/components/still-image/still-image.vue12+++++++-----
Msrc/components/swipe_click/swipe_click.js7+++++++
Msrc/components/tab_switcher/tab_switcher.scss51+++++++++++++++++++++++++++++++--------------------
Msrc/components/terms_of_service_panel/terms_of_service_panel.vue2+-
Msrc/components/thread_tree/thread_tree.vue8+++++---
Msrc/components/timeago/timeago.vue21+++++++++++++++++++--
Msrc/components/timeline/timeline.js35++++++++++++++++++++++++++++++-----
Msrc/components/timeline/timeline.scss38++++++++++++++++++++++++++++++++------
Msrc/components/timeline/timeline.vue92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Dsrc/components/timeline/timeline_quick_settings.js67-------------------------------------------------------------------
Dsrc/components/timeline/timeline_quick_settings.vue109-------------------------------------------------------------------------------
Msrc/components/timeline_menu/timeline_menu.js34++++++++++++++++++++++++++++++++--
Msrc/components/timeline_menu/timeline_menu.vue150+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/components/timeline_menu/timeline_menu_content.js29-----------------------------
Dsrc/components/timeline_menu/timeline_menu_content.vue66------------------------------------------------------------------
Asrc/components/unicode_domain_indicator/unicode_domain_indicator.vue26++++++++++++++++++++++++++
Asrc/components/update_notification/update_notification.js69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/update_notification/update_notification.scss115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/update_notification/update_notification.vue103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/user_avatar/user_avatar.vue5++---
Msrc/components/user_card/user_card.js19+++++++++++++++++--
Msrc/components/user_card/user_card.scss107+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/components/user_card/user_card.vue17++++++++++-------
Asrc/components/user_link/user_link.vue38++++++++++++++++++++++++++++++++++++++
Asrc/components/user_list_menu/user_list_menu.js93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/user_list_menu/user_list_menu.vue38++++++++++++++++++++++++++++++++++++++
Msrc/components/user_list_popover/user_list_popover.js2++
Msrc/components/user_list_popover/user_list_popover.vue4++--
Asrc/components/user_note/user_note.js45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/user_note/user_note.vue88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/user_panel/user_panel.vue4++--
Msrc/components/user_popover/user_popover.js4++--
Msrc/components/user_popover/user_popover.vue6++++--
Msrc/components/user_profile/user_profile.js15++++++++++-----
Msrc/components/user_profile/user_profile.vue7+++++--
Msrc/components/user_reporting_modal/user_reporting_modal.js16++++++++++------
Msrc/components/user_reporting_modal/user_reporting_modal.vue14+++++++++-----
Msrc/components/who_to_follow/who_to_follow.vue3---
Msrc/components/who_to_follow_panel/who_to_follow_panel.vue16++++++++++------
Msrc/hocs/with_load_more/with_load_more.scss3+--
Msrc/hocs/with_subscription/with_subscription.scss3+--
Msrc/i18n/ar.json17+++++++++++++++++
Msrc/i18n/en.json150++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/i18n/eo.json320+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/i18n/fr.json127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/i18n/ko.json828++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Asrc/i18n/languages.js53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/i18n/messages.js46+++++++++++++---------------------------------
Msrc/i18n/nl.json416+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/i18n/ru.json9+++++++++
Msrc/i18n/uk.json192++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/lib/persisted_state.js1+
Msrc/main.js14+++++++++++++-
Asrc/modules/announcements.js135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/modules/api.js29++++++++++++++++++++++++++---
Msrc/modules/config.js22+++++++++++++++++-----
Asrc/modules/editStatus.js25+++++++++++++++++++++++++
Msrc/modules/instance.js190++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Asrc/modules/lists.js130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/modules/reports.js44+++++++++++++++++++++++++++++++++++---------
Asrc/modules/serverSideStorage.js436+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/modules/statusHistory.js25+++++++++++++++++++++++++
Msrc/modules/statuses.js21++++++++++++++++++---
Msrc/modules/users.js64+++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/panel.scss62+++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/services/api/api.service.js384++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/services/backend_interactor_service/backend_interactor_service.js9+++++++--
Msrc/services/entity_normalizer/entity_normalizer.service.js62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/services/html_converter/utility.service.js12++++++++++--
Asrc/services/lists_fetcher/lists_fetcher.service.js22++++++++++++++++++++++
Msrc/services/notification_utils/notification_utils.js4++++
Msrc/services/notifications_fetcher/notifications_fetcher.service.js14++++++++++++++
Msrc/services/push/push.js2+-
Msrc/services/status_poster/status_poster.service.js42++++++++++++++++++++++++++++++++++++++++++
Msrc/services/style_setter/style_setter.js31+++++++++++++++++++++++++++++++
Msrc/services/theme_data/pleromafe.js8++++++++
Msrc/services/timeline_fetcher/timeline_fetcher.service.js14+++++++++-----
Mstatic/config.json1+
Dstatic/emoji.json1432-------------------------------------------------------------------------------
Mtest/unit/karma.conf.js23+----------------------
Mtest/unit/specs/boot/routes.spec.js24++++++++++++++++++++++++
Mtest/unit/specs/components/rich_content.spec.js21+++++++++++++++++----
Mtest/unit/specs/components/user_profile.spec.js5++++-
Atest/unit/specs/modules/lists.spec.js83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/unit/specs/modules/serverSideStorage.spec.js338+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/unit/specs/modules/users.spec.js44+++++++++++++++++++++++++++++++++++++++-----
Mtest/unit/specs/services/entity_normalizer/entity_normalizer.spec.js19++++++++++---------
Myarn.lock8308+++++++++++++++++++++++++++++++------------------------------------------------
302 files changed, 14015 insertions(+), 9193 deletions(-)

diff --git a/.babelrc b/.babelrc @@ -1,5 +1,5 @@ { "presets": ["@babel/preset-env"], "plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-jsx"], - "comments": false + "comments": true } diff --git a/.gitignore b/.gitignore @@ -7,3 +7,4 @@ test/e2e/reports selenium-debug.log .idea/ config/local.json +static/emoji.json diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md @@ -0,0 +1,25 @@ +# Environment info + +<!-- Everything is optional and where applicable but the more information the better. --> +* Browser, version, OS, platform: +* Instance URL: +* Frontend version (see settings -> about): +* Backend version (see settings -> about): +* Browser extensions (ublock, rikaichamp etc): +* Known instance/user customizations (i.e. pleromafe mods/forks, instance styles etc) + +# Bug description & reproduction steps + +<!-- Type out here how to reproduce the bug, what goes wrong and what should go right --> +<!-- Screenshots and videos help a lot ;) any observations might also help --> +<!-- Also mention if there any errors in browser's console if relevant --> + +# Bug seriousness + +<!-- Everything is optional and free-form --> +* How annoying it is: +* How often does it happen: +* How many people does it affect: +* Is there a workaround for it: + +/label ~Bug diff --git a/.gitlab/issue_templates/Suggestion.md b/.gitlab/issue_templates/Suggestion.md @@ -0,0 +1,11 @@ +# Behavior suggestion/Feature request +<!-- +Type out what you want to see changed or what feature you want to see added to +PleormaFE. Please also explain how it would benefit users (or admins/moderators) +and what intended usecase is. Any background information (i.e. porting behavior +from other frontends/services, specific situations, personal preferences etc.) +as well as examples would be greatly appreciated. +--> + +/label ~suggestion + diff --git a/.gitlab/issue_templates/default.md b/.gitlab/issue_templates/default.md @@ -0,0 +1,7 @@ +<!-- +please use one of the templates if applicable, otherwise - type out here +in free-form +--> + +/label ~needs-triage + diff --git a/.gitlab/merge_request_templates/default.md b/.gitlab/merge_request_templates/default.md @@ -0,0 +1,30 @@ +<!-- +Feel free to submit merge requests that are work-in-progress, but mark them as +Draft: or WIP:. +Merge requests that have Draft or WIP status will not be merged and have less chances +of being reviewed, but you can still ask people to take a look if you need advice. +--> +# Changes + +* +* +* + +<!-- List what your merge request changes and how --> +<!-- +Try to not to break existing behavior, if your changes do break existing behavior +make it configurable to toggle between old behavior and new. Which one should be +default is up to discussion. +--> +<!-- If your merge request resolves some issue link it like so: "Closes #99999" --> +<!-- +If merge request adds some new feature that depends on backend: + +1. Make sure it gracefully degrades if backend hasn't been updated to support the feature, + we try to make PleromaFE compatible with older versions of BE so that people can still + update frontend safely without updating backend since it's costly and much riskier. +2. Link related BE merge request here +--> +<!-- Screenshots are welcome --> + +/label ~needs-review diff --git a/.node-version b/.node-version @@ -1 +1 @@ -16.16.0 +16.18.1 diff --git a/.stylelintrc.json b/.stylelintrc.json @@ -1,19 +1,41 @@ { "extends": [ "stylelint-rscss/config", - "stylelint-config-recommended", - "stylelint-config-standard" + "stylelint-config-standard", + "stylelint-config-recommended-scss", + "stylelint-config-html", + "stylelint-config-recommended-vue/scss" ], "rules": { "declaration-no-important": true, "rscss/no-descendant-combinator": false, "rscss/class-format": [ - true, + false, { "component": "pascal-case", "variant": "^-[a-z]\\w+", "element": "^[a-z]\\w+" } + ], + "selector-class-pattern": null, + "import-notation": null, + "custom-property-pattern": null, + "keyframes-name-pattern": null, + "scss/operator-no-newline-after": null, + "declaration-block-no-redundant-longhand-properties": [ + true, + { + "ignoreShorthands": [ + "grid-template", + "margin", + "padding", + "border", + "border-width", + "border-style", + "border-color", + "border-radius" + ] + } ] } } diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -3,51 +3,76 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## Unreleased +## 2.5.0 - 23.12.2022 ### Fixed -- AdminFE button no longer scrolls page to top when clicked +- UI no longer lags when switching between mobile and desktop mode +- Popovers no longer constrained by DOM hierarchy, shouldn't be cut off by anything +- Emoji autocomplete popover and picker popover stick to the text cursor. +- Attachments are ALWAYS in same order as user uploaded, no more "videos first" - Pinned statuses no longer appear at bottom of user timeline (still appear as part of the timeline when fetched deep enough) - Fixed many many bugs related to new mentions, including spacing and alignment issues - Links in profile bios now properly open in new tabs +- "Always show mobile button" is working now - Inline images now respect their intended width/height attributes - Links with `&` in them work properly now -- Interaction list popovers now properly emojify names -- Completely hidden posts still had 1px border -- Attachments are ALWAYS in same order as user uploaded, no more "videos first" - Attachment description is prefilled with backend-provided default when uploading - Proper visual feedback that next image is loading when browsing -- UI no longer lags when switching between mobile and desktop mode -- Popovers no longer constrained by DOM hierarchy, shouldn't be cut off by anything -- "Always show mobile button" is working now +- Additional HTML sanitization on frontend side in case backend sanitization fails +- Interaction list popovers now properly emojify names +- AdminFE button no longer scrolls page to top when clicked +- User handles with non-ascii domains now have less intrusive indicator for the domain name +- Completely hidden posts still no longer have 1px border +- A lot of accessibility improvements ### Changed - Using Vue 3 now -- (You)s are optional (opt-in) now, bolding your nickname is also optional (opt-out) +- A lot of internal dependencies updated +- "(You)s" are optional (opt-in) now, bolding your nickname is also optional (opt-out) - User highlight background now also covers the `@` - Reverted back to textual `@`, svg version is opt-in. - Settings window has been thoroughly rearranged to make more sense and make navigation settings easier. - Uploaded attachments are uniform with displayed attachments - Flash is watchable in media-modal (takes up nearly full screen though due to sizing issues) -- Notifications about likes/repeats/emoji reacts are now minimized so they always take up same amount of space irrelevant to size of post. +- Notifications about likes/repeats/emoji reacts are now minimized so they always take up same amount of space irrelevant to size of post. (You can expand them to full if need be) - Slight width/spacing adjustments - More sizing stuff is font-size dependent now - Scrollbars are styled/colorized now - Scrollbars are toggleable (for stuff that didn't have visible scrollbars before) (opt-in) +- Updated localization files +- Top bar is more useful in mobile mode now. +- "Show new" button is way more compact in mobile mode +- Slightly adjusted placement and spacing of the topbar buttons so it's less easy to accidentally log yourself out ### Added - 3 column mode: only enables when there's space for it (opt-out, customizable) +- Apologetic pleroma-tan +- New button on timeline header to change some of the new and often-used settings +- Support for lists +- Added ability to edit posts and view post edit history etc. +- Added ability to add personal note to users +- Added initial support for admin announcements +- Added ui for account migration +- Added ui for backups +- Added ability to force-unfollow a user from you +- Emoji are now grouped by pack +- Ability to pin navigation items and collapse the navigation menu +- Ability to rearrange order of attachments when uploading +- Ability to scroll column (or page) to top via panel header button - Options to show domains in mentions - Option to show user avatars in mention links (opt-in) - Option to disable the tooltip for mentions - Option to completely hide muted threads +- Option to customize what clicking user avatar does in user popover +- Notifications for poll results +- "Favorites" link in navigation +- Very early and somewhat experimental system for automatic settings sync (used only for pinned navigation and apologetic pleroma-tan) +- Implemented remote interaction with statuses for anon visitors - Ability to open videos in modal even if you disabled that feature, via an icon button - New button on attachment that indicates that attachment has a description and shows a bar filled with description - Attachments are truncated just like post contents - Media modal now also displays description and counter position in gallery (i.e. 1/5) -- Ability to rearrange order of attachments when uploading - Enabled users to zoom and pan images in media viewer with mouse and touch -- Timelines/panels and conversations have sticky headers now -- Added frontend ui for account migration +- Timelines/panels and conversations have sticky headers now (a bit glitchy on some browsers like safari) (opt-out) ## [2.4.2] - 2022-01-09 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md @@ -10,3 +10,5 @@ Contributors of this project. - shpuld (shpuld@shitposter.club): CSS and styling - Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images. - hj (hj@shigusegubu.club): Code +- Sean King (seanking@kazv.moe): Code +- tusooa (tusooa@kazv.moe): Code diff --git a/README.md b/README.md @@ -1,18 +1,19 @@ # Pleroma-FE -> A single column frontend designed for Pleroma. +> Highly-customizable frontend designed for Pleroma. -![screenshot](/uploads/796c5ecf985ed1e2b0943ee0df131ed0/DJVqSJ0.png) +![screenshot](./image-1.png) # For Translators -To translate Pleroma-FE, add your language to [src/i18n/messages.js](https://git.pleroma.social/pleroma/pleroma-fe/blob/develop/src/i18n/messages.js). Pleroma-FE will set your language by your browser locale, but you can temporarily force it in the code by changing the locale in main.js. +To translate Pleroma-FE, use our weblate server: https://translate.pleroma.social/. If you need to add your language it should be added as a json file in [src/i18n/](https://git.pleroma.social/pleroma/pleroma-fe/blob/develop/src/i18n/) folder and added in a list within [src/i18n/languages.js](https://git.pleroma.social/pleroma/pleroma-fe/blob/develop/src/i18n/languages.js). -# FOR ADMINS +Pleroma-FE will set your language by your browser locale, but you can change language in settings. -You don't need to build Pleroma-FE yourself. Those using the Pleroma backend will be able to use it out of the box. +# For instance admins +You don't need to build Pleroma-FE yourself. Those using the Pleroma backend will be able to use it out of the box. Information of customizing PleromaFE settings/defaults is in our [guide](https://docs-develop.pleroma.social/frontend/CONFIGURATION/) and in case you want to build your own custom version there's [another](https://docs-develop.pleroma.social/frontend/HACKING/) -## Build Setup +# Build Setup ``` bash # install dependencies @@ -20,13 +21,13 @@ npm install -g yarn yarn # serve with hot reload at localhost:8080 -npm run dev +yarn dev # build for production with minification -npm run build +yarn build # run unit tests -npm run unit +yarn unit ``` # For Contributors: @@ -40,10 +41,4 @@ FE Build process also leaves current commit hash in global variable `___pleromaf # Configuration -Edit config.json for configuration. - -## Options - -### Login methods - -```loginMethod``` can be set to either ```password``` (the default) or ```token```, which will use the full oauth redirection flow, which is useful for SSO situations. +Set configuration settings in AdminFE, additionally you can edit config.json. For more details see [documentation](https://docs-develop.pleroma.social/frontend/CONFIGURATION/). diff --git a/build/build.js b/build/build.js @@ -18,6 +18,9 @@ console.log( var spinner = ora('building for production...') spinner.start() +var updateEmoji = require('./update-emoji').updateEmoji +updateEmoji() + var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) rm('-rf', assetsPath) mkdir('-p', assetsPath) @@ -33,4 +36,8 @@ webpack(webpackConfig, function (err, stats) { chunks: false, chunkModules: false }) + '\n') + if (stats.hasErrors()) { + console.error('See above for errors.') + process.exit(1) + } }) diff --git a/build/dev-server.js b/build/dev-server.js @@ -10,6 +10,9 @@ var webpackConfig = process.env.NODE_ENV === 'testing' ? require('./webpack.prod.conf') : require('./webpack.dev.conf') +var updateEmoji = require('./update-emoji').updateEmoji +updateEmoji() + // default port where dev server listens for incoming traffic var port = process.env.PORT || config.dev.port // Define HTTP proxies to your custom API backend @@ -29,18 +32,20 @@ var devMiddleware = require('webpack-dev-middleware')(compiler, { }) var hotMiddleware = require('webpack-hot-middleware')(compiler) + +// FIXME: The statement below gives error about hooks being required in webpack 5. // force page reload when html-webpack-plugin template changes -compiler.plugin('compilation', function (compilation) { - compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { - // FIXME: This supposed to reload whole page when index.html is changed, - // however now it reloads entire page on every breath, i suppose the order - // of plugins changed or something. It's a minor thing and douesn't hurt - // disabling it, constant reloads hurt much more +// compiler.plugin('compilation', function (compilation) { +// compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { +// // FIXME: This supposed to reload whole page when index.html is changed, +// // however now it reloads entire page on every breath, i suppose the order +// // of plugins changed or something. It's a minor thing and douesn't hurt +// // disabling it, constant reloads hurt much more - // hotMiddleware.publish({ action: 'reload' }) - // cb() - }) -}) +// // hotMiddleware.publish({ action: 'reload' }) +// // cb() +// }) +// }) // proxy api requests Object.keys(proxyTable).forEach(function (context) { @@ -48,7 +53,7 @@ Object.keys(proxyTable).forEach(function (context) { if (typeof options === 'string') { options = { target: options } } - app.use(proxyMiddleware(context, options)) + app.use(proxyMiddleware.createProxyMiddleware(context, options)) }) // handle fallback for HTML5 history API diff --git a/build/update-emoji.js b/build/update-emoji.js @@ -0,0 +1,27 @@ + +module.exports = { + updateEmoji () { + const emojis = require('@kazvmoe-infra/unicode-emoji-json/data-by-group') + const fs = require('fs') + + Object.keys(emojis) + .map(k => { + emojis[k].map(e => { + delete e.unicode_version + delete e.emoji_version + delete e.skin_tone_support_unicode_version + }) + }) + + const res = {} + Object.keys(emojis) + .map(k => { + const groupId = k.replace('&', 'and').replace(/ /g, '-').toLowerCase() + res[groupId] = emojis[k] + }) + + console.info('Updating emojis...') + fs.writeFileSync('static/emoji.json', JSON.stringify(res)) + console.info('Done.') + } +} diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js @@ -2,11 +2,11 @@ var path = require('path') var config = require('../config') var utils = require('./utils') var projectRoot = path.resolve(__dirname, '../') -var ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin') +var ServiceWorkerWebpackPlugin = require('serviceworker-webpack5-plugin') var CopyPlugin = require('copy-webpack-plugin'); var { VueLoaderPlugin } = require('vue-loader') var ESLintPlugin = require('eslint-webpack-plugin'); - +var StylelintPlugin = require('stylelint-webpack-plugin'); var env = process.env.NODE_ENV // check env & config/index.js to decide weither to enable CSS Sourcemaps for the @@ -24,7 +24,8 @@ module.exports = { output: { path: config.build.assetsRoot, publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, - filename: '[name].js' + filename: '[name].js', + chunkFilename: '[name].js' }, optimization: { splitChunks: { @@ -42,6 +43,10 @@ module.exports = { 'assets': path.resolve(__dirname, '../src/assets'), 'components': path.resolve(__dirname, '../src/components'), 'vue-i18n': 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js' + }, + fallback: { + 'querystring': require.resolve('querystring-es3'), + 'url': require.resolve('url/') } }, module: { @@ -78,22 +83,16 @@ module.exports = { }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, - use: { - loader: 'url-loader', - options: { - limit: 10000, - name: utils.assetsPath('img/[name].[hash:7].[ext]') - } + type: 'asset', + generator: { + filename: utils.assetsPath('img/[name].[hash:7][ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, - use: { - loader: 'url-loader', - options: { - limit: 10000, - name: utils.assetsPath('fonts/[name].[hash:7].[ext]') - } + type: 'asset', + generator: { + filename: utils.assetsPath('fonts/[name].[hash:7][ext]') } }, { @@ -112,14 +111,14 @@ module.exports = { extensions: ['js', 'vue'], formatter: require('eslint-formatter-friendly') }), + new StylelintPlugin({}), new VueLoaderPlugin(), // This copies Ruffle's WASM to a directory so that JS side can access it new CopyPlugin({ patterns: [ { - from: "node_modules/@ruffle-rs/ruffle/*", - to: "static/ruffle", - flatten: true + from: "node_modules/@ruffle-rs/ruffle/**/*", + to: "static/ruffle/[name][ext]" }, ], options: { diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js @@ -16,7 +16,7 @@ module.exports = merge(baseWebpackConfig, { }, mode: 'development', // eval-source-map is faster for development - devtool: '#eval-source-map', + devtool: 'eval-source-map', plugins: [ new webpack.DefinePlugin({ 'process.env': config.dev.env, diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js @@ -5,6 +5,7 @@ var webpack = require('webpack') var merge = require('webpack-merge') var baseWebpackConfig = require('./webpack.base.conf') var MiniCssExtractPlugin = require('mini-css-extract-plugin') +const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") var HtmlWebpackPlugin = require('html-webpack-plugin') var env = process.env.NODE_ENV === 'testing' ? require('../config/test.env') @@ -19,12 +20,16 @@ var webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, extract: true }) }, - devtool: config.build.productionSourceMap ? '#source-map' : false, + devtool: config.build.productionSourceMap ? 'source-map' : false, optimization: { minimize: true, splitChunks: { chunks: 'all' - } + }, + minimizer: [ + `...`, + new CssMinimizerPlugin() + ] }, output: { path: config.build.assetsRoot, @@ -60,9 +65,7 @@ var webpackConfig = merge(baseWebpackConfig, { ignoreCustomComments: [/server-generated-meta/] // more options: // https://github.com/kangax/html-minifier#options-quick-reference - }, - // necessary to consistently work with multiple chunks via CommonsChunkPlugin - chunksSortMode: 'dependency' + } }), // split vendor js into its own file // extract webpack runtime and module manifest to its own file in order to diff --git a/docs/HACKING.md b/docs/HACKING.md @@ -25,7 +25,17 @@ This could be a bit trickier, you basically need steps 1-4 from *develop build* ### Replacing your instance's frontend with custom FE build -This is the most easiest way to use and test FE build: you just need to copy or symlink contents of `dist` folder into backend's [static directory](../backend/configuration/static_dir.md), by default it is located in `instance/static`, or in `/var/lib/pleroma/static` for OTP release installations, create it if it doesn't exist already. Be aware that running `yarn build` wipes the contents of `dist` folder. +#### New way (via AdminFE, a bit janky but works) + +In backend's [static directory](../backend/configuration/static_dir.md) there should be a folder called `frontends` if you installed any frontends from AdminFE before, otherwise you can create it yourself (ensuring correct permissions). Backend will serve given frontend from path `frontends/{frontend}/{reference}`, where `{frontend}` is name of frontend (`pleroma-fe`) and `{reference}` is version. You could make a production build, move `dist` folder into `frontends/pleroma-fe` and rename it into something like `myCustomVersion`. To actually make backend serve this frontend by default, in AdminFE you'll need to set name/reference in Settings -> Frontend -> Frontends -> Primary. + +You could also install from a zip file (i.e. CI build) but AdminFE UI is a bit buggy and lacking, so this approach is not recommended. + +Take note that frontend management is in early development and currently there's no way for user to change frontend or version for themselves, primary frontend becomes default frontend for all users and visitors. + +#### Old way (replaces everything, hard to maintain, not recommended) + +Copy or symlink contents of `dist` folder into backend's [static directory](../backend/configuration/static_dir.md), by default it is located in `instance/static`, or in `/var/lib/pleroma/static` for OTP release installations, create it if it doesn't exist already. Be aware that running `yarn build` wipes the contents of `dist` folder, and this could remove emojis, other frontends etc. and therefore this approach is not recommended. ### Running production build locally or on a separate server diff --git a/image-1.png b/image-1.png Binary files differ. diff --git a/image.png b/image.png Binary files differ. diff --git a/index.html b/index.html @@ -10,5 +10,6 @@ <noscript>To use Pleroma, please enable JavaScript.</noscript> <div id="app"></div> <!-- built files will be auto injected --> + <div id="popovers" /> </body> </html> diff --git a/package.json b/package.json @@ -1,9 +1,9 @@ { "name": "pleroma_fe", - "version": "1.0.0", - "description": "A Qvitter-style frontend for certain GS servers.", - "author": "Roger Braun <roger@rogerbraun.net>", - "private": true, + "version": "2.5.0", + "description": "Pleroma frontend, the default frontend of Pleroma social network server", + "author": "Pleroma contributors <https://git.pleroma.social/pleroma/pleroma-fe/-/blob/develop/CONTRIBUTORS.md>", + "private": false, "scripts": { "dev": "node build/dev-server.js", "build": "node build/build.js", @@ -11,120 +11,125 @@ "unit:watch": "karma start test/unit/karma.conf.js --single-run=false", "e2e": "node test/e2e/runner.js", "test": "npm run unit && npm run e2e", - "stylelint": "npx stylelint src/components/status/status.scss", + "stylelint": "npx stylelint '**/*.scss' '**/*.vue'", "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs", "lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs" }, "dependencies": { - "@babel/runtime": "7.18.9", + "@babel/runtime": "7.20.7", "@chenfengyuan/vue-qrcode": "2.0.0", - "@fortawesome/fontawesome-svg-core": "6.1.2", - "@fortawesome/free-regular-svg-icons": "6.1.2", - "@fortawesome/free-solid-svg-icons": "6.1.2", - "@fortawesome/vue-fontawesome": "3.0.1", + "@fortawesome/fontawesome-svg-core": "6.2.1", + "@fortawesome/free-regular-svg-icons": "6.2.1", + "@fortawesome/free-solid-svg-icons": "6.2.1", + "@fortawesome/vue-fontawesome": "3.0.2", "@kazvmoe-infra/pinch-zoom-element": "1.2.0", - "@ruffle-rs/ruffle": "^0.1.0-nightly.2022.7.12", - "@vuelidate/core": "2.0.0-alpha.43", - "@vuelidate/validators": "2.0.0-alpha.31", + "@kazvmoe-infra/unicode-emoji-json": "0.4.0", + "@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12", + "@vuelidate/core": "2.0.0", + "@vuelidate/validators": "2.0.0", "body-scroll-lock": "3.1.5", "chromatism": "3.0.0", "click-outside-vue3": "4.0.1", "cropperjs": "1.5.12", - "diff": "3.5.0", "escape-html": "1.0.3", - "js-cookie": "^3.0.1", + "js-cookie": "3.0.1", "localforage": "1.10.0", - "parse-link-header": "1.0.1", + "parse-link-header": "2.0.0", "phoenix": "1.6.2", "punycode.js": "2.1.0", - "qrcode": "1", - "utf8": "^3.0.0", - "vue": "3.2.37", - "vue-i18n": "9.2.0", - "vue-router": "4.1.3", - "vue-template-compiler": "2.7.8", - "vuex": "4.0.2" + "qrcode": "1.5.0", + "querystring-es3": "0.2.1", + "url": "0.11.0", + "utf8": "3.0.0", + "vue": "3.2.45", + "vue-i18n": "9.2.2", + "vue-router": "4.1.6", + "vue-template-compiler": "2.7.14", + "vue-virtual-scroller": "^2.0.0-beta.7", + "vuex": "4.1.0" }, "devDependencies": { - "@babel/core": "7.18.9", - "@babel/plugin-transform-runtime": "7.18.9", - "@babel/preset-env": "7.18.9", + "@babel/core": "7.20.7", + "@babel/eslint-parser": "7.19.1", + "@babel/plugin-transform-runtime": "7.19.6", + "@babel/preset-env": "7.20.2", "@babel/register": "7.18.9", - "@babel/eslint-parser": "7.18.9", - "@intlify/vue-i18n-loader": "^5.0.0", + "@intlify/vue-i18n-loader": "5.0.0", "@ungap/event-target": "0.2.3", - "@vue/babel-helper-vue-jsx-merge-props": "1.2.1", + "@vue/babel-helper-vue-jsx-merge-props": "1.4.0", "@vue/babel-plugin-jsx": "1.1.1", - "@vue/compiler-sfc": "3.2.37", - "@vue/test-utils": "2.0.2", - "autoprefixer": "6.7.7", - "babel-loader": "8.2.5", + "@vue/compiler-sfc": "3.2.45", + "@vue/test-utils": "2.2.7", + "autoprefixer": "10.4.13", + "babel-loader": "9.1.0", "babel-plugin-lodash": "3.3.4", - "chai": "3.5.0", + "chai": "4.3.7", "chalk": "1.1.3", - "chromedriver": "103.0.0", - "connect-history-api-fallback": "1.6.0", - "copy-webpack-plugin": "6.4.1", - "cross-spawn": "4.0.2", - "css-loader": "0.28.11", + "chromedriver": "108.0.0", + "connect-history-api-fallback": "2.0.0", + "copy-webpack-plugin": "11.0.0", + "cross-spawn": "7.0.3", + "css-loader": "6.7.3", + "css-minimizer-webpack-plugin": "4.2.2", "custom-event-polyfill": "1.0.7", - "eslint": "8.20.0", + "eslint": "8.32.0", "eslint-config-standard": "17.0.0", "eslint-formatter-friendly": "7.0.0", - "eslint-webpack-plugin": "2.7.0", "eslint-plugin-import": "2.26.0", - "eslint-plugin-n": "15.2.4", - "eslint-plugin-promise": "6.0.0", - "eslint-plugin-vue": "9.3.0", + "eslint-plugin-n": "15.6.1", + "eslint-plugin-promise": "6.1.1", + "eslint-plugin-vue": "9.8.0", + "eslint-webpack-plugin": "3.2.0", "eventsource-polyfill": "0.9.6", - "express": "4.18.1", - "file-loader": "3.0.1", + "express": "4.18.2", "function-bind": "1.1.1", - "html-webpack-plugin": "3.2.0", - "http-proxy-middleware": "0.21.0", - "inject-loader": "2.0.1", + "html-webpack-plugin": "5.5.0", + "http-proxy-middleware": "2.0.6", "iso-639-1": "2.1.15", - "isparta-loader": "2.0.0", "json-loader": "0.5.7", - "karma": "6.4.0", - "karma-coverage": "1.1.2", - "karma-firefox-launcher": "1.3.0", + "karma": "6.4.1", + "karma-coverage": "2.2.0", + "karma-firefox-launcher": "2.1.2", "karma-mocha": "2.0.1", "karma-mocha-reporter": "2.2.5", "karma-sinon-chai": "2.0.2", "karma-sourcemap-loader": "0.3.8", - "karma-spec-reporter": "0.0.34", - "karma-webpack": "4.0.2", + "karma-spec-reporter": "0.0.36", + "karma-webpack": "5.0.0", "lodash": "4.17.21", - "lolex": "1.6.0", - "mini-css-extract-plugin": "0.12.0", - "mocha": "3.5.3", - "nightwatch": "0.9.21", - "opn": "4.0.2", + "mini-css-extract-plugin": "2.7.2", + "mocha": "10.2.0", + "nightwatch": "2.6.10", + "opn": "5.5.0", "ora": "0.4.1", - "postcss-loader": "3.0.0", - "raw-loader": "0.5.1", - "sass": "1.54.0", - "sass-loader": "7.3.1", + "postcss": "8.4.20", + "postcss-html": "^1.5.0", + "postcss-loader": "7.0.2", + "postcss-scss": "^4.0.6", + "sass": "1.57.1", + "sass-loader": "13.2.0", "selenium-server": "2.53.1", - "semver": "5.7.1", - "serviceworker-webpack-plugin": "1.0.1", + "semver": "7.3.8", + "serviceworker-webpack5-plugin": "2.0.0", "shelljs": "0.8.5", - "sinon": "2.4.1", - "sinon-chai": "2.14.0", - "stylelint": "13.13.1", - "stylelint-config-standard": "20.0.0", + "sinon": "15.0.1", + "sinon-chai": "3.7.0", + "stylelint": "14.16.1", + "stylelint-config-html": "^1.1.0", + "stylelint-config-recommended-scss": "^8.0.0", + "stylelint-config-recommended-vue": "^1.4.0", + "stylelint-config-standard": "29.0.0", "stylelint-rscss": "0.4.0", - "url-loader": "1.1.2", - "vue-loader": "^16.0.0", + "stylelint-webpack-plugin": "^3.3.0", + "vue-loader": "17.0.1", "vue-style-loader": "4.1.3", - "webpack": "4.46.0", + "webpack": "5.75.0", "webpack-dev-middleware": "3.7.3", - "webpack-hot-middleware": "2.25.1", + "webpack-hot-middleware": "2.25.3", "webpack-merge": "0.20.0" }, "engines": { - "node": ">= 4.0.0", + "node": ">= 16.0.0", "npm": ">= 3.0.0" } } diff --git a/src/App.js b/src/App.js @@ -10,7 +10,9 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil import MobileNav from './components/mobile_nav/mobile_nav.vue' import DesktopNav from './components/desktop_nav/desktop_nav.vue' import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue' +import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue' import PostStatusModal from './components/post_status_modal/post_status_modal.vue' +import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue' import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue' import { windowWidth, windowHeight } from './services/window_utils/window_utils' import { mapGetters } from 'vuex' @@ -32,8 +34,11 @@ export default { MobileNav, DesktopNav, SettingsModal: defineAsyncComponent(() => import('./components/settings_modal/settings_modal.vue')), + UpdateNotification: defineAsyncComponent(() => import('./components/update_notification/update_notification.vue')), UserReportingModal, PostStatusModal, + EditStatusModal, + StatusHistoryModal, GlobalNoticeList }, data: () => ({ @@ -59,6 +64,13 @@ export default { '-' + this.layoutType ] }, + navClasses () { + const { navbarColumnStretch } = this.$store.getters.mergedConfig + return [ + '-' + this.layoutType, + ...(navbarColumnStretch ? ['-column-stretch'] : []) + ] + }, currentUser () { return this.$store.state.users.currentUser }, userBackground () { return this.currentUser.background_image }, instanceBackground () { @@ -84,11 +96,16 @@ export default { isChats () { return this.$route.name === 'chat' || this.$route.name === 'chats' }, + isListEdit () { + return this.$route.name === 'lists-edit' + }, newPostButtonShown () { if (this.isChats) return false + if (this.isListEdit) return false return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile' }, showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }, + editingAvailable () { return this.$store.state.instance.editingAvailable }, shoutboxPosition () { return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false }, diff --git a/src/App.scss b/src/App.scss @@ -1,16 +1,18 @@ // stylelint-disable rscss/class-format -@import './_variables.scss'; +/* stylelint-disable no-descending-specificity */ +@import "./variables"; +@import "./panel"; :root { --navbar-height: 3.5rem; --post-line-height: 1.4; // Z-Index stuff - --ZI_media_modal: 90000; - --ZI_modals_popovers: 85000; - --ZI_modals: 80000; - --ZI_navbar_popovers: 75000; - --ZI_navbar: 70000; - --ZI_popovers: 60000; + --ZI_media_modal: 9000; + --ZI_modals_popovers: 8500; + --ZI_modals: 8000; + --ZI_navbar_popovers: 7500; + --ZI_navbar: 7000; + --ZI_popovers: 6000; } html { @@ -117,20 +119,35 @@ h4 { margin: 0; } -i[class*=icon-], -.svg-inline--fa { +.iconLetter { + display: inline-block; + text-align: center; + font-weight: 1000; +} + +i[class*="icon-"], +.svg-inline--fa, +.iconLetter { color: $fallback--icon; color: var(--icon, $fallback--icon); } +.button-unstyled:hover, +a:hover { + > i[class*="icon-"], + > .svg-inline--fa, + > .iconLetter { + color: var(--text); + } +} + nav { z-index: var(--ZI_navbar); - color: var(--topBarText); background-color: $fallback--fg; background-color: var(--topBar, $fallback--fg); color: $fallback--faint; color: var(--faint, $fallback--faint); - box-shadow: 0 0 4px rgba(0, 0, 0, 0.6); + box-shadow: 0 0 4px rgb(0 0 0 / 60%); box-shadow: var(--topBarShadow); box-sizing: border-box; height: var(--navbar-height); @@ -141,6 +158,11 @@ nav { grid-area: sidebar; } +#modal { + position: absolute; + z-index: var(--ZI_modals); +} + .column.-scrollable { top: var(--navbar-height); position: sticky; @@ -170,25 +192,28 @@ nav { } .underlay { - grid-column-start: 1; - grid-column-end: span 3; - grid-row-start: 1; - grid-row-end: 1; + grid-column: 1 / span 3; + grid-row: 1 / 1; pointer-events: none; - background-color: rgba(0, 0, 0, 0.15); - background-color: var(--underlay, rgba(0, 0, 0, 0.15)); + background-color: rgb(0 0 0 / 15%); + background-color: var(--underlay, rgb(0 0 0 / 15%)); z-index: -1000; } .app-layout { --miniColumn: 25rem; - --maxiColumn: minmax(var(--miniColumn), 45rem); + --maxiColumn: 45rem; --columnGap: 1em; --status-margin: 0.75em; + --effectiveSidebarColumnWidth: minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn))); + --effectiveNotifsColumnWidth: minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn))); + --effectiveContentColumnWidth: minmax(var(--miniColumn), var(--contentColumnWidth, var(--maxiColumn))); position: relative; display: grid; - grid-template-columns: var(--miniColumn) var(--maxiColumn); + grid-template-columns: + var(--effectiveSidebarColumnWidth) + var(--effectiveContentColumnWidth); grid-template-areas: "sidebar content"; grid-template-rows: 1fr; box-sizing: border-box; @@ -205,8 +230,7 @@ nav { display: grid; grid-template-columns: 100%; box-sizing: border-box; - grid-row-start: 1; - grid-row-end: 1; + grid-row: 1 / 1; margin: 0 calc(var(--___columnMargin) / 2); padding: calc(var(--___columnMargin)) 0; row-gap: var(--___columnMargin); @@ -281,16 +305,25 @@ nav { align-content: start; } - &.-reverse:not(.-wide):not(.-mobile) { - grid-template-columns: var(--maxiColumn) var(--miniColumn); + &.-reverse:not(.-wide, .-mobile) { + grid-template-columns: + var(--effectiveContentColumnWidth) + var(--effectiveSidebarColumnWidth); grid-template-areas: "content sidebar"; } &.-wide { - grid-template-columns: var(--miniColumn) var(--maxiColumn) var(--miniColumn); + grid-template-columns: + var(--effectiveSidebarColumnWidth) + var(--effectiveContentColumnWidth) + var(--effectiveNotifsColumnWidth); grid-template-areas: "sidebar content notifs"; &.-reverse { + grid-template-columns: + var(--effectiveNotifsColumnWidth) + var(--effectiveContentColumnWidth) + var(--effectiveSidebarColumnWidth); grid-template-areas: "notifs content sidebar"; } } @@ -301,11 +334,8 @@ nav { padding: 0; .column { - margin-left: 0; - margin-right: 0; padding-top: 0; - margin-top: var(--navbar-height); - margin-bottom: 0; + margin: var(--navbar-height) 0 0 0; } .panel-heading, @@ -354,7 +384,7 @@ nav { background: transparent; } - i[class*=icon-], + i[class*="icon-"], .svg-inline--fa { color: $fallback--text; color: var(--btnText, $fallback--text); @@ -365,12 +395,15 @@ nav { } &:hover { - box-shadow: 0 0 4px rgba(255, 255, 255, 0.3); + box-shadow: 0 0 4px rgb(255 255 255 / 30%); box-shadow: var(--buttonHoverShadow); } &:active { - box-shadow: 0 0 4px 0 rgba(255, 255, 255, 0.3), 0 1px 0 0 rgba(0, 0, 0, 0.2) inset, 0 -1px 0 0 rgba(255, 255, 255, 0.2) inset; + box-shadow: + 0 0 4px 0 rgb(255 255 255 / 30%), + 0 1px 0 0 rgb(0 0 0 / 20%) inset, + 0 -1px 0 0 rgb(255 255 255 / 20%) inset; box-shadow: var(--buttonPressedShadow); color: $fallback--text; color: var(--btnPressedText, $fallback--text); @@ -403,7 +436,10 @@ nav { color: var(--btnToggledText, $fallback--text); background-color: $fallback--fg; background-color: var(--btnToggled, $fallback--fg); - box-shadow: 0 0 4px 0 rgba(255, 255, 255, 0.3), 0 1px 0 0 rgba(0, 0, 0, 0.2) inset, 0 -1px 0 0 rgba(255, 255, 255, 0.2) inset; + box-shadow: + 0 0 4px 0 rgb(255 255 255 / 30%), + 0 1px 0 0 rgb(0 0 0 / 20%) inset, + 0 -1px 0 0 rgb(255 255 255 / 20%) inset; box-shadow: var(--buttonPressedShadow); svg, @@ -468,7 +504,10 @@ textarea, border: none; border-radius: $fallback--inputRadius; border-radius: var(--inputRadius, $fallback--inputRadius); - box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2) inset, 0 -1px 0 0 rgba(255, 255, 255, 0.2) inset, 0 0 2px 0 rgba(0, 0, 0, 1) inset; + box-shadow: + 0 1px 0 0 rgb(0 0 0 / 20%) inset, + 0 -1px 0 0 rgb(255 255 255 / 20%) inset, + 0 0 2px 0 rgb(0 0 0 / 100%) inset; box-shadow: var(--inputShadow); background-color: $fallback--fg; background-color: var(--input, $fallback--fg); @@ -486,13 +525,13 @@ textarea, padding: 0 var(--_padding); &:disabled, - &[disabled=disabled], + &[disabled="disabled"], &.disabled { cursor: not-allowed; opacity: 0.5; } - &[type=range] { + &[type="range"] { background: none; border: none; margin: 0; @@ -500,7 +539,7 @@ textarea, flex: 1; } - &[type=radio] { + &[type="radio"] { display: none; &:checked + label::before { @@ -520,7 +559,7 @@ textarea, + label::before { flex-shrink: 0; display: inline-block; - content: ''; + content: ""; transition: box-shadow 200ms; width: 1.1em; height: 1.1em; @@ -540,7 +579,7 @@ textarea, } } - &[type=checkbox] { + &[type="checkbox"] { display: none; &:checked + label::before { @@ -559,7 +598,7 @@ textarea, + label::before { flex-shrink: 0; display: inline-block; - content: '✓'; + content: "✓"; transition: color 200ms; width: 1.1em; height: 1.1em; @@ -599,10 +638,10 @@ option { } .hide-number-spinner { - -moz-appearance: textfield; + appearance: textfield; - &[type=number]::-webkit-inner-spin-button, - &[type=number]::-webkit-outer-spin-button { + &[type="number"]::-webkit-inner-spin-button, + &[type="number"]::-webkit-outer-spin-button { opacity: 0; display: none; } @@ -634,8 +673,6 @@ option { } } -@import './panel.scss'; - .fa { color: grey; } @@ -651,7 +688,7 @@ option { max-width: 10em; min-width: 1.7em; height: 1.3em; - padding: 0.15em 0.15em; + padding: 0.15em; vertical-align: middle; font-weight: normal; font-style: normal; @@ -746,17 +783,24 @@ option { } .fa-scale-110 { - &.svg-inline--fa { + &.svg-inline--fa, + &.iconLetter { font-size: 1.1em; } } .fa-old-padding { - &.svg-inline--fa { + &.iconLetter, + &.svg-inline--fa, + &-layer { padding: 0 0.3em; } } +.veryfaint { + opacity: 0.25; +} + .login-hint { text-align: center; @@ -842,3 +886,4 @@ option { .fade-leave-active { opacity: 0; } +/* stylelint-enable no-descending-specificity */ diff --git a/src/App.vue b/src/App.vue @@ -8,7 +8,10 @@ class="app-bg-wrapper" /> <MobileNav v-if="layoutType === 'mobile'" /> - <DesktopNav v-else /> + <DesktopNav + v-else + :class="navClasses" + /> <Notifications v-if="currentUser" /> <div id="content" @@ -30,10 +33,10 @@ <div id="notifs-sidebar" /> </template> </div> - <div + <main id="main-scroller" class="column main" - :class="{ '-full-height': isChats }" + :class="{ '-full-height': isChats || isListEdit }" > <div v-if="!currentUser" @@ -47,7 +50,7 @@ </router-link> </div> <router-view /> - </div> + </main> <div id="notifs-column" class="column -scrollable" @@ -64,10 +67,12 @@ <MobilePostStatusButton /> <UserReportingModal /> <PostStatusModal /> + <EditStatusModal v-if="editingAvailable" /> + <StatusHistoryModal v-if="editingAvailable" /> <SettingsModal /> + <UpdateNotification /> <div id="modal" /> <GlobalNoticeList /> - <div id="popovers" /> </div> </template> diff --git a/src/_mixins.scss b/src/_mixins.scss @@ -0,0 +1,18 @@ +@mixin unfocused-style { + @content; + + &:focus:not(:focus-visible, :hover) { + @content; + } +} + +@mixin focused-style { + &:hover, + &:focus { + @content; + } + + &:focus-visible { + @content; + } +} diff --git a/src/_variables.scss b/src/_variables.scss @@ -4,20 +4,20 @@ $darkened-background: whitesmoke; $fallback--bg: #121a24; $fallback--fg: #182230; -$fallback--faint: rgba(185, 185, 186, .5); +$fallback--faint: rgb(185 185 186 / 50%); $fallback--text: #b9b9ba; $fallback--link: #d8a070; $fallback--icon: #666; -$fallback--lightBg: rgb(21, 30, 42); +$fallback--lightBg: rgb(21 30 42); $fallback--lightText: #b9b9ba; $fallback--border: #222; -$fallback--cRed: #ff0000; +$fallback--cRed: #f00; $fallback--cBlue: #0095ff; $fallback--cGreen: #0fa00f; $fallback--cOrange: orange; -$fallback--alertError: rgba(211,16,20,.5); -$fallback--alertWarning: rgba(111,111,20,.5); +$fallback--alertError: rgb(211 16 20 / 50%); +$fallback--alertWarning: rgb(111 111 20 / 50%); $fallback--panelRadius: 10px; $fallback--checkboxRadius: 2px; @@ -29,6 +29,8 @@ $fallback--avatarAltRadius: 10px; $fallback--attachmentRadius: 10px; $fallback--chatMessageRadius: 10px; -$fallback--buttonShadow: 0px 0px 2px 0px rgba(0, 0, 0, 1), 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset; +$fallback--buttonShadow: 0 0 2px 0 rgb(0 0 0 / 100%), + 0 1px 0 0 rgb(255 255 255 / 20%) inset, + 0 -1px 0 0 rgb(0 0 0 / 20%) inset; $status-margin: 0.75em; diff --git a/src/assets/pleromatan_apology.png b/src/assets/pleromatan_apology.png Binary files differ. diff --git a/src/assets/pleromatan_apology_fox.png b/src/assets/pleromatan_apology_fox.png Binary files differ. diff --git a/src/assets/pleromatan_apology_fox_mask.png b/src/assets/pleromatan_apology_fox_mask.png Binary files differ. diff --git a/src/assets/pleromatan_apology_mask.png b/src/assets/pleromatan_apology_mask.png Binary files differ. diff --git a/src/boot/after_store.js b/src/boot/after_store.js @@ -1,6 +1,8 @@ import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import vClickOutside from 'click-outside-vue3' +import VueVirtualScroller from 'vue-virtual-scroller' +import 'vue-virtual-scroller/dist/vue-virtual-scroller.css' import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome' @@ -12,7 +14,7 @@ import { windowWidth, windowHeight } from '../services/window_utils/window_utils import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js' import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' -import { applyTheme } from '../services/style_setter/style_setter.js' +import { applyTheme, applyConfig } from '../services/style_setter/style_setter.js' import FaviconService from '../services/favicon_service/favicon_service.js' let staticInitialResults = null @@ -251,6 +253,7 @@ const getNodeInfo = async ({ store }) => { store.dispatch('setInstanceOption', { name: 'pleromaChatMessagesAvailable', value: features.includes('pleroma_chat_messages') }) store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') }) store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') }) + store.dispatch('setInstanceOption', { name: 'editingAvailable', value: features.includes('editing') }) store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits }) store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled }) @@ -360,6 +363,8 @@ const afterStoreSetup = async ({ store, i18n }) => { console.error('Failed to load any theme!') } + applyConfig(store.state.config) + // Now we can try getting the server settings and logging in // Most of these are preloaded into the index.html so blocking is minimized await Promise.all([ @@ -371,6 +376,7 @@ const afterStoreSetup = async ({ store, i18n }) => { // Start fetching things that don't need to block the UI store.dispatch('fetchMutes') + store.dispatch('startFetchingAnnouncements') getTOS({ store }) getStickers({ store }) @@ -393,6 +399,7 @@ const afterStoreSetup = async ({ store, i18n }) => { app.use(vClickOutside) app.use(VBodyScrollLock) + app.use(VueVirtualScroller) app.component('FAIcon', FontAwesomeIcon) app.component('FALayers', FontAwesomeLayers) diff --git a/src/boot/routes.js b/src/boot/routes.js @@ -20,6 +20,11 @@ import ShoutPanel from 'components/shout_panel/shout_panel.vue' import WhoToFollow from 'components/who_to_follow/who_to_follow.vue' import About from 'components/about/about.vue' import RemoteUserResolver from 'components/remote_user_resolver/remote_user_resolver.vue' +import Lists from 'components/lists/lists.vue' +import ListsTimeline from 'components/lists_timeline/lists_timeline.vue' +import ListsEdit from 'components/lists_edit/lists_edit.vue' +import NavPanel from 'src/components/nav_panel/nav_panel.vue' +import AnnouncementsPage from 'components/announcements_page/announcements_page.vue' export default (store) => { const validateAuthenticatedRoute = (to, from, next) => { @@ -58,7 +63,7 @@ export default (store) => { component: RemoteUserResolver, beforeEnter: validateAuthenticatedRoute }, - { name: 'external-user-profile', path: '/users/:id', component: UserProfile }, + { name: 'external-user-profile', path: '/users/$:id', component: UserProfile }, { name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute }, { name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute }, { name: 'registration', path: '/registration', component: Registration }, @@ -72,7 +77,14 @@ export default (store) => { { name: 'search', path: '/search', component: Search, props: (route) => ({ query: route.query.query }) }, { name: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute }, { name: 'about', path: '/about', component: About }, - { name: 'user-profile', path: '/:_(users)?/:name', component: UserProfile } + { name: 'announcements', path: '/announcements', component: AnnouncementsPage }, + { name: 'user-profile', path: '/users/:name', component: UserProfile }, + { name: 'legacy-user-profile', path: '/:name', component: UserProfile }, + { name: 'lists', path: '/lists', component: Lists }, + { name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline }, + { name: 'lists-edit', path: '/lists/:id/edit', component: ListsEdit }, + { name: 'lists-new', path: '/lists/new', component: ListsEdit }, + { name: 'edit-navigation', path: '/nav-edit', component: NavPanel, props: () => ({ forceExpand: true, forceEditMode: true }), beforeEnter: validateAuthenticatedRoute } ] if (store.state.instance.pleromaChatMessagesAvailable) { diff --git a/src/components/about/about.vue b/src/components/about/about.vue @@ -9,6 +9,3 @@ </template> <script src="./about.js"></script> - -<style lang="scss"> -</style> diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js @@ -1,6 +1,7 @@ import { mapState } from 'vuex' import ProgressButton from '../progress_button/progress_button.vue' import Popover from '../popover/popover.vue' +import UserListMenu from 'src/components/user_list_menu/user_list_menu.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faEllipsisV @@ -19,7 +20,8 @@ const AccountActions = { }, components: { ProgressButton, - Popover + Popover, + UserListMenu }, methods: { showRepeats () { @@ -34,6 +36,9 @@ const AccountActions = { unblockUser () { this.$store.dispatch('unblockUser', this.user.id) }, + removeUserFromFollowers () { + this.$store.dispatch('removeUserFromFollowers', this.user.id) + }, reportUser () { this.$store.dispatch('openUserReportingModal', { userId: this.user.id }) }, diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue @@ -28,6 +28,14 @@ class="dropdown-divider" /> </template> + <UserListMenu :user="user" /> + <button + v-if="relationship.followed_by" + class="btn button-default btn-block dropdown-item" + @click="removeUserFromFollowers" + > + {{ $t('user_card.remove_follower') }} + </button> <button v-if="relationship.blocking" class="btn button-default btn-block dropdown-item" @@ -72,7 +80,8 @@ <script src="./account_actions.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; + .AccountActions { .ellipsis-button { width: 2.5em; diff --git a/src/components/announcement/announcement.js b/src/components/announcement/announcement.js @@ -0,0 +1,108 @@ +import { mapState } from 'vuex' +import AnnouncementEditor from '../announcement_editor/announcement_editor.vue' +import RichContent from '../rich_content/rich_content.jsx' +import localeService from '../../services/locale/locale.service.js' + +const Announcement = { + components: { + AnnouncementEditor, + RichContent + }, + data () { + return { + editing: false, + editedAnnouncement: { + content: '', + startsAt: undefined, + endsAt: undefined, + allDay: undefined + }, + editError: '' + } + }, + props: { + announcement: Object + }, + computed: { + ...mapState({ + currentUser: state => state.users.currentUser + }), + canEditAnnouncement () { + return this.currentUser && this.currentUser.privileges.includes('announcements_manage_announcements') + }, + content () { + return this.announcement.content + }, + isRead () { + return this.announcement.read + }, + publishedAt () { + const time = this.announcement.published_at + if (!time) { + return + } + + return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale)) + }, + startsAt () { + const time = this.announcement.starts_at + if (!time) { + return + } + + return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale)) + }, + endsAt () { + const time = this.announcement.ends_at + if (!time) { + return + } + + return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale)) + }, + inactive () { + return this.announcement.inactive + } + }, + methods: { + markAsRead () { + if (!this.isRead) { + return this.$store.dispatch('markAnnouncementAsRead', this.announcement.id) + } + }, + deleteAnnouncement () { + return this.$store.dispatch('deleteAnnouncement', this.announcement.id) + }, + formatTimeOrDate (time, locale) { + const d = new Date(time) + return this.announcement.all_day ? d.toLocaleDateString(locale) : d.toLocaleString(locale) + }, + enterEditMode () { + this.editedAnnouncement.content = this.announcement.pleroma.raw_content + this.editedAnnouncement.startsAt = this.announcement.starts_at + this.editedAnnouncement.endsAt = this.announcement.ends_at + this.editedAnnouncement.allDay = this.announcement.all_day + this.editing = true + }, + submitEdit () { + this.$store.dispatch('editAnnouncement', { + id: this.announcement.id, + ...this.editedAnnouncement + }) + .then(() => { + this.editing = false + }) + .catch(error => { + this.editError = error.error + }) + }, + cancelEdit () { + this.editing = false + }, + clearError () { + this.editError = undefined + } + } +} + +export default Announcement diff --git a/src/components/announcement/announcement.vue b/src/components/announcement/announcement.vue @@ -0,0 +1,136 @@ +<template> + <div class="announcement"> + <div class="heading"> + <h4>{{ $t('announcements.title') }}</h4> + </div> + <div class="body"> + <rich-content + v-if="!editing" + :html="content" + :emoji="announcement.emojis" + :handle-links="true" + /> + <announcement-editor + v-else + :announcement="editedAnnouncement" + /> + </div> + <div class="footer"> + <div + v-if="!editing" + class="times" + > + <span v-if="publishedAt"> + {{ $t('announcements.published_time_display', { time: publishedAt }) }} + </span> + <span v-if="startsAt"> + {{ $t('announcements.start_time_display', { time: startsAt }) }} + </span> + <span v-if="endsAt"> + {{ $t('announcements.end_time_display', { time: endsAt }) }} + </span> + </div> + <div + v-if="!editing" + class="actions" + > + <button + v-if="currentUser" + class="btn button-default" + :class="{ toggled: isRead }" + :disabled="inactive" + :title="inactive ? $t('announcements.inactive_message') : ''" + @click="markAsRead" + > + {{ $t('announcements.mark_as_read_action') }} + </button> + <button + v-if="canEditAnnouncement" + class="btn button-default" + @click="enterEditMode" + > + {{ $t('announcements.edit_action') }} + </button> + <button + v-if="canEditAnnouncement" + class="btn button-default" + @click="deleteAnnouncement" + > + {{ $t('announcements.delete_action') }} + </button> + </div> + <div + v-else + class="actions" + > + <button + class="btn button-default" + @click="submitEdit" + > + {{ $t('announcements.submit_edit_action') }} + </button> + <button + class="btn button-default" + @click="cancelEdit" + > + {{ $t('announcements.cancel_edit_action') }} + </button> + <div + v-if="editing && editError" + class="alert error" + > + {{ $t('announcements.edit_error', { error }) }} + <button + class="button-unstyled" + @click="clearError" + > + <FAIcon + class="fa-scale-110 fa-old-padding" + icon="times" + :title="$t('announcements.close_error')" + /> + </button> + </div> + </div> + </div> + </div> +</template> + +<script src="./announcement.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.announcement { + border-bottom: 1px solid var(--border, $fallback--border); + border-radius: 0; + padding: var(--status-margin, $status-margin); + + .heading, + .body { + margin-bottom: var(--status-margin, $status-margin); + } + + .footer { + display: flex; + flex-direction: column; + + .times { + display: flex; + flex-direction: column; + } + } + + .footer .actions { + display: flex; + flex-direction: row; + justify-content: space-evenly; + + .btn { + flex: 1; + margin: 1em; + max-width: 10em; + } + } +} +</style> diff --git a/src/components/announcement_editor/announcement_editor.js b/src/components/announcement_editor/announcement_editor.js @@ -0,0 +1,13 @@ +import Checkbox from '../checkbox/checkbox.vue' + +const AnnouncementEditor = { + components: { + Checkbox + }, + props: { + announcement: Object, + disabled: Boolean + } +} + +export default AnnouncementEditor diff --git a/src/components/announcement_editor/announcement_editor.vue b/src/components/announcement_editor/announcement_editor.vue @@ -0,0 +1,60 @@ +<template> + <div class="announcement-editor"> + <textarea + ref="textarea" + v-model="announcement.content" + class="post-textarea" + rows="1" + cols="1" + :placeholder="$t('announcements.post_placeholder')" + :disabled="disabled" + /> + <span class="announcement-metadata"> + <label for="announcement-start-time">{{ $t('announcements.start_time_prompt') }}</label> + <input + id="announcement-start-time" + v-model="announcement.startsAt" + :type="announcement.allDay ? 'date' : 'datetime-local'" + :disabled="disabled" + > + </span> + <span class="announcement-metadata"> + <label for="announcement-end-time">{{ $t('announcements.end_time_prompt') }}</label> + <input + id="announcement-end-time" + v-model="announcement.endsAt" + :type="announcement.allDay ? 'date' : 'datetime-local'" + :disabled="disabled" + > + </span> + <span class="announcement-metadata"> + <Checkbox + id="announcement-all-day" + v-model="announcement.allDay" + :disabled="disabled" + /> + <label for="announcement-all-day">{{ $t('announcements.all_day_prompt') }}</label> + </span> + </div> +</template> + +<script src="./announcement_editor.js"></script> + +<style lang="scss"> +.announcement-editor { + display: flex; + align-items: stretch; + flex-direction: column; + + .announcement-metadata { + margin-top: 0.5em; + } + + .post-textarea { + resize: vertical; + height: 10em; + overflow: none; + box-sizing: content-box; + } +} +</style> diff --git a/src/components/announcements_page/announcements_page.js b/src/components/announcements_page/announcements_page.js @@ -0,0 +1,58 @@ +import { mapState } from 'vuex' +import Announcement from '../announcement/announcement.vue' +import AnnouncementEditor from '../announcement_editor/announcement_editor.vue' + +const AnnouncementsPage = { + components: { + Announcement, + AnnouncementEditor + }, + data () { + return { + newAnnouncement: { + content: '', + startsAt: undefined, + endsAt: undefined, + allDay: false + }, + posting: false, + error: undefined + } + }, + mounted () { + this.$store.dispatch('fetchAnnouncements') + }, + computed: { + ...mapState({ + currentUser: state => state.users.currentUser + }), + announcements () { + return this.$store.state.announcements.announcements + }, + canPostAnnouncement () { + return this.currentUser && this.currentUser.privileges.includes('announcements_manage_announcements') + } + }, + methods: { + postAnnouncement () { + this.posting = true + this.$store.dispatch('postAnnouncement', this.newAnnouncement) + .then(() => { + this.newAnnouncement.content = '' + this.startsAt = undefined + this.endsAt = undefined + }) + .catch(error => { + this.error = error.error + }) + .finally(() => { + this.posting = false + }) + }, + clearError () { + this.error = undefined + } + } +} + +export default AnnouncementsPage diff --git a/src/components/announcements_page/announcements_page.vue b/src/components/announcements_page/announcements_page.vue @@ -0,0 +1,80 @@ +<template> + <div class="panel panel-default announcements-page"> + <div class="panel-heading"> + <span> + {{ $t('announcements.page_header') }} + </span> + </div> + <div class="panel-body"> + <section + v-if="canPostAnnouncement" + > + <div class="post-form"> + <div class="heading"> + <h4>{{ $t('announcements.post_form_header') }}</h4> + </div> + <div class="body"> + <announcement-editor + :announcement="newAnnouncement" + :disabled="posting" + /> + </div> + <div class="footer"> + <button + class="btn button-default post-button" + :disabled="posting" + @click.prevent="postAnnouncement" + > + {{ $t('announcements.post_action') }} + </button> + <div + v-if="error" + class="alert error" + > + {{ $t('announcements.post_error', { error }) }} + <button + class="button-unstyled" + @click="clearError" + > + <FAIcon + class="fa-scale-110 fa-old-padding" + icon="times" + :title="$t('announcements.close_error')" + /> + </button> + </div> + </div> + </div> + </section> + <section + v-for="announcement in announcements" + :key="announcement.id" + > + <announcement + :announcement="announcement" + /> + </section> + </div> + </div> +</template> + +<script src="./announcements_page.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.announcements-page { + .post-form { + padding: var(--status-margin, $status-margin); + + .heading, + .body { + margin-bottom: var(--status-margin, $status-margin); + } + + .post-button { + min-width: 10em; + } + } +} +</style> diff --git a/src/components/async_component_error/async_component_error.vue b/src/components/async_component_error/async_component_error.vue @@ -34,9 +34,10 @@ export default { height: 100%; align-items: center; justify-content: center; + .btn { - margin: .5em; - padding: .5em 2em; + margin: 0.5em; + padding: 0.5em 2em; } } </style> diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js @@ -36,6 +36,7 @@ library.add( const Attachment = { props: [ 'attachment', + 'compact', 'description', 'hideDescription', 'nsfw', @@ -71,7 +72,8 @@ const Attachment = { { '-loading': this.loading, '-nsfw-placeholder': this.hidden, - '-editable': this.edit !== undefined + '-editable': this.edit !== undefined, + '-compact': this.compact }, '-type-' + this.type, this.size && '-size-' + this.size, @@ -129,6 +131,9 @@ const Attachment = { ...mapGetters(['mergedConfig']) }, watch: { + 'attachment.description' (newVal) { + this.localDescription = newVal + }, localDescription (newVal) { this.onEdit(newVal) } diff --git a/src/components/attachment/attachment.scss b/src/components/attachment/attachment.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .Attachment { display: inline-flex; @@ -102,14 +102,13 @@ padding-top: 0.5em; } - .play-icon { position: absolute; font-size: 64px; top: calc(50% - 32px); left: calc(50% - 32px); - color: rgba(255, 255, 255, 0.75); - text-shadow: 0 0 2px rgba(0, 0, 0, 0.4); + color: rgb(255 255 255 / 75%); + text-shadow: 0 0 2px rgb(0 0 0 / 40%); &::before { margin: 0; @@ -135,18 +134,32 @@ margin-left: 0.5em; font-size: 1.25em; // TODO: theming? hard to theme with unknown background image color - background: rgba(230, 230, 230, 0.7); + background: rgb(230 230 230 / 70%); .svg-inline--fa { - color: rgba(0, 0, 0, 0.6); + color: rgb(0 0 0 / 60%); } &:hover .svg-inline--fa { - color: rgba(0, 0, 0, 0.9); + color: rgb(0 0 0 / 90%); } } } + &.-contain-fit { + img, + canvas { + object-fit: contain; + } + } + + &.-cover-fit { + img, + canvas { + object-fit: cover; + } + } + .oembed-container { line-height: 1.2em; flex: 1 0 100%; @@ -160,8 +173,9 @@ .image { flex: 1; + img { - border: 0px; + border: 0; border-radius: 5px; height: 100%; object-fit: cover; @@ -172,9 +186,10 @@ flex: 2; margin: 8px; word-break: break-all; + h1 { font-size: 1rem; - margin: 0px; + margin: 0; } } } @@ -252,17 +267,9 @@ cursor: progress; } - &.-contain-fit { - img, - canvas { - object-fit: contain; - } - } - - &.-cover-fit { - img, - canvas { - object-fit: cover; + &.-compact { + .placeholder-container { + padding-bottom: 0.5em; } } } diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue @@ -162,10 +162,11 @@ target="_blank" > <FAIcon - size="5x" + :size="compact ? '2x' : '5x'" :icon="placeholderIconClass" + :title="localDescription" /> - <p> + <p v-if="!compact"> {{ localDescription }} </p> </a> diff --git a/src/components/autosuggest/autosuggest.vue b/src/components/autosuggest/autosuggest.vue @@ -24,7 +24,7 @@ <script src="./autosuggest.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .autosuggest { position: relative; @@ -50,7 +50,7 @@ border-radius: var(--inputRadius, $fallback--inputRadius); border-top-left-radius: 0; border-top-right-radius: 0; - box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6); + box-shadow: 1px 1px 4px rgb(0 0 0 / 60%); box-shadow: var(--panelShadow); overflow-y: auto; z-index: 1; diff --git a/src/components/avatar_list/avatar_list.vue b/src/components/avatar_list/avatar_list.vue @@ -17,7 +17,7 @@ <script src="./avatar_list.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .avatars { display: flex; diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js @@ -1,5 +1,6 @@ import UserPopover from '../user_popover/user_popover.vue' import UserAvatar from '../user_avatar/user_avatar.vue' +import UserLink from '../user_link/user_link.vue' import RichContent from 'src/components/rich_content/rich_content.jsx' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' @@ -10,7 +11,8 @@ const BasicUserCard = { components: { UserPopover, UserAvatar, - RichContent + RichContent, + UserLink }, methods: { userProfileLink (user) { diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue @@ -30,12 +30,10 @@ /> </div> <div> - <router-link + <user-link class="basic-user-card-screen-name" - :to="userProfileLink(user)" - > - @{{ user.screen_name_ui }} - </router-link> + :user="user" + /> </div> <slot /> </div> @@ -51,7 +49,7 @@ margin: 0; padding: 0.6em 1em; - --emoji-size: 14px; + --emoji-size: 14px; &-collapsed-content { margin-left: 0.7em; diff --git a/src/components/block_card/block_card.vue b/src/components/block_card/block_card.vue @@ -37,6 +37,7 @@ .block-card-content-container { margin-top: 0.5em; text-align: right; + button { width: 10em; } diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js @@ -57,6 +57,7 @@ const Chat = { }, unmounted () { window.removeEventListener('scroll', this.handleScroll) + window.removeEventListener('resize', this.handleResize) if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false) this.$store.dispatch('clearCurrentChat') }, @@ -135,7 +136,7 @@ const Chat = { }, // "Sticks" scroll to bottom instead of top, helps with OSK resizing the viewport handleResize (opts = {}) { - const { expand = false, delayed = false } = opts + const { delayed = false } = opts if (delayed) { setTimeout(() => { @@ -146,10 +147,10 @@ const Chat = { this.$nextTick(() => { const { offsetHeight = undefined } = getScrollPosition() - const diff = this.lastScrollPosition.offsetHeight - offsetHeight - if (diff !== 0 || (!this.bottomedOut() && expand)) { + const diff = offsetHeight - this.lastScrollPosition.offsetHeight + if (diff !== 0 && !this.bottomedOut()) { this.$nextTick(() => { - window.scrollTo({ top: window.scrollY + diff }) + window.scrollBy({ top: -Math.trunc(diff) }) }) } this.lastScrollPosition = getScrollPosition() @@ -187,6 +188,7 @@ const Chat = { }, 5000) }, handleScroll: _.throttle(function () { + this.lastScrollPosition = getScrollPosition() if (!this.currentChat) { return } if (this.reachedTop()) { diff --git a/src/components/chat/chat.scss b/src/components/chat/chat.scss @@ -17,7 +17,7 @@ width: 100%; overflow: visible; min-height: calc(100vh - var(--navbar-height)); - margin: 0 0 0 0; + margin: 0; border-radius: 10px 10px 0 0; border-radius: var(--panelRadius, 10px) var(--panelRadius, 10px) 0 0; @@ -66,7 +66,7 @@ display: flex; justify-content: center; align-items: center; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 1px rgb(0 0 0 / 30%), 0 2px 4px rgb(0 0 0 / 30%); z-index: 10; transition: 0.35s all; transition-timing-function: cubic-bezier(0, 1, 0.5, 1); diff --git a/src/components/chat/chat.vue b/src/components/chat/chat.vue @@ -95,6 +95,6 @@ <script src="./chat.js"></script> <style lang="scss"> -@import '../../_variables.scss'; -@import './chat.scss'; +@import "../../variables"; +@import "./chat"; </style> diff --git a/src/components/chat_list/chat_list.vue b/src/components/chat_list/chat_list.vue @@ -45,7 +45,7 @@ <script src="./chat_list.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .chat-list { min-height: 25em; diff --git a/src/components/chat_list_item/chat_list_item.scss b/src/components/chat_list_item/chat_list_item.scss @@ -13,7 +13,7 @@ &:hover { background-color: var(--selectedPost, $fallback--lightBg); - box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.1); + box-shadow: 0 0 3px 1px rgb(0 0 0 / 10%); } .chat-list-item-left { @@ -67,6 +67,7 @@ canvas { display: none; } + img { visibility: visible; } @@ -79,13 +80,11 @@ .chat-preview-body { --emoji-size: 1.4em; + + padding-right: 1em; } .time-wrapper { line-height: var(--post-line-height); } - - .chat-preview-body { - padding-right: 1em; - } } diff --git a/src/components/chat_list_item/chat_list_item.vue b/src/components/chat_list_item/chat_list_item.vue @@ -48,6 +48,6 @@ <script src="./chat_list_item.js"></script> <style lang="scss"> -@import '../../_variables.scss'; -@import './chat_list_item.scss'; +@import "../../variables"; +@import "./chat_list_item"; </style> diff --git a/src/components/chat_message/chat_message.scss b/src/components/chat_message/chat_message.scss @@ -1,12 +1,12 @@ -@import '../../_variables.scss'; +@import "../../variables"; .chat-message-wrapper { - &.hovered-message-chain { .animated.Avatar { canvas { display: none; } + img { visibility: visible; } @@ -28,7 +28,8 @@ .menu-icon { cursor: pointer; - &:hover, .extra-button-popover.open & { + &:hover, + .extra-button-popover.open & { color: $fallback--text; color: var(--text, $fallback--text); } @@ -54,27 +55,11 @@ width: 32px; } - .link-preview, .attachments { + .link-preview, + .attachments { margin-bottom: 1em; } - .chat-message-inner { - display: flex; - flex-direction: column; - align-items: flex-start; - max-width: 80%; - min-width: 10em; - width: 100%; - - &.with-media { - width: 100%; - - .status { - width: 100%; - } - } - } - .status { border-radius: $fallback--chatMessageRadius; border-radius: var(--chatMessageRadius, $fallback--chatMessageRadius); @@ -86,7 +71,7 @@ position: relative; float: right; font-size: 0.8em; - margin: -1em 0 -0.5em 0; + margin: -1em 0 -0.5em; font-style: italic; opacity: 0.8; } @@ -103,18 +88,54 @@ } .pending { - .status-content.media-body, .created-at { + .status-content.media-body, + .created-at { color: var(--faint); } } .error { - .status-content.media-body, .created-at { + .status-content.media-body, + .created-at { color: $fallback--cRed; color: var(--badgeNotification, $fallback--cRed); } } + .chat-message-inner { + display: flex; + flex-direction: column; + align-items: flex-start; + max-width: 80%; + min-width: 10em; + width: 100%; + } + + .outgoing { + display: flex; + flex-flow: row wrap; + align-content: end; + justify-content: flex-end; + + a { + color: var(--chatMessageOutgoingLink, $fallback--link); + } + + .status { + color: var(--chatMessageOutgoingText, $fallback--text); + background-color: var(--chatMessageOutgoingBg, $fallback--lightBg); + border: 1px solid var(--chatMessageOutgoingBorder, --lightBg); + } + + .chat-message-inner { + align-items: flex-end; + } + + .chat-message-menu { + right: 0.4rem; + } + } + .incoming { a { color: var(--chatMessageIncomingLink, $fallback--link); @@ -137,36 +158,17 @@ } } - .outgoing { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-content: end; - justify-content: flex-end; - - a { - color: var(--chatMessageOutgoingLink, $fallback--link); - } + .chat-message-inner.with-media { + width: 100%; .status { - color: var(--chatMessageOutgoingText, $fallback--text); - background-color: var(--chatMessageOutgoingBg, $fallback--lightBg); - border: 1px solid var(--chatMessageOutgoingBorder, --lightBg); - } - - .chat-message-inner { - align-items: flex-end; - } - - .chat-message-menu { - right: 0.4rem; + width: 100%; } } .visible { opacity: 1; } - } .chat-message-date-separator { diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue @@ -33,7 +33,7 @@ <div class="media status" :class="{ 'without-attachment': !hasAttachment, 'pending': chatViewItem.data.pending, 'error': chatViewItem.data.error }" - style="position: relative" + style="position: relative;" @mouseenter="hovered = true" @mouseleave="hovered = false" > @@ -98,6 +98,6 @@ <script src="./chat_message.js"></script> <style lang="scss"> -@import './chat_message.scss'; +@import "./chat_message"; </style> diff --git a/src/components/chat_new/chat_new.scss b/src/components/chat_new/chat_new.scss @@ -1,7 +1,7 @@ .chat-new { .input-wrap { display: flex; - margin: 0.7em 0.5em 0.7em 0.5em; + margin: 0.7em 0.5em; input { width: 100%; diff --git a/src/components/chat_new/chat_new.vue b/src/components/chat_new/chat_new.vue @@ -46,6 +46,6 @@ <script src="./chat_new.js"></script> <style lang="scss"> -@import '../../_variables.scss'; -@import './chat_new.scss'; +@import "../../variables"; +@import "./chat_new"; </style> diff --git a/src/components/chat_title/chat_title.vue b/src/components/chat_title/chat_title.vue @@ -26,7 +26,7 @@ <script src="./chat_title.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .chat-title { display: flex; diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue @@ -32,7 +32,7 @@ export default { </script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .checkbox { position: relative; @@ -49,13 +49,13 @@ export default { right: 0; top: 0; display: block; - content: '✓'; + content: "✓"; transition: color 200ms; width: 1.1em; height: 1.1em; border-radius: $fallback--checkboxRadius; border-radius: var(--checkboxRadius, $fallback--checkboxRadius); - box-shadow: 0px 0px 2px black inset; + box-shadow: 0 0 2px black inset; box-shadow: var(--inputShadow); background-color: $fallback--fg; background-color: var(--input, $fallback--fg); @@ -71,15 +71,16 @@ export default { &.disabled { .checkbox-indicator::before, .label { - opacity: .5; + opacity: 0.5; } + .label { color: $fallback--faint; color: var(--faint, $fallback--faint); } } - input[type=checkbox] { + input[type="checkbox"] { display: none; &:checked + .checkbox-indicator::before { @@ -88,15 +89,14 @@ export default { } &:indeterminate + .checkbox-indicator::before { - content: '–'; + content: "–"; color: $fallback--text; color: var(--inputText, $fallback--text); } - } & > span { - margin-left: .5em; + margin-left: 0.5em; } } </style> diff --git a/src/components/color_input/color_input.scss b/src/components/color_input/color_input.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .color-input { display: inline-flex; @@ -8,7 +8,7 @@ flex: 0 0 0; max-width: 9em; align-items: stretch; - padding: .2em 8px; + padding: 0.2em 8px; input { background: none; @@ -27,33 +27,39 @@ &.nativeColor { flex: 0 0 2em; min-width: 2em; - align-self: center; - height: 100%; + align-self: stretch; + min-height: 100%; } } + .computedIndicator, .transparentIndicator { flex: 0 0 2em; min-width: 2em; - align-self: center; - height: 100%; + align-self: stretch; + min-height: 100%; } + .transparentIndicator { // forgot to install counter-strike source, ooops - background-color: #FF00FF; + background-color: #f0f; position: relative; - &::before, &::after { + + &::before, + &::after { display: block; - content: ''; - background-color: #000000; + content: ""; + background-color: #000; position: absolute; height: 50%; width: 50%; } + &::after { top: 0; left: 0; } + &::before { bottom: 0; right: 0; @@ -64,5 +70,4 @@ .label { flex: 1 1 auto; } - } diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue @@ -87,7 +87,6 @@ export default { .contrast-ratio { display: flex; justify-content: flex-end; - margin-top: -4px; margin-bottom: 5px; diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js @@ -1,6 +1,10 @@ import { reduce, filter, findIndex, clone, get } from 'lodash' import Status from '../status/status.vue' import ThreadTree from '../thread_tree/thread_tree.vue' +import { WSConnectionStatus } from '../../services/api/api.service.js' +import { mapGetters, mapState } from 'vuex' +import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.vue' +import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -77,6 +81,9 @@ const conversation = { const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2 return maxDepth >= 1 ? maxDepth : 1 }, + streamingEnabled () { + return this.mergedConfig.useStreamingApi && this.mastoUserSocketStatus === WSConnectionStatus.JOINED + }, displayStyle () { return this.$store.getters.mergedConfig.conversationDisplay }, @@ -339,11 +346,17 @@ const conversation = { }, maybeHighlight () { return this.isExpanded ? this.highlight : null - } + }, + ...mapGetters(['mergedConfig']), + ...mapState({ + mastoUserSocketStatus: state => state.api.mastoUserSocketStatus + }) }, components: { Status, - ThreadTree + ThreadTree, + QuickFilterSettings, + QuickViewSettings }, watch: { statusId (newVal, oldVal) { @@ -395,6 +408,11 @@ const conversation = { setHighlight (id) { if (!id) return this.highlight = id + + if (!this.streamingEnabled) { + this.$store.dispatch('fetchStatus', id) + } + this.$store.dispatch('fetchFavsAndRepeats', id) this.$store.dispatch('fetchEmojiReactionsBy', id) }, diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue @@ -17,6 +17,16 @@ > {{ $t('timeline.collapse') }} </button> + <QuickFilterSettings + v-if="!collapsable" + :conversation="true" + class="rightside-button" + /> + <QuickViewSettings + v-if="!collapsable" + :conversation="true" + class="rightside-button" + /> </div> <div class="conversation-body panel-body"> <div @@ -50,7 +60,7 @@ v-if="shouldShowAncestors" class="thread-ancestors" > - <div + <article v-for="status in ancestorsOf(diveRoot)" :key="status.id" class="thread-ancestor" @@ -120,7 +130,7 @@ </i18n-t> </div> </div> - </div> + </article> </div> <thread-tree v-for="status in showingTopLevel" @@ -158,34 +168,36 @@ v-if="isLinearView" class="thread-body" > - <status - v-for="status in conversation" - :key="status.id" - ref="statusComponent" - :inline-expanded="collapsable && isExpanded" - :statusoid="status" - :expandable="!isExpanded" - :show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]" - :focused="focused(status.id)" - :in-conversation="isExpanded" - :highlight="getHighlight()" - :replies="getReplies(status.id)" - :in-profile="inProfile" - :profile-user-id="profileUserId" - class="conversation-status status-fadein panel-body" + <article> + <status + v-for="status in conversation" + :key="status.id" + ref="statusComponent" + :inline-expanded="collapsable && isExpanded" + :statusoid="status" + :expandable="!isExpanded" + :show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]" + :focused="focused(status.id)" + :in-conversation="isExpanded" + :highlight="getHighlight()" + :replies="getReplies(status.id)" + :in-profile="inProfile" + :profile-user-id="profileUserId" + class="conversation-status status-fadein panel-body" - :toggle-thread-display="toggleThreadDisplay" - :thread-display-status="threadDisplayStatus" - :show-thread-recursively="showThreadRecursively" - :total-reply-count="totalReplyCount" - :total-reply-depth="totalReplyDepth" - :status-content-properties="statusContentProperties" - :set-status-content-property="setStatusContentProperty" - :toggle-status-content-property="toggleStatusContentProperty" + :toggle-thread-display="toggleThreadDisplay" + :thread-display-status="threadDisplayStatus" + :show-thread-recursively="showThreadRecursively" + :total-reply-count="totalReplyCount" + :total-reply-depth="totalReplyDepth" + :status-content-properties="statusContentProperties" + :set-status-content-property="setStatusContentProperty" + :toggle-status-content-property="toggleStatusContentProperty" - @goto="setHighlight" - @toggleExpanded="toggleExpanded" - /> + @goto="setHighlight" + @toggleExpanded="toggleExpanded" + /> + </article> </div> </div> </div> @@ -198,17 +210,16 @@ <script src="./conversation.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .Conversation { z-index: 1; .conversation-dive-to-top-level-box { padding: var(--status-margin, $status-margin); - border-bottom-width: 1px; - border-bottom-style: solid; - border-bottom-color: var(--border, $fallback--border); + border-bottom: 1px solid var(--border, $fallback--border); border-radius: 0; + /* Make the button stretch along the whole row */ display: flex; align-items: stretch; @@ -223,52 +234,48 @@ .thread-ancestor.-faded .StatusContent { --link: var(--faintLink); --text: var(--faint); + color: var(--text); } .thread-ancestor-dive-box { padding-left: var(--status-margin, $status-margin); - border-bottom-width: 1px; - border-bottom-style: solid; - border-bottom-color: var(--border, $fallback--border); + border-bottom: 1px solid var(--border, $fallback--border); border-radius: 0; + /* Make the button stretch along the whole row */ - &, &-inner { + &, + &-inner { display: flex; align-items: stretch; flex-direction: column; } } + .thread-ancestor-dive-box-inner { padding: var(--status-margin, $status-margin); } .conversation-status { - border-bottom-width: 1px; - border-bottom-style: solid; - border-bottom-color: var(--border, $fallback--border); + border-bottom: 1px solid var(--border, $fallback--border); border-radius: 0; } .thread-ancestor-has-other-replies .conversation-status, + &:last-child .conversation-status, .thread-ancestor:last-child .conversation-status, .thread-ancestor:last-child .thread-ancestor-dive-box, - &:last-child .conversation-status, &.-expanded .thread-tree .conversation-status { border-bottom: none; } .thread-ancestors + .thread-tree > .conversation-status { - border-top-width: 1px; - border-top-style: solid; - border-top-color: var(--border, $fallback--border); + border-top: 1px solid var(--border, $fallback--border); } /* expanded conversation in timeline */ &.status-fadein.-expanded .thread-body { - border-left-width: 4px; - border-left-style: solid; - border-left-color: $fallback--cRed; + border-left: 4px solid $fallback--cRed; border-left-color: var(--cRed, $fallback--cRed); border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius; border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius); diff --git a/src/components/desktop_nav/desktop_nav.scss b/src/components/desktop_nav/desktop_nav.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .DesktopNav { width: 100%; @@ -23,13 +23,37 @@ max-width: 980px; } + &.-column-stretch .inner-nav { + --miniColumn: 25rem; + --maxiColumn: 45rem; + --columnGap: 1em; + + max-width: + calc( + var(--sidebarColumnWidth, var(--miniColumn)) + + var(--contentColumnWidth, var(--maxiColumn)) + + var(--columnGap) + ); + } + &.-logoLeft .inner-nav { grid-template-columns: auto 2fr 2fr; grid-template-areas: "logo sitename actions"; } + &.-column-stretch.-wide .inner-nav { + max-width: + calc( + var(--sidebarColumnWidth, var(--miniColumn)) + + var(--contentColumnWidth, var(--maxiColumn)) + + var(--notifsColumnWidth, var(--miniColumn)) + + var(--columnGap) + ); + } + .button-default { - &, svg { + &, + svg { color: $fallback--text; color: var(--btnTopBarText, $fallback--text); } @@ -50,7 +74,7 @@ color: $fallback--text; color: var(--btnToggledTopBarText, $fallback--text); background-color: $fallback--fg; - background-color: var(--btnToggledTopBar, $fallback--fg) + background-color: var(--btnToggledTopBar, $fallback--fg); } } @@ -62,6 +86,7 @@ transition-duration: 100ms; @media all and (min-width: 800px) { + /* stylelint-disable-next-line declaration-no-important */ opacity: 1 !important; } @@ -117,4 +142,8 @@ text-align: right; } } + + .spacer { + width: 1em; + } } diff --git a/src/components/desktop_nav/desktop_nav.vue b/src/components/desktop_nav/desktop_nav.vue @@ -38,7 +38,7 @@ /> <button class="button-unstyled nav-icon" - @click="openSettingsModal" + @click.stop="openSettingsModal" > <FAIcon fixed-width @@ -61,10 +61,11 @@ :title="$t('nav.administration')" /> </a> + <span class="spacer" /> <button v-if="currentUser" class="button-unstyled nav-icon" - @click.prevent="logout" + @click.stop.prevent="logout" > <FAIcon fixed-width diff --git a/src/components/dialog_modal/dialog_modal.vue b/src/components/dialog_modal/dialog_modal.vue @@ -25,7 +25,7 @@ <script src="./dialog_modal.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; // TODO: unify with other modals. .dark-overlay { @@ -38,7 +38,7 @@ position: fixed; right: 0; top: 0; - background: rgba(27,31,35,.5); + background: rgb(27 31 35 / 50%); z-index: 99; } } @@ -65,7 +65,7 @@ .dialog-modal-content { margin: 0; - padding: 1rem 1rem; + padding: 1rem; background-color: $fallback--bg; background-color: var(--bg, $fallback--bg); white-space: normal; @@ -73,7 +73,7 @@ .dialog-modal-footer { margin: 0; - padding: .5em .5em; + padding: 0.5em; background-color: $fallback--bg; background-color: var(--bg, $fallback--bg); border-top: 1px solid $fallback--border; @@ -83,7 +83,7 @@ button { width: auto; - margin-left: .5rem; + margin-left: 0.5rem; } } } diff --git a/src/components/edit_status_modal/edit_status_modal.js b/src/components/edit_status_modal/edit_status_modal.js @@ -0,0 +1,75 @@ +import PostStatusForm from '../post_status_form/post_status_form.vue' +import Modal from '../modal/modal.vue' +import statusPosterService from '../../services/status_poster/status_poster.service.js' +import get from 'lodash/get' + +const EditStatusModal = { + components: { + PostStatusForm, + Modal + }, + data () { + return { + resettingForm: false + } + }, + computed: { + isLoggedIn () { + return !!this.$store.state.users.currentUser + }, + modalActivated () { + return this.$store.state.editStatus.modalActivated + }, + isFormVisible () { + return this.isLoggedIn && !this.resettingForm && this.modalActivated + }, + params () { + return this.$store.state.editStatus.params || {} + } + }, + watch: { + params (newVal, oldVal) { + if (get(newVal, 'statusId') !== get(oldVal, 'statusId')) { + this.resettingForm = true + this.$nextTick(() => { + this.resettingForm = false + }) + } + }, + isFormVisible (val) { + if (val) { + this.$nextTick(() => this.$el && this.$el.querySelector('textarea').focus()) + } + } + }, + methods: { + doEditStatus ({ status, spoilerText, sensitive, media, contentType, poll }) { + const params = { + store: this.$store, + statusId: this.$store.state.editStatus.params.statusId, + status, + spoilerText, + sensitive, + poll, + media, + contentType + } + + return statusPosterService.editStatus(params) + .then((data) => { + return data + }) + .catch((err) => { + console.error('Error editing status', err) + return { + error: err.message + } + }) + }, + closeModal () { + this.$store.dispatch('closeEditStatusModal') + } + } +} + +export default EditStatusModal diff --git a/src/components/edit_status_modal/edit_status_modal.vue b/src/components/edit_status_modal/edit_status_modal.vue @@ -0,0 +1,49 @@ +<template> + <Modal + v-if="isFormVisible" + class="edit-form-modal-view" + @backdropClicked="closeModal" + > + <div class="edit-form-modal-panel panel"> + <div class="panel-heading"> + {{ $t('post_status.edit_status') }} + </div> + <PostStatusForm + class="panel-body" + v-bind="params" + :post-handler="doEditStatus" + :disable-polls="true" + :disable-visibility-selector="true" + @posted="closeModal" + /> + </div> + </Modal> +</template> + +<script src="./edit_status_modal.js"></script> + +<style lang="scss"> +.modal-view.edit-form-modal-view { + align-items: flex-start; +} + +.edit-form-modal-panel { + flex-shrink: 0; + margin-top: 25%; + margin-bottom: 2em; + width: 100%; + max-width: 700px; + + @media (orientation: landscape) { + margin-top: 8%; + } + + .form-bottom-left { + max-width: 6.5em; + + .emoji-icon { + justify-content: right; + } + } +} +</style> diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js @@ -1,8 +1,10 @@ import Completion from '../../services/completion/completion.js' import EmojiPicker from '../emoji_picker/emoji_picker.vue' +import Popover from 'src/components/popover/popover.vue' +import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import { take } from 'lodash' import { findOffset } from '../../services/offset_finder/offset_finder.service.js' - +import { ensureFinalFallback } from '../../i18n/languages.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faSmileBeam @@ -108,46 +110,122 @@ const EmojiInput = { data () { return { input: undefined, + caretEl: undefined, highlighted: 0, caret: 0, focused: false, blurTimeout: null, - showPicker: false, temporarilyHideSuggestions: false, - keepOpen: false, disableClickOutside: false, - suggestions: [] + suggestions: [], + overlayStyle: {}, + pickerShown: false } }, components: { - EmojiPicker + Popover, + EmojiPicker, + UnicodeDomainIndicator }, computed: { padEmoji () { return this.$store.getters.mergedConfig.padEmoji }, + preText () { + return this.modelValue.slice(0, this.caret) + }, + postText () { + return this.modelValue.slice(this.caret) + }, showSuggestions () { return this.focused && this.suggestions && this.suggestions.length > 0 && - !this.showPicker && + !this.pickerShown && !this.temporarilyHideSuggestions }, textAtCaret () { - return (this.wordAtCaret || {}).word || '' + return this.wordAtCaret?.word }, wordAtCaret () { if (this.modelValue && this.caret) { const word = Completion.wordAtPosition(this.modelValue, this.caret - 1) || {} return word } + }, + languages () { + return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage) + }, + maybeLocalizedEmojiNamesAndKeywords () { + return emoji => { + const names = [emoji.displayText] + const keywords = [] + + if (emoji.displayTextI18n) { + names.push(this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)) + } + + if (emoji.annotations) { + this.languages.forEach(lang => { + names.push(emoji.annotations[lang]?.name) + + keywords.push(...(emoji.annotations[lang]?.keywords || [])) + }) + } + + return { + names: names.filter(k => k), + keywords: keywords.filter(k => k) + } + } + }, + maybeLocalizedEmojiName () { + return emoji => { + if (!emoji.annotations) { + return emoji.displayText + } + + if (emoji.displayTextI18n) { + return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args) + } + + for (const lang of this.languages) { + if (emoji.annotations[lang]?.name) { + return emoji.annotations[lang].name + } + } + + return emoji.displayText + } + }, + onInputScroll () { + this.$refs.hiddenOverlay.scrollTo({ + top: this.input.scrollTop, + left: this.input.scrollLeft + }) } }, mounted () { - const { root } = this.$refs + const { root, hiddenOverlayCaret, suggestorPopover } = this.$refs const input = root.querySelector('.emoji-input > input') || root.querySelector('.emoji-input > textarea') if (!input) return this.input = input + this.caretEl = hiddenOverlayCaret + if (suggestorPopover.setAnchorEl) { + suggestorPopover.setAnchorEl(this.caretEl) // unit test compat + this.$refs.picker.setAnchorEl(this.caretEl) + } else { + console.warn('setAnchorEl not found, are we in a unit test?') + } + const style = getComputedStyle(this.input) + this.overlayStyle.padding = style.padding + this.overlayStyle.border = style.border + this.overlayStyle.margin = style.margin + this.overlayStyle.lineHeight = style.lineHeight + this.overlayStyle.fontFamily = style.fontFamily + this.overlayStyle.fontSize = style.fontSize + this.overlayStyle.wordWrap = style.wordWrap + this.overlayStyle.whiteSpace = style.whiteSpace this.resize() input.addEventListener('blur', this.onBlur) input.addEventListener('focus', this.onFocus) @@ -157,6 +235,7 @@ const EmojiInput = { input.addEventListener('click', this.onClickInput) input.addEventListener('transitionend', this.onTransition) input.addEventListener('input', this.onInput) + input.addEventListener('scroll', this.onInputScroll) }, unmounted () { const { input } = this @@ -169,46 +248,43 @@ const EmojiInput = { input.removeEventListener('click', this.onClickInput) input.removeEventListener('transitionend', this.onTransition) input.removeEventListener('input', this.onInput) + input.removeEventListener('scroll', this.onInputScroll) } }, watch: { - showSuggestions: function (newValue) { + showSuggestions: function (newValue, oldValue) { this.$emit('shown', newValue) + if (newValue) { + this.$refs.suggestorPopover.showPopover() + } else { + this.$refs.suggestorPopover.hidePopover() + } }, textAtCaret: async function (newWord) { + if (newWord === undefined) return const firstchar = newWord.charAt(0) - this.suggestions = [] - if (newWord === firstchar) return - const matchedSuggestions = await this.suggest(newWord) + if (newWord === firstchar) { + this.suggestions = [] + return + } + const matchedSuggestions = await this.suggest(newWord, this.maybeLocalizedEmojiNamesAndKeywords) // Async: cancel if textAtCaret has changed during wait - if (this.textAtCaret !== newWord) return - if (matchedSuggestions.length <= 0) return + if (this.textAtCaret !== newWord || matchedSuggestions.length <= 0) { + this.suggestions = [] + return + } this.suggestions = take(matchedSuggestions, 5) .map(({ imageUrl, ...rest }) => ({ ...rest, img: imageUrl || '' })) - }, - suggestions: { - handler (newValue) { - this.$nextTick(this.resize) - }, - deep: true } }, methods: { - focusPickerInput () { - const pickerEl = this.$refs.picker.$el - if (!pickerEl) return - const pickerInput = pickerEl.querySelector('input') - if (pickerInput) pickerInput.focus() - }, triggerShowPicker () { - this.showPicker = true - this.$refs.picker.startEmojiLoad() this.$nextTick(() => { + this.$refs.picker.showPicker() this.scrollIntoView() - this.focusPickerInput() }) // This temporarily disables "click outside" handler // since external trigger also means click originates @@ -220,11 +296,12 @@ const EmojiInput = { }, togglePicker () { this.input.focus() - this.showPicker = !this.showPicker - if (this.showPicker) { + if (!this.pickerShown) { this.scrollIntoView() + this.$refs.picker.showPicker() this.$refs.picker.startEmojiLoad() - this.$nextTick(this.focusPickerInput) + } else { + this.$refs.picker.hidePicker() } }, replace (replacement) { @@ -261,7 +338,6 @@ const EmojiInput = { spaceAfter, after ].join('') - this.keepOpen = keepOpen this.$emit('update:modelValue', newValue) const position = this.caret + (insertion + spaceAfter + spaceBefore).length if (!keepOpen) { @@ -361,8 +437,11 @@ const EmojiInput = { } }) }, - onTransition (e) { - this.resize() + onPickerShown () { + this.pickerShown = true + }, + onPickerClosed () { + this.pickerShown = false }, onBlur (e) { // Clicking on any suggestion removes focus from autocomplete, @@ -370,7 +449,6 @@ const EmojiInput = { this.blurTimeout = setTimeout(() => { this.focused = false this.setCaret(e) - this.resize() }, 200) }, onClick (e, suggestion) { @@ -382,18 +460,13 @@ const EmojiInput = { this.blurTimeout = null } - if (!this.keepOpen) { - this.showPicker = false - } this.focused = true this.setCaret(e) - this.resize() this.temporarilyHideSuggestions = false }, onKeyUp (e) { const { key } = e this.setCaret(e) - this.resize() // Setting hider in keyUp to prevent suggestions from blinking // when moving away from suggested spot @@ -405,7 +478,6 @@ const EmojiInput = { }, onPaste (e) { this.setCaret(e) - this.resize() }, onKeyDown (e) { const { ctrlKey, shiftKey, key } = e @@ -450,58 +522,24 @@ const EmojiInput = { this.input.focus() } } - - this.showPicker = false - this.resize() }, onInput (e) { - this.showPicker = false this.setCaret(e) - this.resize() this.$emit('update:modelValue', e.target.value) }, - onClickInput (e) { - this.showPicker = false - }, - onClickOutside (e) { - if (this.disableClickOutside) return - this.showPicker = false - }, onStickerUploaded (e) { - this.showPicker = false this.$emit('sticker-uploaded', e) }, onStickerUploadFailed (e) { - this.showPicker = false this.$emit('sticker-upload-Failed', e) }, setCaret ({ target: { selectionStart } }) { this.caret = selectionStart + this.$nextTick(() => { + this.$refs.suggestorPopover.updateStyles() + }) }, resize () { - const panel = this.$refs.panel - if (!panel) return - const picker = this.$refs.picker.$el - const panelBody = this.$refs['panel-body'] - const { offsetHeight, offsetTop } = this.input - const offsetBottom = offsetTop + offsetHeight - - this.setPlacement(panelBody, panel, offsetBottom) - this.setPlacement(picker, picker, offsetBottom) - }, - setPlacement (container, target, offsetBottom) { - if (!container || !target) return - - target.style.top = offsetBottom + 'px' - target.style.bottom = 'auto' - - if (this.placement === 'top' || (this.placement === 'auto' && this.overflowsBottom(container))) { - target.style.top = 'auto' - target.style.bottom = this.input.offsetHeight + 'px' - } - }, - overflowsBottom (el) { - return el.getBoundingClientRect().bottom > window.innerHeight } } } diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue @@ -1,11 +1,23 @@ <template> <div ref="root" - v-click-outside="onClickOutside" class="emoji-input" :class="{ 'with-picker': !hideEmojiButton }" > <slot /> + <!-- TODO: make the 'x' disappear if at the end maybe? --> + <div + ref="hiddenOverlay" + class="hidden-overlay" + :style="overlayStyle" + > + <span>{{ preText }}</span> + <span + ref="hiddenOverlayCaret" + class="caret" + >x</span> + <span>{{ postText }}</span> + </div> <template v-if="enableEmojiPicker"> <button v-if="!hideEmojiButton" @@ -18,66 +30,79 @@ <EmojiPicker v-if="enableEmojiPicker" ref="picker" - :class="{ hide: !showPicker }" :enable-sticker-picker="enableStickerPicker" class="emoji-picker-panel" @emoji="insert" @sticker-uploaded="onStickerUploaded" @sticker-upload-failed="onStickerUploadFailed" + @show="onPickerShown" + @close="onPickerClosed" /> </template> - <div - ref="panel" + <Popover + ref="suggestorPopover" class="autocomplete-panel" - :class="{ hide: !showSuggestions }" + placement="bottom" > - <div - ref="panel-body" - class="autocomplete-panel-body" - > + <template #content> <div - v-for="(suggestion, index) in suggestions" - :key="index" - class="autocomplete-item" - :class="{ highlighted: index === highlighted }" - @click.stop.prevent="onClick($event, suggestion)" + ref="panel-body" + class="autocomplete-panel-body" > - <span class="image"> - <img - v-if="suggestion.img" - :src="suggestion.img" - > - <span v-else>{{ suggestion.replacement }}</span> - </span> - <div class="label"> - <span class="displayText">{{ suggestion.displayText }}</span> - <span class="detailText">{{ suggestion.detailText }}</span> + <div + v-for="(suggestion, index) in suggestions" + :key="index" + class="autocomplete-item" + :class="{ highlighted: index === highlighted }" + @click.stop.prevent="onClick($event, suggestion)" + > + <span class="image"> + <img + v-if="suggestion.img" + :src="suggestion.img" + > + <span v-else>{{ suggestion.replacement }}</span> + </span> + <div class="label"> + <span + v-if="suggestion.user" + class="displayText" + > + {{ suggestion.displayText }}<UnicodeDomainIndicator + :user="suggestion.user" + :at="false" + /> + </span> + <span + v-if="!suggestion.user" + class="displayText" + > + {{ maybeLocalizedEmojiName(suggestion) }} + </span> + <span class="detailText">{{ suggestion.detailText }}</span> + </div> </div> </div> - </div> - </div> + </template> + </Popover> </div> </template> <script src="./emoji_input.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .emoji-input { display: flex; flex-direction: column; position: relative; - &.with-picker input { - padding-right: 30px; - } - .emoji-picker-icon { position: absolute; top: 0; right: 0; - margin: .2em .25em; + margin: 0.2em 0.25em; font-size: 1.3em; cursor: pointer; line-height: 24px; @@ -87,99 +112,102 @@ color: var(--text, $fallback--text); } } + .emoji-picker-panel { position: absolute; z-index: 20; margin-top: 2px; &.hide { - display: none + display: none; } } - .autocomplete { - &-panel { - position: absolute; - z-index: 20; - margin-top: 2px; + input, + textarea { + flex: 1 0 auto; + } - &.hide { - display: none - } + &.with-picker input { + padding-right: 30px; + } - &-body { - margin: 0 0.5em 0 0.5em; - border-radius: $fallback--tooltipRadius; - border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); - box-shadow: var(--popupShadow); - min-width: 75%; - background-color: $fallback--bg; - background-color: var(--popover, $fallback--bg); - color: $fallback--link; - color: var(--popoverText, $fallback--link); - --faint: var(--popoverFaintText, $fallback--faint); - --faintLink: var(--popoverFaintLink, $fallback--faint); - --lightText: var(--popoverLightText, $fallback--lightText); - --postLink: var(--popoverPostLink, $fallback--link); - --postFaintLink: var(--popoverPostFaintLink, $fallback--link); - --icon: var(--popoverIcon, $fallback--icon); - } + .hidden-overlay { + opacity: 0; + pointer-events: none; + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + overflow: hidden; + + /* DEBUG STUFF */ + color: red; + + /* set opacity to non-zero to see the overlay */ + + .caret { + width: 0; + margin-right: calc(-1ch - 1px); + border: 1px solid red; } + } +} - &-item { - display: flex; - cursor: pointer; - padding: 0.2em 0.4em; - border-bottom: 1px solid rgba(0, 0, 0, 0.4); +.autocomplete { + &-panel { + position: absolute; + } + + &-item { + display: flex; + cursor: pointer; + padding: 0.2em 0.4em; + border-bottom: 1px solid rgb(0 0 0 / 40%); + height: 32px; + + .image { + width: 32px; height: 32px; + line-height: 32px; + text-align: center; + font-size: 32px; + margin-right: 4px; - .image { + img { width: 32px; height: 32px; - line-height: 32px; - text-align: center; - font-size: 32px; - - margin-right: 4px; - - img { - width: 32px; - height: 32px; - object-fit: contain; - } + object-fit: contain; } + } - .label { - display: flex; - flex-direction: column; - justify-content: center; - margin: 0 0.1em 0 0.2em; - - .displayText { - line-height: 1.5; - } + .label { + display: flex; + flex-direction: column; + justify-content: center; + margin: 0 0.1em 0 0.2em; - .detailText { - font-size: 9px; - line-height: 9px; - } + .displayText { + line-height: 1.5; } - &.highlighted { - background-color: $fallback--fg; - background-color: var(--selectedMenuPopover, $fallback--fg); - color: var(--selectedMenuPopoverText, $fallback--text); - --faint: var(--selectedMenuPopoverFaintText, $fallback--faint); - --faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint); - --lightText: var(--selectedMenuPopoverLightText, $fallback--lightText); - --icon: var(--selectedMenuPopoverIcon, $fallback--icon); + .detailText { + font-size: 9px; + line-height: 9px; } } - } - input, textarea { - flex: 1 0 auto; + &.highlighted { + background-color: $fallback--fg; + background-color: var(--selectedMenuPopover, $fallback--fg); + color: var(--selectedMenuPopoverText, $fallback--text); + + --faint: var(--selectedMenuPopoverFaintText, $fallback--faint); + --faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint); + --lightText: var(--selectedMenuPopoverLightText, $fallback--lightText); + --icon: var(--selectedMenuPopoverIcon, $fallback--icon); + } } } </style> diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js @@ -2,7 +2,7 @@ * suggest - generates a suggestor function to be used by emoji-input * data: object providing source information for specific types of suggestions: * data.emoji - optional, an array of all emoji available i.e. - * (state.instance.emoji + state.instance.customEmoji) + * (getters.standardEmojiList + state.instance.customEmoji) * data.users - optional, an array of all known users * updateUsersList - optional, a function to search and append to users * @@ -13,10 +13,10 @@ export default data => { const emojiCurry = suggestEmoji(data.emoji) const usersCurry = data.store && suggestUsers(data.store) - return input => { + return (input, nameKeywordLocalizer) => { const firstChar = input[0] if (firstChar === ':' && data.emoji) { - return emojiCurry(input) + return emojiCurry(input, nameKeywordLocalizer) } if (firstChar === '@' && usersCurry) { return usersCurry(input) @@ -25,34 +25,34 @@ export default data => { } } -export const suggestEmoji = emojis => input => { +export const suggestEmoji = emojis => (input, nameKeywordLocalizer) => { const noPrefix = input.toLowerCase().substr(1) return emojis - .filter(({ displayText }) => displayText.toLowerCase().match(noPrefix)) - .sort((a, b) => { - let aScore = 0 - let bScore = 0 + .map(emoji => ({ ...emoji, ...nameKeywordLocalizer(emoji) })) + .filter((emoji) => (emoji.names.concat(emoji.keywords)).filter(kw => kw.toLowerCase().match(noPrefix)).length) + .map(k => { + let score = 0 // An exact match always wins - aScore += a.displayText.toLowerCase() === noPrefix ? 200 : 0 - bScore += b.displayText.toLowerCase() === noPrefix ? 200 : 0 + score += Math.max(...k.names.map(name => name.toLowerCase() === noPrefix ? 200 : 0), 0) // Prioritize custom emoji a lot - aScore += a.imageUrl ? 100 : 0 - bScore += b.imageUrl ? 100 : 0 + score += k.imageUrl ? 100 : 0 // Prioritize prefix matches somewhat - aScore += a.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0 - bScore += b.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0 + score += Math.max(...k.names.map(kw => kw.toLowerCase().startsWith(noPrefix) ? 10 : 0), 0) // Sort by length - aScore -= a.displayText.length - bScore -= b.displayText.length + score -= k.displayText.length + k.score = score + return k + }) + .sort((a, b) => { // Break ties alphabetically const alphabetically = a.displayText > b.displayText ? 0.5 : -0.5 - return bScore - aScore + alphabetically + return b.score - a.score + alphabetically }) } @@ -116,11 +116,12 @@ export const suggestUsers = ({ dispatch, state }) => { return diff + nameAlphabetically + screenNameAlphabetically /* eslint-disable camelcase */ - }).map(({ screen_name, screen_name_ui, name, profile_image_url_original }) => ({ - displayText: screen_name_ui, - detailText: name, - imageUrl: profile_image_url_original, - replacement: '@' + screen_name + ' ' + }).map((user) => ({ + user, + displayText: user.screen_name_ui, + detailText: user.name, + imageUrl: user.profile_image_url_original, + replacement: '@' + user.screen_name + ' ' })) /* eslint-enable camelcase */ diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js @@ -1,33 +1,76 @@ import { defineAsyncComponent } from 'vue' import Checkbox from '../checkbox/checkbox.vue' +import Popover from 'src/components/popover/popover.vue' +import StillImage from '../still-image/still-image.vue' +import { ensureFinalFallback } from '../../i18n/languages.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faBoxOpen, faStickyNote, - faSmileBeam + faSmileBeam, + faSmile, + faUser, + faPaw, + faIceCream, + faBus, + faBasketballBall, + faLightbulb, + faCode, + faFlag } from '@fortawesome/free-solid-svg-icons' -import { trim } from 'lodash' +import { debounce, trim, chunk } from 'lodash' library.add( faBoxOpen, faStickyNote, - faSmileBeam + faSmileBeam, + faSmile, + faUser, + faPaw, + faIceCream, + faBus, + faBasketballBall, + faLightbulb, + faCode, + faFlag ) -// At widest, approximately 20 emoji are visible in a row, -// loading 3 rows, could be overkill for narrow picker -const LOAD_EMOJI_BY = 60 +const UNICODE_EMOJI_GROUP_ICON = { + 'smileys-and-emotion': 'smile', + 'people-and-body': 'user', + 'animals-and-nature': 'paw', + 'food-and-drink': 'ice-cream', + 'travel-and-places': 'bus', + activities: 'basketball-ball', + objects: 'lightbulb', + symbols: 'code', + flags: 'flag' +} -// When to start loading new batch emoji, in pixels -const LOAD_EMOJI_MARGIN = 64 +const maybeLocalizedKeywords = (emoji, languages, nameLocalizer) => { + const res = [emoji.displayText, nameLocalizer(emoji)] + if (emoji.annotations) { + languages.forEach(lang => { + const keywords = emoji.annotations[lang]?.keywords || [] + const name = emoji.annotations[lang]?.name + res.push(...(keywords.concat([name]).filter(k => k))) + }) + } + return res +} -const filterByKeyword = (list, keyword = '') => { +const filterByKeyword = (list, keyword = '', languages, nameLocalizer) => { if (keyword === '') return list const keywordLowercase = keyword.toLowerCase() const orderedEmojiList = [] for (const emoji of list) { - const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase) + const indices = maybeLocalizedKeywords(emoji, languages, nameLocalizer) + .map(k => k.toLowerCase().indexOf(keywordLowercase)) + .filter(k => k > -1) + + const indexOfKeyword = indices.length ? Math.min(...indices) : -1 + if (indexOfKeyword > -1) { if (!Array.isArray(orderedEmojiList[indexOfKeyword])) { orderedEmojiList[indexOfKeyword] = [] @@ -38,6 +81,17 @@ const filterByKeyword = (list, keyword = '') => { return orderedEmojiList.flat() } +const getOffset = (elem) => { + const style = elem.style.transform + const res = /translateY\((\d+)px\)/.exec(style) + if (!res) { return 0 } + return res[1] +} + +const toHeaderId = id => { + return id.replace(/^row-\d+-/, '') +} + const EmojiPicker = { props: { enableStickerPicker: { @@ -53,16 +107,41 @@ const EmojiPicker = { showingStickers: false, groupsScrolledClass: 'scrolled-top', keepOpen: false, - customEmojiBufferSlice: LOAD_EMOJI_BY, customEmojiTimeout: null, - customEmojiLoadAllConfirmed: false + // Lazy-load only after the first time `showing` becomes true. + contentLoaded: false, + groupRefs: {}, + emojiRefs: {}, + filteredEmojiGroups: [], + width: 0 } }, components: { StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')), - Checkbox + Checkbox, + StillImage, + Popover }, methods: { + showPicker () { + this.$refs.popover.showPopover() + this.onShowing() + }, + hidePicker () { + this.$refs.popover.hidePopover() + }, + setAnchorEl (el) { + this.$refs.popover.setAnchorEl(el) + }, + setGroupRef (name) { + return el => { this.groupRefs[name] = el } + }, + onPopoverShown () { + this.$emit('show') + }, + onPopoverClosed () { + this.$emit('close') + }, onStickerUploaded (e) { this.$emit('sticker-uploaded', e) }, @@ -71,23 +150,53 @@ const EmojiPicker = { }, onEmoji (emoji) { const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement + if (!this.keepOpen) { + this.$refs.popover.hidePopover() + } this.$emit('emoji', { insertion: value, keepOpen: this.keepOpen }) }, - onScroll (e) { - const target = (e && e.target) || this.$refs['emoji-groups'] - this.updateScrolledClass(target) - this.scrolledGroup(target) - this.triggerLoadMore(target) + onScroll (startIndex, endIndex, visibleStartIndex, visibleEndIndex) { + const target = this.$refs['emoji-groups'].$el + this.scrolledGroup(target, visibleStartIndex, visibleEndIndex) }, - highlight (key) { - const ref = this.$refs['group-' + key] - const top = ref.offsetTop - this.setShowStickers(false) - this.activeGroup = key + scrolledGroup (target, start, end) { + const top = target.scrollTop + 5 this.$nextTick(() => { - this.$refs['emoji-groups'].scrollTop = top + 1 + this.emojiItems.slice(start, end + 1).forEach(group => { + const headerId = toHeaderId(group.id) + const ref = this.groupRefs['group-' + group.id] + if (!ref) { return } + const elem = ref.$el.parentElement + if (!elem) { return } + if (elem && getOffset(elem) <= top) { + this.activeGroup = headerId + } + }) + this.scrollHeader() }) }, + scrollHeader () { + // Scroll the active tab's header into view + const headerRef = this.groupRefs['group-header-' + this.activeGroup] + const left = headerRef.offsetLeft + const right = left + headerRef.offsetWidth + const headerCont = this.$refs.header + const currentScroll = headerCont.scrollLeft + const currentScrollRight = currentScroll + headerCont.clientWidth + const setScroll = s => { headerCont.scrollLeft = s } + + const margin = 7 // .emoji-tabs-item: padding + if (left - margin < currentScroll) { + setScroll(left - margin) + } else if (right + margin > currentScrollRight) { + setScroll(right + margin - headerCont.clientWidth) + } + }, + highlight (groupId) { + this.setShowStickers(false) + const indexInList = this.emojiItems.findIndex(k => k.id === groupId) + this.$refs['emoji-groups'].scrollToItem(indexInList) + }, updateScrolledClass (target) { if (target.scrollTop <= 5) { this.groupsScrolledClass = 'scrolled-top' @@ -97,74 +206,70 @@ const EmojiPicker = { this.groupsScrolledClass = 'scrolled-middle' } }, - triggerLoadMore (target) { - const ref = this.$refs['group-end-custom'] - if (!ref) return - const bottom = ref.offsetTop + ref.offsetHeight - - const scrollerBottom = target.scrollTop + target.clientHeight - const scrollerTop = target.scrollTop - const scrollerMax = target.scrollHeight - - // Loads more emoji when they come into view - const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN - // Always load when at the very top in case there's no scroll space yet - const atTop = scrollerTop < 5 - // Don't load when looking at unicode category or at the very bottom - const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax - if (!bottomAboveViewport && (approachingBottom || atTop)) { - this.loadEmoji() - } + toggleStickers () { + this.showingStickers = !this.showingStickers }, - scrolledGroup (target) { - const top = target.scrollTop + 5 - this.$nextTick(() => { - this.emojisView.forEach(group => { - const ref = this.$refs['group-' + group.id] - if (ref.offsetTop <= top) { - this.activeGroup = group.id - } - }) - }) + setShowStickers (value) { + this.showingStickers = value }, - loadEmoji () { - const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length - - if (allLoaded) { - return - } - - this.customEmojiBufferSlice += LOAD_EMOJI_BY + filterByKeyword (list, keyword) { + return filterByKeyword(list, keyword, this.languages, this.maybeLocalizedEmojiName) }, - startEmojiLoad (forceUpdate = false) { - if (!forceUpdate) { - this.keyword = '' - } + onShowing () { + const oldContentLoaded = this.contentLoaded + this.recalculateItemPerRow() this.$nextTick(() => { - this.$refs['emoji-groups'].scrollTop = 0 + this.$refs.search.focus() }) - const bufferSize = this.customEmojiBuffer.length - const bufferPrefilledAll = bufferSize === this.filteredEmoji.length - if (bufferPrefilledAll && !forceUpdate) { - return + this.contentLoaded = true + this.filteredEmojiGroups = this.getFilteredEmojiGroups() + if (!oldContentLoaded) { + this.$nextTick(() => { + if (this.defaultGroup) { + this.highlight(this.defaultGroup) + } + }) } - this.customEmojiBufferSlice = LOAD_EMOJI_BY }, - toggleStickers () { - this.showingStickers = !this.showingStickers + getFilteredEmojiGroups () { + return this.allEmojiGroups + .map(group => ({ + ...group, + emojis: this.filterByKeyword(group.emojis, trim(this.keyword)) + })) + .filter(group => group.emojis.length > 0) }, - setShowStickers (value) { - this.showingStickers = value + recalculateItemPerRow () { + this.$nextTick(() => { + if (!this.$refs['emoji-groups']) { + return + } + this.width = this.$refs['emoji-groups'].$el.clientWidth + }) } }, watch: { keyword () { - this.customEmojiLoadAllConfirmed = false this.onScroll() - this.startEmojiLoad(true) + this.debouncedHandleKeywordChange() + }, + allCustomGroups () { + this.filteredEmojiGroups = this.getFilteredEmojiGroups() } }, computed: { + minItemSize () { + return this.emojiHeight + }, + emojiHeight () { + return 32 + 4 + }, + emojiWidth () { + return 32 + 4 + }, + itemPerRow () { + return this.width ? Math.floor(this.width / this.emojiWidth - 1) : 6 + }, activeGroupView () { return this.showingStickers ? '' : this.activeGroup }, @@ -174,39 +279,69 @@ const EmojiPicker = { } return 0 }, - filteredEmoji () { - return filterByKeyword( - this.$store.state.instance.customEmoji || [], - trim(this.keyword) - ) + allCustomGroups () { + const emojis = this.$store.getters.groupedCustomEmojis + if (emojis.unpacked) { + emojis.unpacked.text = this.$t('emoji.unpacked') + } + return emojis }, - customEmojiBuffer () { - return this.filteredEmoji.slice(0, this.customEmojiBufferSlice) + defaultGroup () { + return Object.keys(this.allCustomGroups)[0] }, - emojis () { - const standardEmojis = this.$store.state.instance.emoji || [] - const customEmojis = this.customEmojiBuffer - - return [ - { - id: 'custom', - text: this.$t('emoji.custom'), - icon: 'smile-beam', - emojis: customEmojis - }, - { - id: 'standard', - text: this.$t('emoji.unicode'), - icon: 'box-open', - emojis: filterByKeyword(standardEmojis, trim(this.keyword)) - } - ] + unicodeEmojiGroups () { + return this.$store.getters.standardEmojiGroupList.map(group => ({ + id: `standard-${group.id}`, + text: this.$t(`emoji.unicode_groups.${group.id}`), + icon: UNICODE_EMOJI_GROUP_ICON[group.id], + emojis: group.emojis + })) }, - emojisView () { - return this.emojis.filter(value => value.emojis.length > 0) + allEmojiGroups () { + return Object.entries(this.allCustomGroups) + .map(([_, v]) => v) + .concat(this.unicodeEmojiGroups) }, stickerPickerEnabled () { return (this.$store.state.instance.stickers || []).length !== 0 + }, + debouncedHandleKeywordChange () { + return debounce(() => { + this.filteredEmojiGroups = this.getFilteredEmojiGroups() + }, 500) + }, + emojiItems () { + return this.filteredEmojiGroups.map(group => + chunk(group.emojis, this.itemPerRow) + .map((items, index) => ({ + ...group, + id: index === 0 ? group.id : `row-${index}-${group.id}`, + emojis: items, + isFirstRow: index === 0 + }))) + .reduce((a, c) => a.concat(c), []) + }, + languages () { + return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage) + }, + maybeLocalizedEmojiName () { + return emoji => { + if (!emoji.annotations) { + return emoji.displayText + } + + if (emoji.displayTextI18n) { + return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args) + } + + for (const lang of this.languages) { + if (emoji.annotations[lang]?.name) { + return emoji.annotations[lang].name + } + } + + return emoji.displayText + } } } } diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss @@ -1,24 +1,43 @@ -@import '../../_variables.scss'; +@import "../../variables"; + +$emoji-picker-header-height: 36px; +$emoji-picker-header-picture-width: 32px; +$emoji-picker-header-picture-height: 32px; +$emoji-picker-emoji-size: 32px; .emoji-picker { + width: 25em; + max-width: calc(100vw - 20px); // popover gives 10px margin from window edge display: flex; flex-direction: column; - position: absolute; - right: 0; - left: 0; - margin: 0 !important; - // TODO: actually use popover in emoji picker - z-index: var(--ZI_popovers); background-color: $fallback--bg; background-color: var(--popover, $fallback--bg); color: $fallback--link; color: var(--popoverText, $fallback--link); - --lightText: var(--popoverLightText, $fallback--faint); + --faint: var(--popoverFaintText, $fallback--faint); --faintLink: var(--popoverFaintLink, $fallback--faint); --lightText: var(--popoverLightText, $fallback--lightText); --icon: var(--popoverIcon, $fallback--icon); + &-header-image { + display: inline-flex; + justify-content: center; + align-items: center; + width: $emoji-picker-header-picture-width; + max-width: $emoji-picker-header-picture-width; + height: $emoji-picker-header-picture-height; + max-height: $emoji-picker-header-picture-height; + + .still-image { + max-width: 100%; + max-height: 100%; + height: 100%; + width: 100%; + object-fit: contain; + } + } + .keep-open, .too-many-emoji { padding: 7px; @@ -37,7 +56,6 @@ .heading { display: flex; - height: 32px; padding: 10px 7px 5px; } @@ -45,18 +63,18 @@ display: flex; flex-direction: column; flex: 1 1 auto; - min-height: 0px; + min-height: 0; } .emoji-tabs { flex-grow: 1; - } - - .emoji-groups { - min-height: 200px; + display: flex; + flex-flow: row nowrap; + overflow-x: auto; } .additional-tabs { + display: flex; border-left: 1px solid; border-left-color: $fallback--icon; border-left-color: var(--icon, $fallback--icon); @@ -66,15 +84,20 @@ .additional-tabs, .emoji-tabs { - display: block; - min-width: 0; flex-basis: auto; - flex-shrink: 1; + display: flex; + align-content: center; &-item { padding: 0 7px; cursor: pointer; font-size: 1.85em; + width: $emoji-picker-header-picture-width; + max-width: $emoji-picker-header-picture-width; + height: $emoji-picker-header-picture-height; + max-height: $emoji-picker-header-picture-height; + display: flex; + align-items: center; &.disabled { opacity: 0.5; @@ -93,7 +116,7 @@ } .sticker-picker { - flex: 1 1 auto + flex: 1 1 auto; } .stickers, @@ -123,22 +146,27 @@ } &-groups { + height: 100%; + min-height: 200px; flex: 1 1 1px; position: relative; overflow: auto; user-select: none; - mask: linear-gradient(to top, white 0, transparent 100%) bottom no-repeat, - linear-gradient(to bottom, white 0, transparent 100%) top no-repeat, - linear-gradient(to top, white, white); + mask: + linear-gradient(to top, white 0, transparent 100%) bottom no-repeat, + linear-gradient(to bottom, white 0, transparent 100%) top no-repeat, + linear-gradient(to top, white, white); transition: mask-size 150ms; mask-size: 100% 20px, 100% 20px, auto; // Autoprefixed seem to ignore this one, and also syntax is different - -webkit-mask-composite: xor; + mask-composite: xor; mask-composite: exclude; + &.scrolled { &-top { mask-size: 100% 20px, 100% 0, auto; } + &-bottom { mask-size: 100% 0, 100% 20px, auto; } @@ -164,24 +192,26 @@ } &-item { - width: 32px; - height: 32px; + width: $emoji-picker-emoji-size; + height: $emoji-picker-emoji-size; box-sizing: border-box; display: flex; - font-size: 32px; + line-height: $emoji-picker-emoji-size; align-items: center; justify-content: center; margin: 4px; - cursor: pointer; - img { + .emoji-picker-emoji.-custom { object-fit: contain; max-width: 100%; max-height: 100%; } - } + .emoji-picker-emoji.-unicode { + font-size: 24px; + overflow: hidden; + } + } } - } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue @@ -1,105 +1,148 @@ <template> - <div class="emoji-picker panel panel-default panel-body"> - <div class="heading"> - <span class="emoji-tabs"> + <Popover + ref="popover" + trigger="click" + popover-class="emoji-picker popover-default" + @show="onPopoverShown" + @close="onPopoverClosed" + > + <template #content> + <div class="heading"> <span - v-for="group in emojis" - :key="group.id" - class="emoji-tabs-item" - :class="{ - active: activeGroupView === group.id, - disabled: group.emojis.length === 0 - }" - :title="group.text" - @click.prevent="highlight(group.id)" + ref="header" + class="emoji-tabs" > - <FAIcon - :icon="group.icon" - fixed-width - /> + <span + v-for="group in filteredEmojiGroups" + :ref="setGroupRef('group-header-' + group.id)" + :key="group.id" + class="emoji-tabs-item" + :class="{ + active: activeGroupView === group.id + }" + :title="group.text" + @click.prevent="highlight(group.id)" + > + <span + v-if="group.image" + class="emoji-picker-header-image" + > + <still-image + :alt="group.text" + :src="group.image" + /> + </span> + <FAIcon + v-else + :icon="group.icon" + fixed-width + /> + </span> </span> - </span> - <span - v-if="stickerPickerEnabled" - class="additional-tabs" - > <span - class="stickers-tab-icon additional-tabs-item" - :class="{active: showingStickers}" - :title="$t('emoji.stickers')" - @click.prevent="toggleStickers" + v-if="stickerPickerEnabled" + class="additional-tabs" > - <FAIcon - icon="sticky-note" - fixed-width - /> + <span + class="stickers-tab-icon additional-tabs-item" + :class="{active: showingStickers}" + :title="$t('emoji.stickers')" + @click.prevent="toggleStickers" + > + <FAIcon + icon="sticky-note" + fixed-width + /> + </span> </span> - </span> - </div> - <div class="content"> + </div> <div - class="emoji-content" - :class="{hidden: showingStickers}" + v-if="contentLoaded" + class="content" > - <div class="emoji-search"> - <input - v-model="keyword" - type="text" - class="form-control" - :placeholder="$t('emoji.search_emoji')" - @input="$event.target.composing = false" - > - </div> <div - ref="emoji-groups" - class="emoji-groups" - :class="groupsScrolledClass" - @scroll="onScroll" + class="emoji-content" + :class="{hidden: showingStickers}" > - <div - v-for="group in emojisView" - :key="group.id" - class="emoji-group" - > - <h6 - :ref="'group-' + group.id" - class="emoji-group-title" - > - {{ group.text }} - </h6> - <span - v-for="emoji in group.emojis" - :key="group.id + emoji.displayText" - :title="emoji.displayText" - class="emoji-item" - @click.stop.prevent="onEmoji(emoji)" + <div class="emoji-search"> + <input + ref="search" + v-model="keyword" + type="text" + class="form-control" + :placeholder="$t('emoji.search_emoji')" + @input="$event.target.composing = false" > - <span v-if="!emoji.imageUrl">{{ emoji.replacement }}</span> - <img - v-else - :src="emoji.imageUrl" + </div> + <DynamicScroller + ref="emoji-groups" + class="emoji-groups" + :class="groupsScrolledClass" + :min-item-size="minItemSize" + :items="emojiItems" + :emit-update="true" + @update="onScroll" + @visible="recalculateItemPerRow" + @resize="recalculateItemPerRow" + > + <template #default="{ item: group, index, active }"> + <DynamicScrollerItem + :ref="setGroupRef('group-' + group.id)" + :item="group" + :active="active" + :data-index="index" + :size-dependencies="[group.emojis.length]" > - </span> - <span :ref="'group-end-' + group.id" /> + <div + class="emoji-group" + > + <h6 + v-if="group.isFirstRow" + class="emoji-group-title" + > + {{ group.text }} + </h6> + <span + v-for="emoji in group.emojis" + :key="group.id + emoji.displayText" + :title="maybeLocalizedEmojiName(emoji)" + class="emoji-item" + @click.stop.prevent="onEmoji(emoji)" + > + <span + v-if="!emoji.imageUrl" + class="emoji-picker-emoji -unicode" + >{{ emoji.replacement }}</span> + <still-image + v-else + class="emoji-picker-emoji -custom" + loading="lazy" + :src="emoji.imageUrl" + :data-emoji-name="group.id + emoji.displayText" + /> + </span> + </div> + </DynamicScrollerItem> + </template> + </DynamicScroller> + <div class="keep-open"> + <Checkbox v-model="keepOpen"> + {{ $t('emoji.keep_open') }} + </Checkbox> </div> </div> - <div class="keep-open"> - <Checkbox v-model="keepOpen"> - {{ $t('emoji.keep_open') }} - </Checkbox> + <div + v-if="showingStickers" + class="stickers-content" + > + <sticker-picker + @uploaded="onStickerUploaded" + @upload-failed="onStickerUploadFailed" + /> </div> </div> - <div - v-if="showingStickers" - class="stickers-content" - > - <sticker-picker - @uploaded="onStickerUploaded" - @upload-failed="onStickerUploadFailed" - /> - </div> - </div> - </div> + </template> + </Popover> </template> <script src="./emoji_picker.js"></script> diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue @@ -1,5 +1,5 @@ <template> - <div class="emoji-reactions"> + <div class="EmojiReactions"> <UserListPopover v-for="(reaction) in emojiReactions" :key="reaction.name" @@ -7,7 +7,7 @@ > <button class="emoji-reaction btn button-default" - :class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }" + :class="{ '-picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }" @click="emojiOnClick(reaction.name, $event)" @mouseenter="fetchEmojiReactionsByIfMissing()" > @@ -28,55 +28,58 @@ <script src="./emoji_reactions.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; -.emoji-reactions { +.EmojiReactions { display: flex; margin-top: 0.25em; flex-wrap: wrap; -} -.emoji-reaction { - padding: 0 0.5em; - margin-right: 0.5em; - margin-top: 0.5em; - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - .reaction-emoji { - width: 1.25em; - margin-right: 0.25em; - } - &:focus { - outline: none; - } + .emoji-reaction { + padding: 0 0.5em; + margin-right: 0.5em; + margin-top: 0.5em; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; - &.not-clickable { - cursor: default; - &:hover { - box-shadow: $fallback--buttonShadow; - box-shadow: var(--buttonShadow); + .reaction-emoji { + width: 1.25em; + margin-right: 0.25em; } - } -} -.emoji-reaction-expand { - padding: 0 0.5em; - margin-right: 0.5em; - margin-top: 0.5em; - display: flex; - align-items: center; - justify-content: center; - &:hover { - text-decoration: underline; + &:focus { + outline: none; + } + + &.not-clickable { + cursor: default; + + &:hover { + box-shadow: $fallback--buttonShadow; + box-shadow: var(--buttonShadow); + } + } + + &.-picked-reaction { + border: 1px solid var(--accent, $fallback--link); + margin-left: -1px; // offset the border, can't use inset shadows either + margin-right: calc(0.5em - 1px); + } } -} -.picked-reaction { - border: 1px solid var(--accent, $fallback--link); - margin-left: -1px; // offset the border, can't use inset shadows either - margin-right: calc(0.5em - 1px); -} + .emoji-reaction-expand { + padding: 0 0.5em; + margin-right: 0.5em; + margin-top: 0.5em; + display: flex; + align-items: center; + justify-content: center; + &:hover { + text-decoration: underline; + } + } +} </style> diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js @@ -6,7 +6,10 @@ import { faEyeSlash, faThumbtack, faShareAlt, - faExternalLinkAlt + faExternalLinkAlt, + faHistory, + faPlus, + faTimes } from '@fortawesome/free-solid-svg-icons' import { faBookmark as faBookmarkReg, @@ -21,13 +24,27 @@ library.add( faThumbtack, faShareAlt, faExternalLinkAlt, - faFlag + faFlag, + faHistory, + faPlus, + faTimes ) const ExtraButtons = { props: ['status'], components: { Popover }, + data () { + return { + expanded: false + } + }, methods: { + onShow () { + this.expanded = true + }, + onClose () { + this.expanded = false + }, deleteStatus () { const confirmed = window.confirm(this.$t('status.delete_confirm')) if (confirmed) { @@ -71,14 +88,32 @@ const ExtraButtons = { }, reportStatus () { this.$store.dispatch('openUserReportingModal', { userId: this.status.user.id, statusIds: [this.status.id] }) + }, + editStatus () { + this.$store.dispatch('fetchStatusSource', { id: this.status.id }) + .then(data => this.$store.dispatch('openEditStatusModal', { + statusId: this.status.id, + subject: data.spoiler_text, + statusText: data.text, + statusIsSensitive: this.status.nsfw, + statusPoll: this.status.poll, + statusFiles: [...this.status.attachments], + visibility: this.status.visibility, + statusContentType: data.content_type + })) + }, + showStatusHistory () { + const originalStatus = { ...this.status } + const stripFieldsList = ['attachments', 'created_at', 'emojis', 'text', 'raw_html', 'nsfw', 'poll', 'summary', 'summary_raw_html'] + stripFieldsList.forEach(p => delete originalStatus[p]) + this.$store.dispatch('openStatusHistoryModal', originalStatus) } }, computed: { currentUser () { return this.$store.state.users.currentUser }, canDelete () { if (!this.currentUser) { return } - const superuser = this.currentUser.rights.moderator || this.currentUser.rights.admin - return superuser || this.status.user.id === this.currentUser.id + return this.currentUser.privileges.includes('messages_delete') || this.status.user.id === this.currentUser.id }, ownStatus () { return this.status.user.id === this.currentUser.id @@ -94,7 +129,11 @@ const ExtraButtons = { }, statusLink () { return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}` - } + }, + isEdited () { + return this.status.edited_at !== null + }, + editingAvailable () { return this.$store.state.instance.editingAvailable } } } diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue @@ -6,6 +6,8 @@ :offset="{ y: 5 }" :bound-to="{ x: 'container' }" remove-padding + @show="onShow" + @close="onClose" > <template #content="{close}"> <div class="dropdown-menu"> @@ -76,6 +78,28 @@ </button> </template> <button + v-if="ownStatus && editingAvailable" + class="button-default dropdown-item dropdown-item-icon" + @click.prevent="editStatus" + @click="close" + > + <FAIcon + fixed-width + icon="pen" + /><span>{{ $t("status.edit") }}</span> + </button> + <button + v-if="isEdited && editingAvailable" + class="button-default dropdown-item dropdown-item-icon" + @click.prevent="showStatusHistory" + @click="close" + > + <FAIcon + fixed-width + icon="history" + /><span>{{ $t("status.status_history") }}</span> + </button> + <button v-if="canDelete" class="button-default dropdown-item dropdown-item-icon" @click.prevent="deleteStatus" @@ -122,10 +146,24 @@ </template> <template #trigger> <span class="button-unstyled popover-trigger"> - <FAIcon - class="fa-scale-110 fa-old-padding" - icon="ellipsis-h" - /> + <FALayers class="fa-old-padding-layer"> + <FAIcon + class="fa-scale-110 " + icon="ellipsis-h" + /> + <FAIcon + v-show="!expanded" + class="focus-marker" + transform="shrink-6 up-8 right-16" + icon="plus" + /> + <FAIcon + v-show="expanded" + class="focus-marker" + transform="shrink-6 up-8 right-16" + icon="times" + /> + </FALayers> </span> </template> </Popover> @@ -134,14 +172,10 @@ <script src="./extra_buttons.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; +@import "../../mixins"; .ExtraButtons { - /* override of popover internal stuff */ - .popover-trigger-button { - width: auto; - } - .popover-trigger { position: static; padding: 10px; @@ -152,5 +186,22 @@ color: var(--text, $fallback--text); } } + + .popover-trigger-button { + /* override of popover internal stuff */ + width: auto; + + @include unfocused-style { + .focus-marker { + visibility: hidden; + } + } + + @include focused-style { + .focus-marker { + visibility: visible; + } + } + } } </style> diff --git a/src/components/favorite_button/favorite_button.js b/src/components/favorite_button/favorite_button.js @@ -1,13 +1,21 @@ import { mapGetters } from 'vuex' import { library } from '@fortawesome/fontawesome-svg-core' -import { faStar } from '@fortawesome/free-solid-svg-icons' +import { + faStar, + faPlus, + faMinus, + faCheck +} from '@fortawesome/free-solid-svg-icons' import { faStar as faStarRegular } from '@fortawesome/free-regular-svg-icons' library.add( faStar, - faStarRegular + faStarRegular, + faPlus, + faMinus, + faCheck ) const FavoriteButton = { @@ -31,7 +39,10 @@ const FavoriteButton = { } }, computed: { - ...mapGetters(['mergedConfig']) + ...mapGetters(['mergedConfig']), + remoteInteractionLink () { + return this.$store.getters.remoteInteractionLink({ statusId: this.status.id }) + } } } diff --git a/src/components/favorite_button/favorite_button.vue b/src/components/favorite_button/favorite_button.vue @@ -7,19 +7,45 @@ :title="$t('tool_tip.favorite')" @click.prevent="favorite()" > - <FAIcon - class="fa-scale-110 fa-old-padding" - :icon="[status.favorited ? 'fas' : 'far', 'star']" - :spin="animated" - /> + <FALayers class="fa-scale-110 fa-old-padding-layer"> + <FAIcon + class="fa-scale-110" + :icon="[status.favorited ? 'fas' : 'far', 'star']" + :spin="animated" + /> + <FAIcon + v-if="status.favorited" + class="active-marker" + transform="shrink-6 up-9 right-12" + icon="check" + /> + <FAIcon + v-if="!status.favorited" + class="focus-marker" + transform="shrink-6 up-9 right-12" + icon="plus" + /> + <FAIcon + v-else + class="focus-marker" + transform="shrink-6 up-9 right-12" + icon="minus" + /> + </FALayers> </button> - <span v-else> + <a + v-else + class="button-unstyled interactive" + target="_blank" + role="button" + :href="remoteInteractionLink" + > <FAIcon class="fa-scale-110 fa-old-padding" :title="$t('tool_tip.favorite')" :icon="['far', 'star']" /> - </span> + </a> <span v-if="!mergedConfig.hidePostStats && status.fave_num > 0" class="action-counter" @@ -32,7 +58,8 @@ <script src="./favorite_button.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; +@import "../../mixins"; .FavoriteButton { display: flex; @@ -57,6 +84,26 @@ color: $fallback--cOrange; color: var(--cOrange, $fallback--cOrange); } + + @include unfocused-style { + .focus-marker { + visibility: hidden; + } + + .active-marker { + visibility: visible; + } + } + + @include focused-style { + .focus-marker { + visibility: visible; + } + + .active-marker { + visibility: hidden; + } + } } } </style> diff --git a/src/components/flash/flash.vue b/src/components/flash/flash.vue @@ -42,7 +42,8 @@ <script src="./flash.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; + .Flash { display: inline-block; width: 100%; @@ -78,7 +79,7 @@ .hidden { display: none; - visibility: 'hidden'; + visibility: "hidden"; } } </style> diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js @@ -1,6 +1,7 @@ import BasicUserCard from '../basic_user_card/basic_user_card.vue' import RemoteFollow from '../remote_follow/remote_follow.vue' import FollowButton from '../follow_button/follow_button.vue' +import RemoveFollowerButton from '../remove_follower_button/remove_follower_button.vue' const FollowCard = { props: [ @@ -10,7 +11,8 @@ const FollowCard = { components: { BasicUserCard, RemoteFollow, - FollowButton + FollowButton, + RemoveFollowerButton }, computed: { isMe () { diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue @@ -22,6 +22,11 @@ class="follow-card-follow-button" :user="user" /> + <RemoveFollowerButton + v-if="noFollowsYou && relationship.followed_by" + :relationship="relationship" + class="follow-card-button" + /> </template> </div> </basic-user-card> @@ -34,12 +39,17 @@ &-content-container { flex-shrink: 0; display: flex; - flex-direction: row; + flex-flow: row wrap; justify-content: space-between; - flex-wrap: wrap; line-height: 1.5em; } + &-button { + margin-top: 0.5em; + padding: 0 1.5em; + margin-left: 1em; + } + &-follow-button { margin-top: 0.5em; margin-left: auto; diff --git a/src/components/follow_request_card/follow_request_card.vue b/src/components/follow_request_card/follow_request_card.vue @@ -22,8 +22,8 @@ <style lang="scss"> .follow-request-card-content-container { display: flex; - flex-direction: row; - flex-wrap: wrap; + flex-flow: row wrap; + button { margin-top: 0.5em; margin-right: 0.5em; diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue @@ -50,17 +50,20 @@ <script src="./font_control.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; + .font-control { input.custom-font { min-width: 10em; } + &.custom { /* TODO Should make proper joiners... */ .font-switcher { border-top-right-radius: 0; border-bottom-right-radius: 0; } + .custom-font { border-top-left-radius: 0; border-bottom-left-radius: 0; diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js @@ -4,6 +4,7 @@ import { sumBy, set } from 'lodash' const Gallery = { props: [ 'attachments', + 'compact', 'limitRows', 'descriptions', 'limit', diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue @@ -20,6 +20,7 @@ v-for="(attachment, attachmentIndex) in row.items" :key="attachment.id" class="gallery-item" + :compact="compact" :nsfw="nsfw" :attachment="attachment" :size="size" @@ -86,7 +87,7 @@ <script src='./gallery.js'></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .Gallery { .gallery-rows { @@ -100,6 +101,53 @@ width: 100%; flex-grow: 1; + .gallery-row-inner { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + flex-flow: row wrap; + align-content: stretch; + + .gallery-item { + margin: 0 0.5em 0 0; + flex-grow: 1; + height: 100%; + box-sizing: border-box; + // to make failed images a bit more noticeable on chromium + min-width: 2em; + + &:last-child { + margin: 0; + } + } + + &.-grid { + width: 100%; + height: auto; + position: relative; + display: grid; + grid-gap: 0.5em; + grid-template-columns: repeat(auto-fill, minmax(15em, 1fr)); + + .gallery-item { + margin: 0; + height: 200px; + } + } + } + + &.-grid, + &.-minimal { + height: auto; + + .gallery-row-inner { + position: relative; + } + } + &:not(:first-child) { margin-top: 0.5em; } @@ -114,7 +162,7 @@ linear-gradient(to top, white, white); /* Autoprefixed seem to ignore this one, and also syntax is different */ - -webkit-mask-composite: xor; + mask-composite: xor; mask-composite: exclude; } } @@ -138,54 +186,5 @@ padding: 0 2em; } } - - .gallery-row { - &.-grid, - &.-minimal { - height: auto; - .gallery-row-inner { - position: relative; - } - } - } - - .gallery-row-inner { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-content: stretch; - - &.-grid { - width: 100%; - height: auto; - position: relative; - display: grid; - grid-column-gap: 0.5em; - grid-row-gap: 0.5em; - grid-template-columns: repeat(auto-fill, minmax(15em, 1fr)); - - .gallery-item { - margin: 0; - height: 200px; - } - } - } - - .gallery-item { - margin: 0 0.5em 0 0; - flex-grow: 1; - height: 100%; - box-sizing: border-box; - // to make failed images a bit more noticeable on chromium - min-width: 2em; - &:last-child { - margin: 0; - } - } } </style> diff --git a/src/components/global_notice_list/global_notice_list.vue b/src/components/global_notice_list/global_notice_list.vue @@ -25,14 +25,14 @@ <script src="./global_notice_list.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .global-notice-list { position: fixed; - top: 50px; + top: calc(var(--navbar-height) + 0.5em); width: 100%; pointer-events: none; - z-index: var(--ZI_popovers); + z-index: var(--ZI_navbar_popovers); display: flex; flex-direction: column; align-items: center; @@ -73,6 +73,7 @@ .global-success { background-color: var(--alertPopupSuccess, $fallback--cGreen); color: var(--alertPopupSuccessText, $fallback--text); + .svg-inline--fa { color: var(--alertPopupSuccessText, $fallback--text); } @@ -81,6 +82,7 @@ .global-info { background-color: var(--alertPopupNeutral, $fallback--fg); color: var(--alertPopupNeutralText, $fallback--text); + .svg-inline--fa { color: var(--alertPopupNeutralText, $fallback--text); } @@ -88,6 +90,7 @@ .close-notice { padding-right: 0.2em; + .svg-inline--fa:hover { opacity: 0.6; } diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js @@ -5,6 +5,8 @@ const tabModeDict = { mentions: ['mention'], 'likes+repeats': ['repeat', 'like'], follows: ['follow'], + reactions: ['pleroma:emoji_reaction'], + reports: ['pleroma:report'], moves: ['move'] } @@ -12,7 +14,8 @@ const Interactions = { data () { return { allowFollowingMove: this.$store.state.users.currentUser.allow_following_move, - filterMode: tabModeDict.mentions + filterMode: tabModeDict.mentions, + canSeeReports: this.$store.state.users.currentUser.privileges.includes('reports_manage_reports') } }, methods: { diff --git a/src/components/interactions/interactions.vue b/src/components/interactions/interactions.vue @@ -22,6 +22,15 @@ :label="$t('interactions.follows')" /> <span + key="reactions" + :label="$t('interactions.emoji_reactions')" + /> + <span + v-if="canSeeReports" + key="reports" + :label="$t('interactions.reports')" + /> + <span v-if="!allowFollowingMove" key="moves" :label="$t('interactions.moves')" diff --git a/src/components/link-preview/link-preview.vue b/src/components/link-preview/link-preview.vue @@ -33,7 +33,7 @@ <script src="./link-preview.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .link-preview-card { display: flex; @@ -46,6 +46,7 @@ flex-shrink: 0; width: 120px; max-width: 25%; + img { width: 100%; height: 100%; @@ -67,7 +68,7 @@ } .card-description { - margin: 0.5em 0 0 0; + margin: 0.5em 0 0; overflow: hidden; text-overflow: ellipsis; word-break: break-word; diff --git a/src/components/list/list.vue b/src/components/list/list.vue @@ -35,7 +35,7 @@ export default { </script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .list { &-item:not(:last-child) { diff --git a/src/components/lists/lists.js b/src/components/lists/lists.js @@ -0,0 +1,27 @@ +import ListsCard from '../lists_card/lists_card.vue' + +const Lists = { + data () { + return { + isNew: false + } + }, + components: { + ListsCard + }, + computed: { + lists () { + return this.$store.state.lists.allLists + } + }, + methods: { + cancelNewList () { + this.isNew = false + }, + newList () { + this.isNew = true + } + } +} + +export default Lists diff --git a/src/components/lists/lists.vue b/src/components/lists/lists.vue @@ -0,0 +1,33 @@ +<template> + <div class="Lists panel panel-default"> + <div class="panel-heading"> + <div class="title"> + {{ $t('lists.lists') }} + </div> + <router-link + :to="{ name: 'lists-new' }" + class="button-default btn new-list-button" + > + {{ $t("lists.new") }} + </router-link> + </div> + <div class="panel-body"> + <ListsCard + v-for="list in lists.slice().reverse()" + :key="list" + :list="list" + class="list-item" + /> + </div> + </div> +</template> + +<script src="./lists.js"></script> + +<style lang="scss"> +.Lists { + .new-list-button { + padding: 0 0.5em; + } +} +</style> diff --git a/src/components/lists_card/lists_card.js b/src/components/lists_card/lists_card.js @@ -0,0 +1,16 @@ +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faEllipsisH +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faEllipsisH +) + +const ListsCard = { + props: [ + 'list' + ] +} + +export default ListsCard diff --git a/src/components/lists_card/lists_card.vue b/src/components/lists_card/lists_card.vue @@ -0,0 +1,52 @@ +<template> + <div class="list-card"> + <router-link + :to="{ name: 'lists-timeline', params: { id: list.id } }" + class="list-name" + > + {{ list.title }} + </router-link> + <router-link + :to="{ name: 'lists-edit', params: { id: list.id } }" + class="button-list-edit" + > + <FAIcon + class="fa-scale-110 fa-old-padding" + icon="ellipsis-h" + /> + </router-link> + </div> +</template> + +<script src="./lists_card.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.list-card { + display: flex; +} + +.list-name { + flex-grow: 1; +} + +.list-name, +.button-list-edit { + margin: 0; + padding: 1em; + color: $fallback--link; + color: var(--link, $fallback--link); + + &:hover { + background-color: $fallback--lightBg; + background-color: var(--selectedMenu, $fallback--lightBg); + color: $fallback--link; + color: var(--selectedMenuText, $fallback--link); + + --faint: var(--selectedMenuFaintText, $fallback--faint); + --faintLink: var(--selectedMenuFaintLink, $fallback--faint); + --lightText: var(--selectedMenuLightText, $fallback--lightText); + } +} +</style> diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js @@ -0,0 +1,145 @@ +import { mapState, mapGetters } from 'vuex' +import BasicUserCard from '../basic_user_card/basic_user_card.vue' +import ListsUserSearch from '../lists_user_search/lists_user_search.vue' +import PanelLoading from 'src/components/panel_loading/panel_loading.vue' +import UserAvatar from '../user_avatar/user_avatar.vue' +import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faSearch, + faChevronLeft +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faSearch, + faChevronLeft +) + +const ListsNew = { + components: { + BasicUserCard, + UserAvatar, + ListsUserSearch, + TabSwitcher, + PanelLoading + }, + data () { + return { + title: '', + titleDraft: '', + membersUserIds: [], + removedUserIds: new Set([]), // users we added for members, to undo + searchUserIds: [], + addedUserIds: new Set([]), // users we added from search, to undo + searchLoading: false, + reallyDelete: false + } + }, + created () { + if (!this.id) return + this.$store.dispatch('fetchList', { listId: this.id }) + .then(() => { + this.title = this.findListTitle(this.id) + this.titleDraft = this.title + }) + this.$store.dispatch('fetchListAccounts', { listId: this.id }) + .then(() => { + this.membersUserIds = this.findListAccounts(this.id) + this.membersUserIds.forEach(userId => { + this.$store.dispatch('fetchUserIfMissing', userId) + }) + }) + }, + computed: { + id () { + return this.$route.params.id + }, + membersUsers () { + return [...this.membersUserIds, ...this.addedUserIds] + .map(userId => this.findUser(userId)).filter(user => user) + }, + searchUsers () { + return this.searchUserIds.map(userId => this.findUser(userId)).filter(user => user) + }, + ...mapState({ + currentUser: state => state.users.currentUser + }), + ...mapGetters(['findUser', 'findListTitle', 'findListAccounts']) + }, + methods: { + onInput () { + this.search(this.query) + }, + toggleRemoveMember (user) { + if (this.removedUserIds.has(user.id)) { + this.id && this.addUser(user) + this.removedUserIds.delete(user.id) + } else { + this.id && this.removeUser(user.id) + this.removedUserIds.add(user.id) + } + }, + toggleAddFromSearch (user) { + if (this.addedUserIds.has(user.id)) { + this.id && this.removeUser(user.id) + this.addedUserIds.delete(user.id) + } else { + this.id && this.addUser(user) + this.addedUserIds.add(user.id) + } + }, + isRemoved (user) { + return this.removedUserIds.has(user.id) + }, + isAdded (user) { + return this.addedUserIds.has(user.id) + }, + addUser (user) { + this.$store.dispatch('addListAccount', { accountId: user.id, listId: this.id }) + }, + removeUser (userId) { + this.$store.dispatch('removeListAccount', { accountId: userId, listId: this.id }) + }, + onSearchLoading (results) { + this.searchLoading = true + }, + onSearchLoadingDone (results) { + this.searchLoading = false + }, + onSearchResults (results) { + this.searchLoading = false + this.searchUserIds = results + }, + updateListTitle () { + this.$store.dispatch('setList', { listId: this.id, title: this.titleDraft }) + .then(() => { + this.title = this.findListTitle(this.id) + }) + }, + createList () { + this.$store.dispatch('createList', { title: this.titleDraft }) + .then((list) => { + return this + .$store + .dispatch('setListAccounts', { listId: list.id, accountIds: [...this.addedUserIds] }) + .then(() => list.id) + }) + .then((listId) => { + this.$router.push({ name: 'lists-timeline', params: { id: listId } }) + }) + .catch((e) => { + this.$store.dispatch('pushGlobalNotice', { + messageKey: 'lists.error', + messageArgs: [e.message], + level: 'error' + }) + }) + }, + deleteList () { + this.$store.dispatch('deleteList', { listId: this.id }) + this.$router.push({ name: 'lists' }) + } + } +} + +export default ListsNew diff --git a/src/components/lists_edit/lists_edit.vue b/src/components/lists_edit/lists_edit.vue @@ -0,0 +1,228 @@ +<template> + <div class="panel-default panel ListEdit"> + <div + ref="header" + class="panel-heading list-edit-heading" + > + <button + class="button-unstyled go-back-button" + @click="$router.back" + > + <FAIcon + size="lg" + icon="chevron-left" + /> + </button> + <div class="title"> + <i18n-t + v-if="id" + keypath="lists.editing_list" + > + <template #listTitle> + {{ title }} + </template> + </i18n-t> + <i18n-t + v-else + keypath="lists.creating_list" + /> + </div> + </div> + <div class="panel-body"> + <div class="input-wrap"> + <label for="list-edit-title">{{ $t('lists.title') }}</label> + {{ ' ' }} + <input + id="list-edit-title" + ref="title" + v-model="titleDraft" + > + <button + v-if="id" + class="btn button-default follow-button" + @click="updateListTitle" + > + {{ $t('lists.update_title') }} + </button> + </div> + <tab-switcher + class="list-member-management" + :scrollable-tabs="true" + > + <div + v-if="id || addedUserIds.size > 0" + :label="$t('lists.manage_members')" + class="members-list" + > + <div class="users-list"> + <div + v-for="user in membersUsers" + :key="user.id" + class="member" + > + <BasicUserCard + :user="user" + > + <button + class="btn button-default follow-button" + @click="toggleRemoveMember(user)" + > + {{ isRemoved(user) ? $t('general.undo') : $t('lists.remove_from_list') }} + </button> + </BasicUserCard> + </div> + </div> + </div> + + <div + class="search-list" + :label="$t('lists.add_members')" + > + <ListsUserSearch + @results="onSearchResults" + @loading="onSearchLoading" + @loadingDone="onSearchLoadingDone" + /> + <div + v-if="searchLoading" + class="loading" + > + <PanelLoading /> + </div> + <div + v-else + class="users-list" + > + <div + v-for="user in searchUsers" + :key="user.id" + class="member" + > + <BasicUserCard + :user="user" + > + <span + v-if="membersUserIds.includes(user.id)" + > + {{ $t('lists.is_in_list') }} + </span> + <button + v-if="!membersUserIds.includes(user.id)" + class="btn button-default follow-button" + @click="toggleAddFromSearch(user)" + > + {{ isAdded(user) ? $t('general.undo') : $t('lists.add_to_list') }} + </button> + <button + v-else + class="btn button-default follow-button" + @click="toggleRemoveMember(user)" + > + {{ isRemoved(user) ? $t('general.undo') : $t('lists.remove_from_list') }} + </button> + </BasicUserCard> + </div> + </div> + </div> + </tab-switcher> + </div> + <div class="panel-footer"> + <span class="spacer" /> + <button + v-if="!id" + class="btn button-default footer-button" + @click="createList" + > + {{ $t('lists.create') }} + </button> + <button + v-else-if="!reallyDelete" + class="btn button-default footer-button" + @click="reallyDelete = true" + > + {{ $t('lists.delete') }} + </button> + <template v-else> + {{ $t('lists.really_delete') }} + <button + class="btn button-default footer-button" + @click="deleteList" + > + {{ $t('general.yes') }} + </button> + <button + class="btn button-default footer-button" + @click="reallyDelete = false" + > + {{ $t('general.no') }} + </button> + </template> + </div> + </div> +</template> + +<script src="./lists_edit.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.ListEdit { + --panel-body-padding: 0.5em; + + height: calc(100vh - var(--navbar-height)); + overflow: hidden; + display: flex; + flex-direction: column; + + .list-edit-heading { + grid-template-columns: auto minmax(50%, 1fr); + } + + .panel-body { + display: flex; + flex: 1; + flex-direction: column; + overflow: hidden; + } + + .list-member-management { + flex: 1 0 auto; + } + + .search-icon { + margin-right: 0.3em; + } + + .users-list { + padding-bottom: 0.7rem; + overflow-y: auto; + } + + & .search-list, + & .members-list { + overflow: hidden; + flex-direction: column; + min-height: 0; + } + + .go-back-button { + text-align: center; + line-height: 1; + height: 100%; + align-self: start; + width: var(--__panel-heading-height-inner); + } + + .btn { + margin: 0 0.5em; + } + + .panel-footer { + grid-template-columns: minmax(10%, 1fr); + + .footer-button { + min-width: 9em; + } + } +} +</style> diff --git a/src/components/lists_menu/lists_menu_content.js b/src/components/lists_menu/lists_menu_content.js @@ -0,0 +1,22 @@ +import { mapState } from 'vuex' +import NavigationEntry from 'src/components/navigation/navigation_entry.vue' +import { getListEntries } from 'src/components/navigation/filter.js' + +export const ListsMenuContent = { + props: [ + 'showPin' + ], + components: { + NavigationEntry + }, + computed: { + ...mapState({ + lists: getListEntries, + currentUser: state => state.users.currentUser, + privateMode: state => state.instance.private, + federating: state => state.instance.federating + }) + } +} + +export default ListsMenuContent diff --git a/src/components/lists_menu/lists_menu_content.vue b/src/components/lists_menu/lists_menu_content.vue @@ -0,0 +1,12 @@ +<template> + <ul> + <NavigationEntry + v-for="item in lists" + :key="item.name" + :show-pin="showPin" + :item="item" + /> + </ul> +</template> + +<script src="./lists_menu_content.js"></script> diff --git a/src/components/lists_timeline/lists_timeline.js b/src/components/lists_timeline/lists_timeline.js @@ -0,0 +1,36 @@ +import Timeline from '../timeline/timeline.vue' +const ListsTimeline = { + data () { + return { + listId: null + } + }, + components: { + Timeline + }, + computed: { + timeline () { return this.$store.state.statuses.timelines.list } + }, + watch: { + $route: function (route) { + if (route.name === 'lists-timeline' && route.params.id !== this.listId) { + this.listId = route.params.id + this.$store.dispatch('stopFetchingTimeline', 'list') + this.$store.commit('clearTimeline', { timeline: 'list' }) + this.$store.dispatch('fetchList', { listId: this.listId }) + this.$store.dispatch('startFetchingTimeline', { timeline: 'list', listId: this.listId }) + } + } + }, + created () { + this.listId = this.$route.params.id + this.$store.dispatch('fetchList', { listId: this.listId }) + this.$store.dispatch('startFetchingTimeline', { timeline: 'list', listId: this.listId }) + }, + unmounted () { + this.$store.dispatch('stopFetchingTimeline', 'list') + this.$store.commit('clearTimeline', { timeline: 'list' }) + } +} + +export default ListsTimeline diff --git a/src/components/lists_timeline/lists_timeline.vue b/src/components/lists_timeline/lists_timeline.vue @@ -0,0 +1,10 @@ +<template> + <Timeline + title="list.name" + :timeline="timeline" + :list-id="listId" + timeline-name="list" + /> +</template> + +<script src="./lists_timeline.js"></script> diff --git a/src/components/lists_user_search/lists_user_search.js b/src/components/lists_user_search/lists_user_search.js @@ -0,0 +1,51 @@ +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faSearch, + faChevronLeft +} from '@fortawesome/free-solid-svg-icons' +import { debounce } from 'lodash' +import Checkbox from '../checkbox/checkbox.vue' + +library.add( + faSearch, + faChevronLeft +) + +const ListsUserSearch = { + components: { + Checkbox + }, + emits: ['loading', 'loadingDone', 'results'], + data () { + return { + loading: false, + query: '', + followingOnly: true + } + }, + methods: { + onInput: debounce(function () { + this.search(this.query) + }, 2000), + search (query) { + if (!query) { + this.loading = false + return + } + + this.loading = true + this.$emit('loading') + this.userIds = [] + this.$store.dispatch('search', { q: query, resolve: true, type: 'accounts', following: this.followingOnly }) + .then(data => { + this.$emit('results', data.accounts.map(a => a.id)) + }) + .finally(() => { + this.loading = false + this.$emit('loadingDone') + }) + } + } +} + +export default ListsUserSearch diff --git a/src/components/lists_user_search/lists_user_search.vue b/src/components/lists_user_search/lists_user_search.vue @@ -0,0 +1,47 @@ +<template> + <div class="ListsUserSearch"> + <div class="input-wrap"> + <div class="input-search"> + <FAIcon + class="search-icon fa-scale-110 fa-old-padding" + icon="search" + /> + </div> + <input + ref="search" + v-model="query" + :placeholder="$t('lists.search')" + @input="onInput" + > + </div> + <div class="input-wrap"> + <Checkbox + v-model="followingOnly" + @change="onInput" + > + {{ $t('lists.following_only') }} + </Checkbox> + </div> + </div> +</template> + +<script src="./lists_user_search.js"></script> +<style lang="scss"> +@import "../../variables"; + +.ListsUserSearch { + .input-wrap { + display: flex; + margin: 0.7em 0.5em; + + input { + width: 100%; + } + } + + .search-icon { + margin-right: 0.3em; + } +} + +</style> diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue @@ -93,7 +93,7 @@ <script src="./login_form.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .login-form { display: flex; @@ -110,7 +110,7 @@ } .login-bottom { - margin-top: 1.0em; + margin-top: 1em; display: flex; flex-direction: row; align-items: center; @@ -121,7 +121,7 @@ display: flex; flex-direction: column; padding: 0.3em 0.5em 0.6em; - line-height:24px; + line-height: 24px; } .form-bottom { @@ -142,7 +142,6 @@ .error { text-align: center; - animation-name: shakeError; animation-duration: 0.4s; animation-timing-function: ease-in-out; diff --git a/src/components/media_modal/media_modal.js b/src/components/media_modal/media_modal.js @@ -63,6 +63,11 @@ const MediaModal = { }, type () { return this.currentMedia ? this.getType(this.currentMedia) : null + }, + swipeDisableClickThreshold () { + // If there is only one media, allow more mouse movements to close the modal + // because there is less chance that the user wants to switch to another image + return () => this.canNavigate ? 1 : 30 } }, methods: { diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue @@ -10,6 +10,7 @@ class="modal-image-container" :direction="swipeDirection" :threshold="swipeThreshold" + :disable-click-threshold="swipeDisableClickThreshold" @preview-requested="handleSwipePreview" @swipe-finished="handleSwipeEnd" @swipeless-clicked="hide" @@ -120,32 +121,12 @@ $modal-view-button-icon-half-height: calc(#{$modal-view-button-icon-height} / 2) $modal-view-button-icon-width: 3em; $modal-view-button-icon-margin: 0.5em; -.modal-view.media-modal-view { - z-index: var(--ZI_media_modal); - flex-direction: column; - - .modal-view-button-arrow, - .modal-view-button-hide { - opacity: 0.75; - - &:focus, - &:hover { - outline: none; - box-shadow: none; - } - - &:hover { - opacity: 1; - } - } - overflow: hidden; -} - .media-modal-view { @keyframes media-fadein { from { opacity: 0; } + to { opacity: 1; } @@ -226,7 +207,7 @@ $modal-view-button-icon-margin: 0.5em; appearance: none; overflow: visible; cursor: pointer; - transition: opacity 333ms cubic-bezier(.4,0,.22,1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); height: $modal-view-button-icon-height; width: $modal-view-button-icon-width; @@ -236,9 +217,9 @@ $modal-view-button-icon-margin: 0.5em; width: $modal-view-button-icon-width; font-size: 1rem; line-height: $modal-view-button-icon-height; - color: #FFF; + color: #fff; text-align: center; - background-color: rgba(0,0,0,.3); + background-color: rgb(0 0 0 / 30%); } } @@ -254,13 +235,14 @@ $modal-view-button-icon-margin: 0.5em; position: absolute; top: 0; line-height: $modal-view-button-icon-height; - color: #FFF; + color: #fff; text-align: center; - background-color: rgba(0,0,0,.3); + background-color: rgb(0 0 0 / 30%); } &--prev { left: 0; + .arrow-icon { left: $modal-view-button-icon-margin; } @@ -268,6 +250,7 @@ $modal-view-button-icon-margin: 0.5em; &--next { right: 0; + .arrow-icon { right: $modal-view-button-icon-margin; } @@ -278,10 +261,33 @@ $modal-view-button-icon-margin: 0.5em; position: absolute; top: 0; right: 0; + .button-icon { top: $modal-view-button-icon-margin; right: $modal-view-button-icon-margin; } } } + +.modal-view.media-modal-view { + z-index: var(--ZI_media_modal); + flex-direction: column; + + .modal-view-button-arrow, + .modal-view-button-hide { + opacity: 0.75; + + &:focus, + &:hover { + outline: none; + box-shadow: none; + } + + &:hover { + opacity: 1; + } + } + + overflow: hidden; +} </style> diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue @@ -29,7 +29,7 @@ <script src="./media_upload.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .media-upload { cursor: pointer; // We use <label> for interactivity... i wonder if it's fine diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js @@ -2,6 +2,7 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p import { mapGetters, mapState } from 'vuex' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' import UserAvatar from '../user_avatar/user_avatar.vue' +import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import { defineAsyncComponent } from 'vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -16,6 +17,7 @@ const MentionLink = { name: 'MentionLink', components: { UserAvatar, + UnicodeDomainIndicator, UserPopover: defineAsyncComponent(() => import('../user_popover/user_popover.vue')) }, props: { diff --git a/src/components/mention_link/mention_link.scss b/src/components/mention_link/mention_link.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .MentionLink { position: relative; @@ -59,6 +59,7 @@ font-weight: 600; } } + &.-has-selection { color: var(--alertNeutralText, $fallback--text); background-color: var(--alertNeutral, $fallback--fg); @@ -100,10 +101,6 @@ } } - .full { - pointer-events: none; - } - .serverName.-faded { color: var(--faintLink, $fallback--link); } diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue @@ -47,6 +47,9 @@ class="serverName" :class="{ '-faded': shouldFadeDomain }" v-html="'@' + serverName" + /><UnicodeDomainIndicator + v-if="shouldShowFullUserName" + :user="user" /> </span> <span diff --git a/src/components/mentions_line/mentions_line.scss b/src/components/mentions_line/mentions_line.scss @@ -2,7 +2,7 @@ word-break: break-all; .mention-link:not(:first-child)::before { - content: ' '; + content: " "; } .showMoreLess { diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js @@ -2,33 +2,40 @@ import SideDrawer from '../side_drawer/side_drawer.vue' import Notifications from '../notifications/notifications.vue' import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils' import GestureService from '../../services/gesture_service/gesture_service' +import NavigationPins from 'src/components/navigation/navigation_pins.vue' import { mapGetters } from 'vuex' import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes, faBell, - faBars + faBars, + faArrowUp, + faMinus } from '@fortawesome/free-solid-svg-icons' library.add( faTimes, faBell, - faBars + faBars, + faArrowUp, + faMinus ) const MobileNav = { components: { SideDrawer, - Notifications + Notifications, + NavigationPins }, data: () => ({ notificationsCloseGesture: undefined, - notificationsOpen: false + notificationsOpen: false, + notificationsAtTop: true }), created () { this.notificationsCloseGesture = GestureService.swipeGesture( GestureService.DIRECTION_RIGHT, - this.closeMobileNotifications, + () => this.closeMobileNotifications(true), 50 ) }, @@ -47,7 +54,10 @@ const MobileNav = { isChat () { return this.$route.name === 'chat' }, - ...mapGetters(['unreadChatCount']) + ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']), + chatsPinned () { + return new Set(this.$store.state.serverSideStorage.prefsStorage.collections.pinnedNavItems).has('chats') + } }, methods: { toggleMobileSidebar () { @@ -56,12 +66,14 @@ const MobileNav = { openMobileNotifications () { this.notificationsOpen = true }, - closeMobileNotifications () { + closeMobileNotifications (markRead) { if (this.notificationsOpen) { // make sure to mark notifs seen only when the notifs were open and not // from close-calls. this.notificationsOpen = false - this.markNotificationsAsSeen() + if (markRead) { + this.markNotificationsAsSeen() + } } }, notificationsTouchStart (e) { @@ -73,6 +85,9 @@ const MobileNav = { scrollToTop () { window.scrollTo(0, 0) }, + scrollMobileNotificationsToTop () { + this.$refs.mobileNotifications.scrollTo(0, 0) + }, logout () { this.$router.replace('/main/public') this.$store.dispatch('logout') @@ -82,6 +97,7 @@ const MobileNav = { this.$store.dispatch('markNotificationsAsSeen') }, onScroll ({ target: { scrollTop, clientHeight, scrollHeight } }) { + this.notificationsAtTop = scrollTop > 0 if (scrollTop + clientHeight >= scrollHeight) { this.$refs.notifications.fetchOlderNotifications() } diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue @@ -10,6 +10,8 @@ <div class="item"> <button class="button-unstyled mobile-nav-button" + :title="$t('nav.mobile_sidebar')" + :aria-expanaded="$refs.sideDrawer && !$refs.sideDrawer.closed" @click.stop.prevent="toggleMobileSidebar()" > <FAIcon @@ -17,23 +19,16 @@ icon="bars" /> <div - v-if="unreadChatCount" + v-if="(unreadChatCount && !chatsPinned) || unreadAnnouncementCount" class="alert-dot" /> </button> - <router-link - v-if="!hideSitename" - class="site-name" - :to="{ name: 'root' }" - active-class="home" - > - {{ sitename }} - </router-link> - </div> - <div class="item right"> + <NavigationPins class="pins" /> + </div> <div class="item right"> <button v-if="currentUser" class="button-unstyled mobile-nav-button" + :title="unseenNotificationsCount ? $t('nav.mobile_notifications_unread_active') : $t('nav.mobile_notifications')" @click.stop.prevent="openMobileNotifications()" > <FAIcon @@ -47,7 +42,7 @@ </button> </div> </nav> - <div + <aside v-if="currentUser" class="mobile-notifications-drawer" :class="{ '-closed': !notificationsOpen }" @@ -56,22 +51,39 @@ > <div class="mobile-notifications-header"> <span class="title">{{ $t('notifications.notifications') }}</span> - <a - class="mobile-nav-button" - @click.stop.prevent="closeMobileNotifications()" + <span class="spacer" /> + <button + v-if="notificationsAtTop" + class="button-unstyled mobile-nav-button" + :title="$t('general.scroll_to_top')" + @click.stop.prevent="scrollMobileNotificationsToTop" + > + <FALayers class="fa-scale-110 fa-old-padding-layer"> + <FAIcon icon="arrow-up" /> + <FAIcon + icon="minus" + transform="up-7" + /> + </FALayers> + </button> + <button + class="button-unstyled mobile-nav-button" + :title="$t('nav.mobile_notifications_close')" + @click.stop.prevent="closeMobileNotifications(true)" > <FAIcon class="fa-scale-110 fa-old-padding" icon="times" /> - </a> + </button> </div> <div id="mobile-notifications" + ref="mobileNotifications" class="mobile-notifications" @scroll="onScroll" /> - </div> + </aside> <SideDrawer ref="sideDrawer" :logout="logout" @@ -82,7 +94,7 @@ <script src="./mobile_nav.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .MobileNav { z-index: var(--ZI_navbar); @@ -94,6 +106,7 @@ grid-template-columns: 2fr auto; width: 100%; box-sizing: border-box; + a { color: var(--topBarLink, $fallback--link); } @@ -114,7 +127,7 @@ } .site-name { - padding: 0 .3em; + padding: 0 0.3em; display: inline-block; } @@ -143,7 +156,7 @@ position: fixed; top: 0; left: 0; - box-shadow: 1px 1px 4px rgba(0,0,0,.6); + box-shadow: 1px 1px 4px rgb(0 0 0 / 60%); box-shadow: var(--panelShadow); transition-property: transform; transition-duration: 0.25s; @@ -169,22 +182,33 @@ color: var(--topBarText); background-color: $fallback--fg; background-color: var(--topBar, $fallback--fg); - box-shadow: 0px 0px 4px rgba(0,0,0,.6); + box-shadow: 0 0 4px rgb(0 0 0 / 60%); box-shadow: var(--topBarShadow); + .spacer { + flex: 1; + } + .title { font-size: 1.3em; margin-left: 0.6em; } } + .pins { + flex: 1; + + .pinned-item { + flex-grow: 1; + } + } + .mobile-notifications { margin-top: 50px; width: 100vw; height: calc(100vh - var(--navbar-height)); overflow-x: hidden; overflow-y: scroll; - color: $fallback--text; color: var(--text, $fallback--text); background-color: $fallback--bg; @@ -194,14 +218,17 @@ padding: 0; border-radius: 0; box-shadow: none; + .panel { border-radius: 0; margin: 0; box-shadow: none; } - .panel:after { + + .panel::after { border-radius: 0; } + .panel .panel-heading { border-radius: 0; box-shadow: none; diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.js b/src/components/mobile_post_status_button/mobile_post_status_button.js @@ -10,7 +10,8 @@ library.add( const HIDDEN_FOR_PAGES = new Set([ 'chats', - 'chat' + 'chat', + 'lists-edit' ]) const MobilePostStatusButton = { diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.vue b/src/components/mobile_post_status_button/mobile_post_status_button.vue @@ -3,6 +3,7 @@ v-if="isLoggedIn" class="MobilePostButton button-default new-status-button" :class="{ 'hidden': isHidden, 'always-show': isPersistent }" + :title="$t('post_status.new_status')" @click="openPostForm" > <FAIcon icon="pen" /> @@ -12,7 +13,7 @@ <script src="./mobile_post_status_button.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .MobilePostButton { &.button-default { @@ -29,9 +30,8 @@ display: flex; justify-content: center; align-items: center; - box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3), 0px 4px 6px rgba(0, 0, 0, 0.3); + box-shadow: 0 2px 2px rgb(0 0 0 / 30%), 0 4px 6px rgb(0 0 0 / 30%); z-index: 10; - transition: 0.35s transform; transition-timing-function: cubic-bezier(0, 1, 0.5, 1); } diff --git a/src/components/modal/modal.vue b/src/components/modal/modal.vue @@ -59,7 +59,7 @@ export default { &.modal-background { pointer-events: initial; - background-color: rgba(0, 0, 0, 0.5); + background-color: rgb(0 0 0 / 50%); } &.open { @@ -69,10 +69,11 @@ export default { @keyframes modal-background-fadein { from { - background-color: rgba(0, 0, 0, 0); + background-color: rgb(0 0 0 / 0%); } + to { - background-color: rgba(0, 0, 0, 0.5); + background-color: rgb(0 0 0 / 50%); } } </style> diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js @@ -41,14 +41,26 @@ const ModerationTools = { tagsSet () { return new Set(this.user.tags) }, - hasTagPolicy () { - return this.$store.state.instance.tagPolicyAvailable + canGrantRole () { + return this.user.is_local && !this.user.deactivated && this.$store.state.users.currentUser.role === 'admin' + }, + canChangeActivationState () { + return this.privileged('users_manage_activation_state') + }, + canDeleteAccount () { + return this.privileged('users_delete') + }, + canUseTagPolicy () { + return this.$store.state.instance.tagPolicyAvailable && this.privileged('users_manage_tags') } }, methods: { hasTag (tagName) { return this.tagsSet.has(tagName) }, + privileged (privilege) { + return this.$store.state.users.currentUser.privileges.includes(privilege) + }, toggleTag (tag) { const store = this.$store if (this.tagsSet.has(tag)) { diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue @@ -10,7 +10,7 @@ > <template #content> <div class="dropdown-menu"> - <span v-if="user.is_local"> + <span v-if="canGrantRole"> <button class="button-default dropdown-item" @click="toggleRight(&quot;admin&quot;)" @@ -24,28 +24,31 @@ {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }} </button> <div + v-if="canChangeActivationState || canDeleteAccount" role="separator" class="dropdown-divider" /> </span> <button + v-if="canChangeActivationState" class="button-default dropdown-item" @click="toggleActivationStatus()" > {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }} </button> <button + v-if="canDeleteAccount" class="button-default dropdown-item" @click="deleteUserDialog(true)" > {{ $t('user_card.admin_menu.delete_account') }} </button> <div - v-if="hasTagPolicy" + v-if="canUseTagPolicy" role="separator" class="dropdown-divider" /> - <span v-if="hasTagPolicy"> + <span v-if="canUseTagPolicy"> <button class="button-default dropdown-item" @click="toggleTag(tags.FORCE_NSFW)" @@ -163,18 +166,21 @@ <script src="./moderation_tools.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .moderation-tools-popover { height: 100%; + .trigger { + /* stylelint-disable-next-line declaration-no-important */ display: flex !important; height: 100%; } } .moderation-tools-button { - svg,i { + svg, + i { font-size: 0.8em; } } diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.scss b/src/components/mrf_transparency_panel/mrf_transparency_panel.scss @@ -2,19 +2,21 @@ margin: 1em; table { - width:100%; + width: 100%; text-align: left; - padding-left:10px; - padding-bottom:20px; + padding-left: 10px; + padding-bottom: 20px; - th, td { + th, + td { width: 180px; max-width: 360px; - overflow: hidden; + overflow: hidden; vertical-align: text-top; } - th+th, td+td { + th + th, + td + td { width: auto; } } diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.vue b/src/components/mrf_transparency_panel/mrf_transparency_panel.vue @@ -227,6 +227,6 @@ <script src="./mrf_transparency_panel.js"></script> <style lang="scss"> -@import '../../_variables.scss'; -@import './mrf_transparency_panel.scss'; +@import "../../variables"; +@import "./mrf_transparency_panel"; </style> diff --git a/src/components/mute_card/mute_card.vue b/src/components/mute_card/mute_card.vue @@ -37,6 +37,7 @@ .mute-card-content-container { margin-top: 0.5em; text-align: right; + button { width: 10em; } diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js @@ -1,5 +1,10 @@ -import TimelineMenuContent from '../timeline_menu/timeline_menu_content.vue' +import ListsMenuContent from 'src/components/lists_menu/lists_menu_content.vue' import { mapState, mapGetters } from 'vuex' +import { TIMELINES, ROOT_ITEMS } from 'src/components/navigation/navigation.js' +import { filterNavigation } from 'src/components/navigation/filter.js' +import NavigationEntry from 'src/components/navigation/navigation_entry.vue' +import NavigationPins from 'src/components/navigation/navigation_pins.vue' +import Checkbox from 'src/components/checkbox/checkbox.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -12,7 +17,9 @@ import { faComments, faBell, faInfoCircle, - faStream + faStream, + faList, + faBullhorn } from '@fortawesome/free-solid-svg-icons' library.add( @@ -25,26 +32,53 @@ library.add( faComments, faBell, faInfoCircle, - faStream + faStream, + faList, + faBullhorn ) - const NavPanel = { + props: ['forceExpand', 'forceEditMode'], created () { - if (this.currentUser && this.currentUser.locked) { - this.$store.dispatch('startFetchingFollowRequests') - } }, components: { - TimelineMenuContent + ListsMenuContent, + NavigationEntry, + NavigationPins, + Checkbox }, data () { return { - showTimelines: false + editMode: false, + showTimelines: false, + showLists: false, + timelinesList: Object.entries(TIMELINES).map(([k, v]) => ({ ...v, name: k })), + rootList: Object.entries(ROOT_ITEMS).map(([k, v]) => ({ ...v, name: k })) } }, methods: { toggleTimelines () { this.showTimelines = !this.showTimelines + }, + toggleLists () { + this.showLists = !this.showLists + }, + toggleEditMode () { + this.editMode = !this.editMode + }, + toggleCollapse () { + this.$store.commit('setPreference', { path: 'simple.collapseNav', value: !this.collapsed }) + this.$store.dispatch('pushServerSideStorage') + }, + isPinned (item) { + return this.pinnedItems.has(item) + }, + togglePin (item) { + if (this.isPinned(item)) { + this.$store.commit('removeCollectionPreference', { path: 'collections.pinnedNavItems', value: item }) + } else { + this.$store.commit('addCollectionPreference', { path: 'collections.pinnedNavItems', value: item }) + } + this.$store.dispatch('pushServerSideStorage') } }, computed: { @@ -53,9 +87,40 @@ const NavPanel = { followRequestCount: state => state.api.followRequests.length, privateMode: state => state.instance.private, federating: state => state.instance.federating, - pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable + pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable, + supportsAnnouncements: state => state.announcements.supportsAnnouncements, + pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems), + collapsed: state => state.serverSideStorage.prefsStorage.simple.collapseNav }), - ...mapGetters(['unreadChatCount']) + timelinesItems () { + return filterNavigation( + Object + .entries({ ...TIMELINES }) + .map(([k, v]) => ({ ...v, name: k })), + { + hasChats: this.pleromaChatMessagesAvailable, + hasAnnouncements: this.supportsAnnouncements, + isFederating: this.federating, + isPrivate: this.privateMode, + currentUser: this.currentUser + } + ) + }, + rootItems () { + return filterNavigation( + Object + .entries({ ...ROOT_ITEMS }) + .map(([k, v]) => ({ ...v, name: k })), + { + hasChats: this.pleromaChatMessagesAvailable, + hasAnnouncements: this.supportsAnnouncements, + isFederating: this.federating, + isPrivate: this.privateMode, + currentUser: this.currentUser + } + ) + }, + ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']) } } diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue @@ -1,90 +1,99 @@ <template> <div class="NavPanel"> <div class="panel panel-default"> - <ul> - <li v-if="currentUser || !privateMode"> - <button - class="button-unstyled menu-item" - @click="toggleTimelines" - > - <FAIcon - fixed-width - class="fa-scale-110" - icon="stream" - />{{ $t("nav.timelines") }} - <FAIcon - class="timelines-chevron" - fixed-width - :icon="showTimelines ? 'chevron-up' : 'chevron-down'" + <div + v-if="!forceExpand" + class="panel-heading nav-panel-heading" + > + <NavigationPins :limit="6" /> + <div class="spacer" /> + <button + class="button-unstyled" + @click="toggleCollapse" + > + <FAIcon + class="navigation-chevron" + fixed-width + :icon="collapsed ? 'chevron-down' : 'chevron-up'" + /> + </button> + </div> + <ul + v-if="!collapsed || forceExpand" + class="panel-body" + > + <NavigationEntry + v-if="currentUser || !privateMode" + :show-pin="false" + :item="{ icon: 'stream', label: 'nav.timelines' }" + :aria-expanded="showTimelines ? 'true' : 'false'" + @click="toggleTimelines" + > + <FAIcon + class="timelines-chevron" + fixed-width + :icon="showTimelines ? 'chevron-up' : 'chevron-down'" + /> + </NavigationEntry> + <div + v-show="showTimelines" + class="timelines-background" + > + <div class="timelines"> + <NavigationEntry + v-for="item in timelinesItems" + :key="item.name" + :show-pin="editMode || forceEditMode" + :item="item" /> - </button> - <div - v-show="showTimelines" - class="timelines-background" - > - <TimelineMenuContent class="timelines" /> </div> - </li> - <li v-if="currentUser"> - <router-link - class="menu-item" - :to="{ name: 'interactions', params: { username: currentUser.screen_name } }" - > - <FAIcon - fixed-width - class="fa-scale-110" - icon="bell" - />{{ $t("nav.interactions") }} - </router-link> - </li> - <li v-if="currentUser && pleromaChatMessagesAvailable"> + </div> + <NavigationEntry + v-if="currentUser" + :show-pin="false" + :item="{ icon: 'list', label: 'nav.lists' }" + :aria-expanded="showLists ? 'true' : 'false'" + @click="toggleLists" + > <router-link - class="menu-item" - :to="{ name: 'chats', params: { username: currentUser.screen_name } }" + :title="$t('lists.manage_lists')" + class="extra-button" + :to="{ name: 'lists' }" + @click.stop > - <div - v-if="unreadChatCount" - class="badge badge-notification" - > - {{ unreadChatCount }} - </div> <FAIcon + class="extra-button" fixed-width - class="fa-scale-110" - icon="comments" - />{{ $t("nav.chats") }} - </router-link> - </li> - <li v-if="currentUser && currentUser.locked"> - <router-link - class="menu-item" - :to="{ name: 'friend-requests' }" - > - <FAIcon - fixed-width - class="fa-scale-110" - icon="user-plus" - />{{ $t("nav.friend_requests") }} - <span - v-if="followRequestCount > 0" - class="badge badge-notification" - > - {{ followRequestCount }} - </span> - </router-link> - </li> - <li> - <router-link - class="menu-item" - :to="{ name: 'about' }" - > - <FAIcon - fixed-width - class="fa-scale-110" - icon="info-circle" - />{{ $t("nav.about") }} + icon="wrench" + /> </router-link> - </li> + <FAIcon + class="timelines-chevron" + fixed-width + :icon="showLists ? 'chevron-up' : 'chevron-down'" + /> + </NavigationEntry> + <div + v-show="showLists" + class="timelines-background" + > + <ListsMenuContent + :show-pin="editMode || forceEditMode" + class="timelines" + /> + </div> + <NavigationEntry + v-for="item in rootItems" + :key="item.name" + :show-pin="editMode || forceEditMode" + :item="item" + /> + <NavigationEntry + v-if="!forceEditMode && currentUser" + :show-pin="false" + :item="{ label: editMode ? $t('nav.edit_finish') : $t('nav.edit_pinned'), icon: editMode ? 'check' : 'wrench' }" + @click="toggleEditMode" + /> </ul> </div> </div> @@ -93,7 +102,7 @@ <script src="./nav_panel.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .NavPanel { .panel { @@ -112,7 +121,6 @@ border-bottom: 1px solid; border-color: $fallback--border; border-color: var(--border, $fallback--border); - padding: 0; } > li { @@ -135,42 +143,10 @@ border: none; } - .menu-item { - display: block; - box-sizing: border-box; - height: 3.5em; - line-height: 3.5em; - padding: 0 1em; - width: 100%; - color: $fallback--link; - color: var(--link, $fallback--link); - - &:hover { - background-color: $fallback--lightBg; - background-color: var(--selectedMenu, $fallback--lightBg); - color: $fallback--link; - color: var(--selectedMenuText, $fallback--link); - --faint: var(--selectedMenuFaintText, $fallback--faint); - --faintLink: var(--selectedMenuFaintLink, $fallback--faint); - --lightText: var(--selectedMenuLightText, $fallback--lightText); - --icon: var(--selectedMenuIcon, $fallback--icon); - } - - &.router-link-active { - font-weight: bolder; - background-color: $fallback--lightBg; - background-color: var(--selectedMenu, $fallback--lightBg); - color: $fallback--text; - color: var(--selectedMenuText, $fallback--text); - --faint: var(--selectedMenuFaintText, $fallback--faint); - --faintLink: var(--selectedMenuFaintLink, $fallback--faint); - --lightText: var(--selectedMenuLightText, $fallback--lightText); - --icon: var(--selectedMenuIcon, $fallback--icon); - - &:hover { - text-decoration: underline; - } - } + .navigation-chevron { + margin-left: 0.8em; + margin-right: 0.8em; + font-size: 1.1em; } .timelines-chevron { @@ -182,7 +158,7 @@ padding: 0 0 0 0.6em; background-color: $fallback--lightBg; background-color: var(--selectedMenu, $fallback--lightBg); - border-top: 1px solid; + border-bottom: 1px solid; border-color: $fallback--border; border-color: var(--border, $fallback--border); } @@ -192,14 +168,10 @@ background-color: var(--bg, $fallback--bg); } - .fa-scale-110 { - margin-right: 0.8em; - } - - .badge { - position: absolute; - right: 0.6rem; - top: 1.25em; + .nav-panel-heading { + // breaks without a unit + // stylelint-disable-next-line length-zero-no-unit + --panel-heading-height-padding: 0px; } } </style> diff --git a/src/components/navigation/filter.js b/src/components/navigation/filter.js @@ -0,0 +1,19 @@ +export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFederating, isPrivate, currentUser }) => { + return list.filter(({ criteria, anon, anonRoute }) => { + const set = new Set(criteria || []) + if (!isFederating && set.has('federating')) return false + if (!currentUser && isPrivate && set.has('!private')) return false + if (!currentUser && !(anon || anonRoute)) return false + if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) return false + if (!hasChats && set.has('chats')) return false + if (!hasAnnouncements && set.has('announcements')) return false + return true + }) +} + +export const getListEntries = state => state.lists.allLists.map(list => ({ + name: 'list-' + list.id, + routeObject: { name: 'lists-timeline', params: { id: list.id } }, + labelRaw: list.title, + iconLetter: list.title[0] +})) diff --git a/src/components/navigation/navigation.js b/src/components/navigation/navigation.js @@ -0,0 +1,82 @@ +export const USERNAME_ROUTES = new Set([ + 'bookmarks', + 'dms', + 'interactions', + 'notifications', + 'chat', + 'chats', + 'user-profile' +]) + +export const TIMELINES = { + home: { + route: 'friends', + icon: 'home', + label: 'nav.home_timeline', + criteria: ['!private'] + }, + public: { + route: 'public-timeline', + anon: true, + icon: 'users', + label: 'nav.public_tl', + criteria: ['!private'] + }, + twkn: { + route: 'public-external-timeline', + anon: true, + icon: 'globe', + label: 'nav.twkn', + criteria: ['!private', 'federating'] + }, + bookmarks: { + route: 'bookmarks', + icon: 'bookmark', + label: 'nav.bookmarks' + }, + favorites: { + routeObject: { name: 'user-profile', query: { tab: 'favorites' } }, + icon: 'star', + label: 'user_card.favorites' + }, + dms: { + route: 'dms', + icon: 'envelope', + label: 'nav.dms' + } +} + +export const ROOT_ITEMS = { + interactions: { + route: 'interactions', + icon: 'bell', + label: 'nav.interactions' + }, + chats: { + route: 'chats', + icon: 'comments', + label: 'nav.chats', + badgeGetter: 'unreadChatCount', + criteria: ['chats'] + }, + friendRequests: { + route: 'friend-requests', + icon: 'user-plus', + label: 'nav.friend_requests', + criteria: ['lockedUser'], + badgeGetter: 'followRequestCount' + }, + about: { + route: 'about', + anon: true, + icon: 'info-circle', + label: 'nav.about' + }, + announcements: { + route: 'announcements', + icon: 'bullhorn', + label: 'nav.announcements', + badgeGetter: 'unreadAnnouncementCount', + criteria: ['announcements'] + } +} diff --git a/src/components/navigation/navigation_entry.js b/src/components/navigation/navigation_entry.js @@ -0,0 +1,51 @@ +import { mapState } from 'vuex' +import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js' +import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue' +import { library } from '@fortawesome/fontawesome-svg-core' +import { faThumbtack } from '@fortawesome/free-solid-svg-icons' + +library.add(faThumbtack) + +const NavigationEntry = { + props: ['item', 'showPin'], + components: { + OptionalRouterLink + }, + methods: { + isPinned (value) { + return this.pinnedItems.has(value) + }, + togglePin (value) { + if (this.isPinned(value)) { + this.$store.commit('removeCollectionPreference', { path: 'collections.pinnedNavItems', value }) + } else { + this.$store.commit('addCollectionPreference', { path: 'collections.pinnedNavItems', value }) + } + this.$store.dispatch('pushServerSideStorage') + } + }, + computed: { + routeTo () { + if (!this.item.route && !this.item.routeObject) return null + let route + if (this.item.routeObject) { + route = this.item.routeObject + } else { + route = { name: (this.item.anon || this.currentUser) ? this.item.route : this.item.anonRoute } + } + if (USERNAME_ROUTES.has(route.name)) { + route.params = { username: this.currentUser.screen_name, name: this.currentUser.screen_name } + } + return route + }, + getters () { + return this.$store.getters + }, + ...mapState({ + currentUser: state => state.users.currentUser, + pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems) + }) + } +} + +export default NavigationEntry diff --git a/src/components/navigation/navigation_entry.vue b/src/components/navigation/navigation_entry.vue @@ -0,0 +1,135 @@ +<template> + <OptionalRouterLink + v-slot="{ isActive, href, navigate } = {}" + ass="ass" + :to="routeTo" + > + <li + class="NavigationEntry menu-item" + :class="{ '-active': isActive }" + v-bind="$attrs" + > + <component + :is="routeTo ? 'a' : 'button'" + class="main-link button-unstyled" + :href="href" + @click="navigate" + > + <span> + <FAIcon + v-if="item.icon" + fixed-width + class="fa-scale-110 menu-icon" + :icon="item.icon" + /> + </span> + <span + v-if="item.iconLetter" + class="icon iconLetter fa-scale-110 menu-icon" + >{{ item.iconLetter }} + </span> + <span class="label"> + {{ item.labelRaw || $t(item.label) }} + </span> + </component> + <slot /> + <div + v-if="item.badgeGetter && getters[item.badgeGetter]" + class="badge badge-notification" + > + {{ getters[item.badgeGetter] }} + </div> + <button + v-if="showPin && currentUser" + type="button" + class="button-unstyled extra-button" + :title="$t(isPinned ? 'general.unpin' : 'general.pin' )" + :aria-pressed="!!isPinned" + @click.stop.prevent="togglePin(item.name)" + > + <FAIcon + v-if="showPin && currentUser" + fixed-width + class="fa-scale-110" + :class="{ 'veryfaint': !isPinned(item.name) }" + :transform="!isPinned(item.name) ? 'rotate-45' : ''" + icon="thumbtack" + /> + </button> + </li> + </OptionalRouterLink> +</template> + +<script src="./navigation_entry.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.NavigationEntry { + display: flex; + box-sizing: border-box; + align-items: baseline; + height: 3.5em; + line-height: 3.5em; + padding: 0 1em; + width: 100%; + color: $fallback--link; + color: var(--link, $fallback--link); + + .timelines-chevron { + margin-right: 0; + } + + .main-link { + flex: 1; + } + + .menu-icon { + margin-right: 0.8em; + } + + .extra-button { + width: 3em; + text-align: center; + + &:last-child { + margin-right: -0.8em; + } + } + + &:hover { + background-color: $fallback--lightBg; + background-color: var(--selectedMenu, $fallback--lightBg); + color: $fallback--link; + color: var(--selectedMenuText, $fallback--link); + + --faint: var(--selectedMenuFaintText, $fallback--faint); + --faintLink: var(--selectedMenuFaintLink, $fallback--faint); + --lightText: var(--selectedMenuLightText, $fallback--lightText); + + .menu-icon { + --icon: var(--text, $fallback--icon); + } + } + + &.-active { + font-weight: bolder; + background-color: $fallback--lightBg; + background-color: var(--selectedMenu, $fallback--lightBg); + color: $fallback--text; + color: var(--selectedMenuText, $fallback--text); + + --faint: var(--selectedMenuFaintText, $fallback--faint); + --faintLink: var(--selectedMenuFaintLink, $fallback--faint); + --lightText: var(--selectedMenuLightText, $fallback--lightText); + + .menu-icon { + --icon: var(--text, $fallback--icon); + } + + &:hover { + text-decoration: underline; + } + } +} +</style> diff --git a/src/components/navigation/navigation_pins.js b/src/components/navigation/navigation_pins.js @@ -0,0 +1,94 @@ +import { mapState } from 'vuex' +import { TIMELINES, ROOT_ITEMS, USERNAME_ROUTES } from 'src/components/navigation/navigation.js' +import { getListEntries, filterNavigation } from 'src/components/navigation/filter.js' + +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faUsers, + faGlobe, + faBookmark, + faEnvelope, + faComments, + faBell, + faInfoCircle, + faStream, + faList +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faUsers, + faGlobe, + faBookmark, + faEnvelope, + faComments, + faBell, + faInfoCircle, + faStream, + faList +) + +const NavPanel = { + props: ['limit'], + methods: { + getRouteTo (item) { + if (item.routeObject) { + return item.routeObject + } + const route = { name: (item.anon || this.currentUser) ? item.route : item.anonRoute } + if (USERNAME_ROUTES.has(route.name)) { + route.params = { username: this.currentUser.screen_name } + } + return route + } + }, + computed: { + getters () { + return this.$store.getters + }, + ...mapState({ + lists: getListEntries, + currentUser: state => state.users.currentUser, + followRequestCount: state => state.api.followRequests.length, + privateMode: state => state.instance.private, + federating: state => state.instance.federating, + pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable, + pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems) + }), + pinnedList () { + if (!this.currentUser) { + return filterNavigation([ + { ...TIMELINES.public, name: 'public' }, + { ...TIMELINES.twkn, name: 'twkn' }, + { ...ROOT_ITEMS.about, name: 'about' } + ], + { + hasChats: this.pleromaChatMessagesAvailable, + isFederating: this.federating, + isPrivate: this.privateMode, + currentUser: this.currentUser + }) + } + return filterNavigation( + [ + ...Object + .entries({ ...TIMELINES }) + .filter(([k]) => this.pinnedItems.has(k)) + .map(([k, v]) => ({ ...v, name: k })), + ...this.lists.filter((k) => this.pinnedItems.has(k.name)), + ...Object + .entries({ ...ROOT_ITEMS }) + .filter(([k]) => this.pinnedItems.has(k)) + .map(([k, v]) => ({ ...v, name: k })) + ], + { + hasChats: this.pleromaChatMessagesAvailable, + isFederating: this.federating, + isPrivate: this.privateMode, + currentUser: this.currentUser + } + ).slice(0, this.limit) + } + } +} + +export default NavPanel diff --git a/src/components/navigation/navigation_pins.vue b/src/components/navigation/navigation_pins.vue @@ -0,0 +1,75 @@ +<template> + <span class="NavigationPins"> + <router-link + v-for="item in pinnedList" + :key="item.name" + class="pinned-item" + :to="getRouteTo(item)" + :title="item.labelRaw || $t(item.label)" + > + <FAIcon + v-if="item.icon" + fixed-width + :icon="item.icon" + /> + <span + v-if="item.iconLetter" + class="iconLetter fa-scale-110 fa-old-padding" + >{{ item.iconLetter }}</span> + <div + v-if="item.badgeGetter && getters[item.badgeGetter]" + class="alert-dot" + /> + </router-link> + </span> +</template> + +<script src="./navigation_pins.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.NavigationPins { + display: flex; + flex-wrap: wrap; + overflow: hidden; + height: 100%; + + .alert-dot { + border-radius: 100%; + height: 0.5em; + width: 0.5em; + position: absolute; + right: calc(50% - 0.75em); + top: calc(50% - 0.5em); + background-color: $fallback--cRed; + background-color: var(--badgeNotification, $fallback--cRed); + } + + .pinned-item { + position: relative; + flex: 1 0 3em; + min-width: 2em; + text-align: center; + overflow: visible; + box-sizing: border-box; + height: 100%; + + & .svg-inline--fa, + & .iconLetter { + margin: 0; + } + + &.router-link-active { + color: $fallback--text; + color: var(--panelText, $fallback--text); + border-bottom: 4px solid; + + & .svg-inline--fa, + & .iconLetter { + color: inherit; + } + } + } +} +</style> diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js @@ -4,6 +4,8 @@ import Status from '../status/status.vue' import UserAvatar from '../user_avatar/user_avatar.vue' import UserCard from '../user_card/user_card.vue' import Timeago from '../timeago/timeago.vue' +import Report from '../report/report.vue' +import UserLink from '../user_link/user_link.vue' import RichContent from 'src/components/rich_content/rich_content.jsx' import UserPopover from '../user_popover/user_popover.vue' import { isStatusNotification } from '../../services/notification_utils/notification_utils.js' @@ -18,7 +20,9 @@ import { faUserPlus, faEyeSlash, faUser, - faSuitcaseRolling + faSuitcaseRolling, + faExpandAlt, + faCompressAlt } from '@fortawesome/free-solid-svg-icons' library.add( @@ -29,13 +33,15 @@ library.add( faUserPlus, faUser, faEyeSlash, - faSuitcaseRolling + faSuitcaseRolling, + faExpandAlt, + faCompressAlt ) const Notification = { data () { return { - userExpanded: false, + statusExpanded: false, betterShadow: this.$store.state.interface.browserSupport.cssFilter, unmuted: false } @@ -47,12 +53,14 @@ const Notification = { UserCard, Timeago, Status, + Report, RichContent, - UserPopover + UserPopover, + UserLink }, methods: { - toggleUserExpanded () { - this.userExpanded = !this.userExpanded + toggleStatusExpanded () { + this.statusExpanded = !this.statusExpanded }, generateUserProfileLink (user) { return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames) diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss @@ -1,13 +1,14 @@ -@import '../../_variables.scss'; +@import "../../variables"; // TODO Copypaste from Status, should unify it somehow .Notification { - border-bottom: 1px solid; - border-color: $fallback--border; - border-color: var(--border, $fallback--border); - word-wrap: break-word; - word-break: break-word; - --emoji-size: 14px; + border-bottom: 1px solid; + border-color: $fallback--border; + border-color: var(--border, $fallback--border); + word-wrap: break-word; + word-break: break-word; + + --emoji-size: 14px; &:hover { --_still-image-img-visibility: visible; @@ -54,7 +55,7 @@ margin-left: 0.2em; &::before { - content: ' '; + content: " "; } } diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue @@ -1,19 +1,23 @@ <template> - <Status + <article v-if="notification.type === 'mention'" - class="Notification" - :compact="true" - :statusoid="notification.status" - /> - <div v-else> + > + <Status + class="Notification" + :compact="true" + :statusoid="notification.status" + /> + </article> + <article v-else> <div v-if="needMute && !unmuted" class="Notification container -muted" > <small> - <router-link :to="userProfileLink"> - {{ notification.from_profile.screen_name_ui }} - </router-link> + <user-link + :user="notification.from_profile" + :at="false" + /> </small> <button class="button-unstyled unmute" @@ -121,6 +125,9 @@ </i18n-t> </small> </span> + <span v-if="notification.type === 'pleroma:report'"> + <small>{{ $t('notifications.submitted_report') }}</small> + </span> <span v-if="notification.type === 'poll'"> <FAIcon class="type-icon" @@ -137,13 +144,25 @@ <router-link v-if="notification.status" :to="{ name: 'conversation', params: { id: notification.status.id } }" - class="faint-link" + class="timeago-link faint-link" > <Timeago :time="notification.created_at" :auto-update="240" /> </router-link> + <button + class="button-unstyled expand-icon" + @click.prevent="toggleStatusExpanded" + :title="$t('tool_tip.toggle_expand')" + :aria-expanded="statusExpanded" + > + <FAIcon + class="fa-scale-110" + fixed-width + :icon="statusExpanded ? 'compress-alt' : 'expand-alt'" + /> + </button> </div> <div v-else @@ -159,6 +178,8 @@ <button v-if="needMute" class="button-unstyled" + :title="$t('tool_tip.toggle_mute')" + :aria-expanded="!unmuted" @click.prevent="toggleMute" > <FAIcon @@ -171,12 +192,10 @@ v-if="notification.type === 'follow' || notification.type === 'follow_request'" class="follow-text" > - <router-link - :to="userProfileLink" + <user-link class="follow-name" - > - @{{ notification.from_profile.screen_name_ui }} - </router-link> + :user="notification.from_profile" + /> <div v-if="notification.type === 'follow_request'" style="white-space: nowrap;" @@ -207,20 +226,24 @@ v-else-if="notification.type === 'move'" class="move-text" > - <router-link :to="targetUserProfileLink"> - @{{ notification.target.screen_name_ui }} - </router-link> + <user-link + :user="notification.target" + /> </div> + <Report + v-else-if="notification.type === 'pleroma:report'" + :report-id="notification.report.id" + /> <template v-else> <StatusContent - class="faint" - :compact="true" + :class="{ faint: !statusExpanded }" + :compact="!statusExpanded" :status="notification.action" /> </template> </div> </div> - </div> + </article> </template> <script src="./notification.js"></script> diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue @@ -109,22 +109,3 @@ export default { } } </script> - -<style lang="scss"> - -.NotificationFilters { - align-self: stretch; - - > button { - line-height: 100%; - height: 100%; - width: var(--__panel-heading-height-inner); - text-align: center; - - svg { - font-size: 1.2em; - } - } -} - -</style> diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js @@ -10,10 +10,12 @@ import { } from '../../services/notification_utils/notification_utils.js' import FaviconService from '../../services/favicon_service/favicon_service.js' import { library } from '@fortawesome/fontawesome-svg-core' -import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' +import { faCircleNotch, faArrowUp, faMinus } from '@fortawesome/free-solid-svg-icons' library.add( - faCircleNotch + faCircleNotch, + faArrowUp, + faMinus ) const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 @@ -34,6 +36,7 @@ const Notifications = { }, data () { return { + showScrollTop: false, bottomedOut: false, // How many seen notifications to display in the list. The more there are, // the heavier the page becomes. This count is increased when loading @@ -66,7 +69,7 @@ const Notifications = { return this.unseenNotifications.length }, unseenCountTitle () { - return this.unseenCount + (this.unreadChatCount) + return this.unseenCount + (this.unreadChatCount) + this.unreadAnnouncementCount }, loading () { return this.$store.state.statuses.notifications.loading @@ -90,7 +93,22 @@ const Notifications = { notificationsToDisplay () { return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount) }, - ...mapGetters(['unreadChatCount']) + noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders }, + ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']) + }, + mounted () { + this.scrollerRef = this.$refs.root.closest('.column.-scrollable') + if (!this.scrollerRef) { + this.scrollerRef = this.$refs.root.closest('.mobile-notifications') + } + if (!this.scrollerRef) { + this.scrollerRef = this.$refs.root.closest('.column.main') + } + this.scrollerRef.addEventListener('scroll', this.updateScrollPosition) + }, + unmounted () { + if (!this.scrollerRef) return + this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition) }, watch: { unseenCountTitle (count) { @@ -101,9 +119,29 @@ const Notifications = { FaviconService.clearFaviconBadge() this.$store.dispatch('setPageTitle', '') } + }, + teleportTarget () { + // handle scroller change + this.$nextTick(() => { + this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition) + this.scrollerRef = this.$refs.root.closest('.column.-scrollable') + if (!this.scrollerRef) { + this.scrollerRef = this.$refs.root.closest('.mobile-notifications') + } + this.scrollerRef.addEventListener('scroll', this.updateScrollPosition) + this.updateScrollPosition() + }) } }, methods: { + scrollToTop () { + const scrollable = this.scrollerRef + scrollable.scrollTo({ top: this.$refs.root.offsetTop }) + // this.$refs.root.scrollIntoView({ behavior: 'smooth', block: 'start' }) + }, + updateScrollPosition () { + this.showScrollTop = this.$refs.root.offsetTop < this.scrollerRef.scrollTop + }, markAsSeen () { this.$store.dispatch('markNotificationsAsSeen') this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .Notifications { &:not(.minimal) { @@ -25,12 +25,13 @@ &.unseen { .notification-overlay { - background-image: linear-gradient(135deg, var(--badgeNotification, $fallback--cRed) 4px, transparent 10px) + background-image: linear-gradient(135deg, var(--badgeNotification, $fallback--cRed) 4px, transparent 10px); } } } } +/* stylelint-disable-next-line no-descending-specificity */ .notification { box-sizing: border-box; @@ -38,6 +39,7 @@ canvas { display: none; } + img { visibility: visible; } @@ -59,8 +61,10 @@ height: 32px; } - --link: var(--faintLink); - --text: var(--faint); + .faint { + --link: var(--faintLink); + --text: var(--faint); + } } .follow-request-accept { @@ -77,7 +81,8 @@ } } - .follow-text, .move-text { + .follow-text, + .move-text { padding: 0.5em 0; overflow-wrap: break-word; display: flex; @@ -110,6 +115,16 @@ min-width: 3em; text-align: right; } + + .timeago-link { + margin-right: 0.2em; + } + + .expand-icon { + .svg-inline--fa { + margin-left: 0.25em; + } + } } .emoji-reaction-emoji { diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue @@ -3,7 +3,9 @@ :disabled="minimalMode || disableTeleport" :to="teleportTarget" > - <div + <component + :is="noHeading ? 'div' : 'aside'" + ref="root" :class="{ minimal: minimalMode }" class="Notifications" > @@ -19,19 +21,43 @@ class="badge badge-notification unseen-count" >{{ unseenCount }}</span> </div> + <div + v-if="showScrollTop" + class="rightside-button" + > + <button + class="button-unstyled scroll-to-top-button" + type="button" + :title="$t('general.scroll_to_top')" + @click="scrollToTop" + > + <FALayers class="fa-scale-110 fa-old-padding-layer"> + <FAIcon icon="arrow-up" /> + <FAIcon + icon="minus" + transform="up-7" + /> + </FALayers> + </button> + </div> <button v-if="unseenCount" class="button-default read-button" + type="button" @click.prevent="markAsSeen" > {{ $t('notifications.read') }} </button> - <NotificationFilters /> + <NotificationFilters class="rightside-button" /> </div> - <div class="panel-body"> + <div + class="panel-body" + role="feed" + > <div v-for="notification in notificationsToDisplay" :key="notification.id" + role="listitem" class="notification" :class="{unseen: !minimalMode && !notification.seen}" > @@ -67,7 +93,7 @@ </div> </div> </div> - </div> + </component> </teleport> </template> diff --git a/src/components/optional_router_link/optional_router_link.vue b/src/components/optional_router_link/optional_router_link.vue @@ -0,0 +1,23 @@ +<template> + <!-- eslint-disable vue/no-multiple-template-root --> + <router-link + v-if="to" + v-slot="props" + :to="to" + custom + > + <slot + v-bind="props" + /> + </router-link> + <slot + v-else + v-bind="{}" + /> +</template> + +<script> +export default { + props: ['to'] +} +</script> diff --git a/src/components/panel_loading/panel_loading.vue b/src/components/panel_loading/panel_loading.vue @@ -23,7 +23,7 @@ export default {} </script> <style lang="scss"> -@import 'src/_variables.scss'; +@import "src/variables"; .panel-loading { display: flex; @@ -33,6 +33,7 @@ export default {} font-size: 2em; color: $fallback--text; color: var(--text, $fallback--text); + .loading-text svg { line-height: 0; vertical-align: middle; diff --git a/src/components/password_reset/password_reset.vue b/src/components/password_reset/password_reset.vue @@ -77,7 +77,7 @@ <script src="./password_reset.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .password-reset-form { display: flex; diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue @@ -90,7 +90,7 @@ <script src="./poll.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .poll { .votes { @@ -98,9 +98,11 @@ flex-direction: column; margin: 0 0 0.5em; } + .poll-option { margin: 0.75em 0.5em; } + .option-result { height: 100%; display: flex; @@ -109,6 +111,7 @@ color: $fallback--lightText; color: var(--lightText, $fallback--lightText); } + .option-result-label { display: flex; align-items: center; @@ -116,10 +119,12 @@ z-index: 1; word-break: break-word; } + .result-percentage { width: 3.5em; flex-shrink: 0; } + .result-fill { height: 100%; position: absolute; @@ -133,20 +138,25 @@ left: 0; transition: width 0.5s; } + .option-vote { display: flex; align-items: center; } + input { width: 3.5em; } + .footer { display: flex; align-items: center; } + &.loading * { cursor: progress; } + .poll-vote-button { padding: 0 0.5em; margin-right: 0.5em; diff --git a/src/components/poll/poll_form.vue b/src/components/poll/poll_form.vue @@ -95,7 +95,7 @@ <script src="./poll_form.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .poll-form { display: flex; @@ -117,6 +117,7 @@ .input-container { width: 100%; + input { // Hack: dodge the floating X icon padding-right: 2.5em; diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js @@ -4,7 +4,7 @@ const Popover = { // Action to trigger popover: either 'hover' or 'click' trigger: String, - // Either 'top' or 'bottom' + // 'top', 'bottom', 'left', 'right' placement: String, // Takes object with properties 'x' and 'y', values of these can be @@ -43,7 +43,12 @@ const Popover = { overlayCentersSelector: String, // Lets hover popover stay when clicking inside of it - stayOnClick: Boolean + stayOnClick: Boolean, + + triggerAttrs: { + type: Object, + default: {} + } }, inject: ['popoversZLayer'], // override popover z layer data () { @@ -51,6 +56,10 @@ const Popover = { // lockReEntry is a flag that is set when mouse cursor is leaving the popover's content // so that if mouse goes back into popover it won't be re-shown again to prevent annoyance // with popovers refusing to be hidden when user wants to interact with something in below popover + anchorEl: null, + // There's an issue where having teleport enabled by default causes things just... + // not render at all, i.e. main post status form and its emoji inputs + teleport: false, lockReEntry: false, hidden: true, styles: {}, @@ -59,10 +68,15 @@ const Popover = { // used to avoid blinking if hovered onto popover graceTimeout: null, parentPopover: null, + disableClickOutside: false, childrenShown: new Set() } }, methods: { + setAnchorEl (el) { + this.anchorEl = el + this.updateStyles() + }, containerBoundingClientRect () { const container = this.boundToSelector ? this.$el.closest(this.boundToSelector) : this.$el.offsetParent return container.getBoundingClientRect() @@ -75,7 +89,7 @@ const Popover = { // Popover will be anchored around this element, trigger ref is the container, so // its children are what are inside the slot. Expect only one v-slot:trigger. - const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el + const anchorEl = this.anchorEl || (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el // SVGs don't have offsetWidth/Height, use fallback const anchorHeight = anchorEl.offsetHeight || anchorEl.clientHeight const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth @@ -84,6 +98,8 @@ const Popover = { const anchorStyle = getComputedStyle(anchorEl) const topPadding = parseFloat(anchorStyle.paddingTop) const bottomPadding = parseFloat(anchorStyle.paddingBottom) + const rightPadding = parseFloat(anchorStyle.paddingRight) + const leftPadding = parseFloat(anchorStyle.paddingLeft) // Screen position of the origin point for popover = center of the anchor const origin = { @@ -170,7 +186,7 @@ const Popover = { if (overlayCenter) { translateX = origin.x + horizOffset translateY = origin.y + vertOffset - } else { + } else if (this.placement !== 'right' && this.placement !== 'left') { // Default to whatever user wished with placement prop let usingTop = this.placement !== 'bottom' @@ -189,6 +205,25 @@ const Popover = { const xOffset = (this.offset && this.offset.x) || 0 translateX = origin.x + horizOffset + xOffset + } else { + // Default to whatever user wished with placement prop + let usingRight = this.placement !== 'left' + + // Handle special cases, first force to displaying on top if there's not space on bottom, + // regardless of what placement value was. Then check if there's not space on top, and + // force to bottom, again regardless of what placement value was. + const rightBoundary = origin.x - anchorWidth * 0.5 + (this.removePadding ? rightPadding : 0) + const leftBoundary = origin.x + anchorWidth * 0.5 - (this.removePadding ? leftPadding : 0) + if (leftBoundary + content.offsetWidth > xBounds.max) usingRight = true + if (rightBoundary - content.offsetWidth < xBounds.min) usingRight = false + + const xOffset = (this.offset && this.offset.x) || 0 + translateX = usingRight + ? rightBoundary - xOffset - content.offsetWidth + : leftBoundary + xOffset + + const yOffset = (this.offset && this.offset.y) || 0 + translateY = origin.y + vertOffset + yOffset } this.styles = { @@ -205,6 +240,10 @@ const Popover = { }, showPopover () { if (this.disabled) return + this.disableClickOutside = true + setTimeout(() => { + this.disableClickOutside = false + }, 0) const wasHidden = this.hidden this.hidden = false this.parentPopover && this.parentPopover.onChildPopoverState(this, true) @@ -265,6 +304,7 @@ const Popover = { } }, onClickOutside (e) { + if (this.disableClickOutside) return if (this.hidden) return if (this.$refs.content && this.$refs.content.contains(e.target)) return if (this.$el.contains(e.target)) return @@ -298,6 +338,7 @@ const Popover = { } }, mounted () { + this.teleport = true let scrollable = this.$refs.trigger.closest('.column.-scrollable') || this.$refs.trigger.closest('.mobile-notifications') if (!scrollable) scrollable = window diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue @@ -7,11 +7,15 @@ ref="trigger" class="button-unstyled popover-trigger-button" type="button" + v-bind="triggerAttrs" @click="onClick" > <slot name="trigger" /> </button> - <teleport to="#popovers"> + <teleport + :disabled="!teleport" + to="#popovers" + > <transition name="fade"> <div v-if="!hidden" @@ -37,7 +41,7 @@ <script src="./popover.js" /> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .popover-trigger-button { display: inline-block; @@ -48,31 +52,31 @@ position: fixed; min-width: 0; max-width: calc(100vw - 20px); - box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); + box-shadow: 2px 2px 3px rgb(0 0 0 / 50%); box-shadow: var(--popupShadow); } .popover-default { - &:after { - content: ''; + &::after { + content: ""; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 3; - box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6); + box-shadow: 1px 1px 4px rgb(0 0 0 / 60%); box-shadow: var(--panelShadow); pointer-events: none; } border-radius: $fallback--btnRadius; border-radius: var(--btnRadius, $fallback--btnRadius); - background-color: $fallback--bg; background-color: var(--popover, $fallback--bg); color: $fallback--text; color: var(--popoverText, $fallback--text); + --faint: var(--popoverFaintText, $fallback--faint); --faintLink: var(--popoverFaintLink, $fallback--faint); --lightText: var(--popoverLightText, $fallback--lightText); @@ -83,7 +87,7 @@ .dropdown-menu { display: block; - padding: .5rem 0; + padding: 0.5rem 0; font-size: 1em; text-align: left; list-style: none; @@ -93,7 +97,7 @@ .dropdown-divider { height: 0; - margin: .5rem 0; + margin: 0.5rem 0; overflow: hidden; border-top: 1px solid $fallback--border; border-top: 1px solid var(--border, $fallback--border); @@ -109,7 +113,7 @@ text-align: inherit; white-space: nowrap; border: none; - border-radius: 0px; + border-radius: 0; background-color: transparent; box-shadow: none; width: 100%; @@ -122,21 +126,32 @@ svg { width: 22px; margin-right: 0.75rem; - color: var(--menuPopoverIcon, $fallback--icon) + color: var(--menuPopoverIcon, $fallback--icon); + } + } + + &.-has-submenu { + .chevron-icon { + margin-right: 0.25rem; + margin-left: 2rem; } } - &:active, &:hover { + &:active, + &:hover { background-color: $fallback--lightBg; background-color: var(--selectedMenuPopover, $fallback--lightBg); box-shadow: none; + --btnText: var(--selectedMenuPopoverText, $fallback--link); --faint: var(--selectedMenuPopoverFaintText, $fallback--faint); --faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint); --lightText: var(--selectedMenuPopoverLightText, $fallback--lightText); --icon: var(--selectedMenuPopoverIcon, $fallback--icon); + svg { color: var(--selectedMenuPopoverIcon, $fallback--icon); + --icon: var(--selectedMenuPopoverIcon, $fallback--icon); } } @@ -150,16 +165,16 @@ max-height: 22px; line-height: 22px; text-align: center; - border-radius: 0px; + border-radius: 0; background-color: $fallback--fg; background-color: var(--input, $fallback--fg); - box-shadow: 0px 0px 2px black inset; + box-shadow: 0 0 2px black inset; box-shadow: var(--inputShadow); margin-right: 0.75em; &.menu-checkbox-checked::after { font-size: 1.25em; - content: '✓'; + content: "✓"; } &.-radio { @@ -167,16 +182,15 @@ &.menu-checkbox-checked::after { font-size: 2em; - content: '•'; + content: "•"; } } } - } .button-default.dropdown-item { &, - i[class*=icon-] { + i[class*="icon-"] { color: $fallback--text; color: var(--btnText, $fallback--text); } diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js @@ -55,6 +55,14 @@ const pxStringToNumber = (str) => { const PostStatusForm = { props: [ + 'statusId', + 'statusText', + 'statusIsSensitive', + 'statusPoll', + 'statusFiles', + 'statusMediaDescriptions', + 'statusScope', + 'statusContentType', 'replyTo', 'repliedUser', 'attentions', @@ -62,6 +70,7 @@ const PostStatusForm = { 'subject', 'disableSubject', 'disableScopeSelector', + 'disableVisibilitySelector', 'disableNotice', 'disableLockWarning', 'disablePolls', @@ -125,22 +134,38 @@ const PostStatusForm = { const { postContentType: contentType, sensitiveByDefault } = this.$store.getters.mergedConfig + let statusParams = { + spoilerText: this.subject || '', + status: statusText, + nsfw: !!sensitiveByDefault, + files: [], + poll: {}, + mediaDescriptions: {}, + visibility: scope, + contentType + } + + if (this.statusId) { + const statusContentType = this.statusContentType || contentType + statusParams = { + spoilerText: this.subject || '', + status: this.statusText || '', + nsfw: this.statusIsSensitive || !!sensitiveByDefault, + files: this.statusFiles || [], + poll: this.statusPoll || {}, + mediaDescriptions: this.statusMediaDescriptions || {}, + visibility: this.statusScope || scope, + contentType: statusContentType + } + } + return { dropFiles: [], uploadingFiles: false, error: null, posting: false, highlighted: 0, - newStatus: { - spoilerText: this.subject || '', - status: statusText, - nsfw: !!sensitiveByDefault, - files: [], - poll: {}, - mediaDescriptions: {}, - visibility: scope, - contentType - }, + newStatus: statusParams, caret: 0, pollFormVisible: false, showDropIcon: 'hide', @@ -164,7 +189,7 @@ const PostStatusForm = { emojiUserSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ], store: this.$store @@ -173,13 +198,13 @@ const PostStatusForm = { emojiSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ] }) }, emoji () { - return this.$store.state.instance.emoji || [] + return this.$store.getters.standardEmojiList || [] }, customEmoji () { return this.$store.state.instance.customEmoji || [] @@ -236,6 +261,9 @@ const PostStatusForm = { uploadFileLimitReached () { return this.newStatus.files.length >= this.fileLimit }, + isEdit () { + return typeof this.statusId !== 'undefined' && this.statusId.trim() !== '' + }, ...mapGetters(['mergedConfig']), ...mapState({ mobileLayout: state => state.interface.mobileLayout @@ -473,7 +501,6 @@ const PostStatusForm = { if (target.value === '') { target.style.height = null this.$emit('resize') - this.$refs['emoji-input'].resize() return } @@ -560,8 +587,6 @@ const PostStatusForm = { } else { scrollerRef.scrollTop = targetScroll } - - this.$refs['emoji-input'].resize() }, showEmojiPicker () { this.$refs.textarea.focus() diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue @@ -67,6 +67,13 @@ <span v-else>{{ $t('post_status.direct_warning_to_all') }}</span> </p> <div + v-if="isEdit" + class="visibility-notice edit-warning" + > + <p>{{ $t('post_status.edit_remote_warning') }}</p> + <p>{{ $t('post_status.edit_unsupported_warning') }}</p> + </div> + <div v-if="!disablePreview" class="preview-heading faint" > @@ -170,6 +177,7 @@ class="visibility-tray" > <scope-selector + v-if="!disableVisibilitySelector" :show-all="showAllScopes" :user-default="userDefaultScope" :original-scope="copyMessageScope" @@ -323,7 +331,7 @@ <script src="./post_status_form.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .post-status-form { position: relative; @@ -370,7 +378,9 @@ &:hover { text-decoration: underline; } - svg, i { + + svg, + i { margin-left: 0.2em; font-size: 0.8em; transform: rotate(90deg); @@ -410,7 +420,35 @@ align-items: baseline; } - .media-upload-icon, .poll-icon, .emoji-icon { + .visibility-notice.edit-warning { + > :first-child { + margin-top: 0; + } + + > :last-child { + margin-bottom: 0; + } + } + + // Order is not necessary but a good indicator + .media-upload-icon { + order: 1; + justify-content: left; + } + + .emoji-icon { + order: 2; + justify-content: center; + } + + .poll-icon { + order: 3; + justify-content: right; + } + + .media-upload-icon, + .poll-icon, + .emoji-icon { font-size: 1.85em; line-height: 1.1; flex: 1; @@ -418,16 +456,20 @@ display: flex; align-items: center; - &.selected, &:hover { + &.selected, + &:hover { // needs to be specific to override icon default color - svg, i, label { + svg, + i, + label { color: $fallback--lightText; color: var(--lightText, $fallback--lightText); } } &.disabled { - svg, i { + svg, + i { cursor: not-allowed; color: $fallback--icon; color: var(--btnDisabledText, $fallback--icon); @@ -440,32 +482,17 @@ } } - // Order is not necessary but a good indicator - .media-upload-icon { - order: 1; - justify-content: left; - } - - .emoji-icon { - order: 2; - justify-content: center; - } - - .poll-icon { - order: 3; - justify-content: right; - } - .error { text-align: center; } .media-upload-wrapper { - margin-right: .2em; - margin-bottom: .5em; + margin-right: 0.2em; + margin-bottom: 0.5em; width: 18em; - img, video { + img, + video { object-fit: contain; max-height: 10em; } @@ -539,18 +566,14 @@ } } - .btn[disabled] { - cursor: not-allowed; - } - @keyframes fade-in { from { opacity: 0; } - to { opacity: 0.6; } + to { opacity: 0.6; } } @keyframes fade-out { from { opacity: 0.6; } - to { opacity: 0; } + to { opacity: 0; } } .drop-indicator { diff --git a/src/components/quick_filter_settings/quick_filter_settings.js b/src/components/quick_filter_settings/quick_filter_settings.js @@ -0,0 +1,70 @@ +import Popover from '../popover/popover.vue' +import { mapGetters } from 'vuex' +import { library } from '@fortawesome/fontawesome-svg-core' +import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons' + +library.add( + faFilter, + faFont, + faWrench +) + +const QuickFilterSettings = { + props: { + conversation: Boolean + }, + components: { + Popover + }, + methods: { + setReplyVisibility (visibility) { + this.$store.dispatch('setOption', { name: 'replyVisibility', value: visibility }) + this.$store.dispatch('queueFlushAll') + }, + openTab (tab) { + this.$store.dispatch('openSettingsModalTab', tab) + } + }, + computed: { + ...mapGetters(['mergedConfig']), + loggedIn () { + return !!this.$store.state.users.currentUser + }, + replyVisibilitySelf: { + get () { return this.mergedConfig.replyVisibility === 'self' }, + set () { this.setReplyVisibility('self') } + }, + replyVisibilityFollowing: { + get () { return this.mergedConfig.replyVisibility === 'following' }, + set () { this.setReplyVisibility('following') } + }, + replyVisibilityAll: { + get () { return this.mergedConfig.replyVisibility === 'all' }, + set () { this.setReplyVisibility('all') } + }, + hideMedia: { + get () { return this.mergedConfig.hideAttachments || this.mergedConfig.hideAttachmentsInConv }, + set () { + const value = !this.hideMedia + this.$store.dispatch('setOption', { name: 'hideAttachments', value }) + this.$store.dispatch('setOption', { name: 'hideAttachmentsInConv', value }) + } + }, + hideMutedPosts: { + get () { return this.mergedConfig.hideFilteredStatuses }, + set () { + const value = !this.hideMutedPosts + this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value }) + } + }, + muteBotStatuses: { + get () { return this.mergedConfig.muteBotStatuses }, + set () { + const value = !this.muteBotStatuses + this.$store.dispatch('setOption', { name: 'muteBotStatuses', value }) + } + } + } +} + +export default QuickFilterSettings diff --git a/src/components/quick_filter_settings/quick_filter_settings.vue b/src/components/quick_filter_settings/quick_filter_settings.vue @@ -0,0 +1,88 @@ +<template> + <Popover + trigger="click" + class="QuickFilterSettings" + :bound-to="{ x: 'container' }" + :trigger-attrs="{ title: $t('timeline.quick_filter_settings') }" + > + <template #content> + <div class="dropdown-menu"> + <div v-if="loggedIn"> + <button + v-if="!conversation" + class="button-default dropdown-item" + @click="replyVisibilityAll = true" + > + <span + class="menu-checkbox -radio" + :class="{ 'menu-checkbox-checked': replyVisibilityAll }" + />{{ $t('settings.reply_visibility_all') }} + </button> + <button + v-if="!conversation" + class="button-default dropdown-item" + @click="replyVisibilityFollowing = true" + > + <span + class="menu-checkbox -radio" + :class="{ 'menu-checkbox-checked': replyVisibilityFollowing }" + />{{ $t('settings.reply_visibility_following_short') }} + </button> + <button + v-if="!conversation" + class="button-default dropdown-item" + @click="replyVisibilitySelf = true" + > + <span + class="menu-checkbox -radio" + :class="{ 'menu-checkbox-checked': replyVisibilitySelf }" + />{{ $t('settings.reply_visibility_self_short') }} + </button> + <div + v-if="!conversation" + role="separator" + class="dropdown-divider" + /> + </div> + <button + class="button-default dropdown-item" + @click="muteBotStatuses = !muteBotStatuses" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': muteBotStatuses }" + />{{ $t('settings.mute_bot_posts') }} + </button> + <button + class="button-default dropdown-item" + @click="hideMedia = !hideMedia" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': hideMedia }" + />{{ $t('settings.hide_media_previews') }} + </button> + <button + class="button-default dropdown-item" + @click="hideMutedPosts = !hideMutedPosts" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': hideMutedPosts }" + />{{ $t('settings.hide_all_muted_posts') }} + </button> + <button + class="button-default dropdown-item dropdown-item-icon" + @click="openTab('filtering')" + > + <FAIcon icon="font" />{{ $t('settings.word_filter_and_more') }} + </button> + </div> + </template> + <template #trigger> + <FAIcon icon="filter" /> + </template> + </Popover> +</template> + +<script src="./quick_filter_settings.js"></script> diff --git a/src/components/quick_view_settings/quick_view_settings.js b/src/components/quick_view_settings/quick_view_settings.js @@ -0,0 +1,69 @@ +import Popover from '../popover/popover.vue' +import { mapGetters } from 'vuex' +import { library } from '@fortawesome/fontawesome-svg-core' +import { faList, faFolderTree, faBars, faWrench } from '@fortawesome/free-solid-svg-icons' + +library.add( + faList, + faFolderTree, + faBars, + faWrench +) + +const QuickViewSettings = { + props: { + conversation: Boolean + }, + components: { + Popover + }, + methods: { + setConversationDisplay (visibility) { + this.$store.dispatch('setOption', { name: 'conversationDisplay', value: visibility }) + }, + openTab (tab) { + this.$store.dispatch('openSettingsModalTab', tab) + } + }, + computed: { + ...mapGetters(['mergedConfig']), + loggedIn () { + return !!this.$store.state.users.currentUser + }, + conversationDisplay: { + get () { return this.mergedConfig.conversationDisplay }, + set (newVal) { this.setConversationDisplay(newVal) } + }, + autoUpdate: { + get () { return this.mergedConfig.streaming }, + set () { + const value = !this.autoUpdate + this.$store.dispatch('setOption', { name: 'streaming', value }) + } + }, + collapseWithSubjects: { + get () { return this.mergedConfig.collapseMessageWithSubject }, + set () { + const value = !this.collapseWithSubjects + this.$store.dispatch('setOption', { name: 'collapseMessageWithSubject', value }) + } + }, + showUserAvatars: { + get () { return this.mergedConfig.mentionLinkShowAvatar }, + set () { + const value = !this.showUserAvatars + console.log(value) + this.$store.dispatch('setOption', { name: 'mentionLinkShowAvatar', value }) + } + }, + muteBotStatuses: { + get () { return this.mergedConfig.muteBotStatuses }, + set () { + const value = !this.muteBotStatuses + this.$store.dispatch('setOption', { name: 'muteBotStatuses', value }) + } + } + } +} + +export default QuickViewSettings diff --git a/src/components/quick_view_settings/quick_view_settings.vue b/src/components/quick_view_settings/quick_view_settings.vue @@ -0,0 +1,75 @@ +<template> + <Popover + trigger="click" + class="QuickViewSettings" + :bound-to="{ x: 'container' }" + :trigger-attrs="{ title: $t('timeline.quick_view_settings') }" + > + <template #content> + <div class="dropdown-menu"> + <button + class="button-default dropdown-item" + @click="conversationDisplay = 'tree'" + > + <span + class="menu-checkbox -radio" + :class="{ 'menu-checkbox-checked': conversationDisplay === 'tree' }" + /><FAIcon icon="folder-tree" /> {{ $t('settings.conversation_display_tree_quick') }} + </button> + <button + class="button-default dropdown-item" + @click="conversationDisplay = 'linear'" + > + <span + class="menu-checkbox -radio" + :class="{ 'menu-checkbox-checked': conversationDisplay === 'linear' }" + /><FAIcon icon="list" /> {{ $t('settings.conversation_display_linear_quick') }} + </button> + <div + role="separator" + class="dropdown-divider" + /> + <button + class="button-default dropdown-item" + @click="showUserAvatars = !showUserAvatars" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': showUserAvatars }" + />{{ $t('settings.mention_link_show_avatar_quick') }} + </button> + <button + v-if="!conversation" + class="button-default dropdown-item" + @click="autoUpdate = !autoUpdate" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': autoUpdate }" + />{{ $t('settings.auto_update') }} + </button> + <button + v-if="!conversation" + class="button-default dropdown-item" + @click="collapseWithSubjects = !collapseWithSubjects" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': collapseWithSubjects }" + />{{ $t('settings.collapse_subject') }} + </button> + <button + class="button-default dropdown-item dropdown-item-icon" + @click="openTab('general')" + > + <FAIcon icon="wrench" />{{ $t('settings.more_settings') }} + </button> + </div> + </template> + <template #trigger> + <FAIcon icon="bars" /> + </template> + </Popover> +</template> + +<script src="./quick_view_settings.js"></script> diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js @@ -1,15 +1,22 @@ import Popover from '../popover/popover.vue' +import { ensureFinalFallback } from '../../i18n/languages.js' import { library } from '@fortawesome/fontawesome-svg-core' +import { faPlus, faTimes } from '@fortawesome/free-solid-svg-icons' import { faSmileBeam } from '@fortawesome/free-regular-svg-icons' import { trim } from 'lodash' -library.add(faSmileBeam) +library.add( + faPlus, + faTimes, + faSmileBeam +) const ReactButton = { props: ['status'], data () { return { - filterWord: '' + filterWord: '', + expanded: false } }, components: { @@ -25,41 +32,90 @@ const ReactButton = { } close() }, + onShow () { + this.expanded = true + this.focusInput() + }, + onClose () { + this.expanded = false + }, focusInput () { this.$nextTick(() => { - const input = this.$el.querySelector('input') + const input = document.querySelector('.reaction-picker-filter > input') if (input) input.focus() }) + }, + // Vaguely adjusted copypaste from emoji_input and emoji_picker! + maybeLocalizedEmojiNamesAndKeywords (emoji) { + const names = [emoji.displayText] + const keywords = [] + + if (emoji.displayTextI18n) { + names.push(this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)) + } + + if (emoji.annotations) { + this.languages.forEach(lang => { + names.push(emoji.annotations[lang]?.name) + + keywords.push(...(emoji.annotations[lang]?.keywords || [])) + }) + } + + return { + names: names.filter(k => k), + keywords: keywords.filter(k => k) + } + }, + maybeLocalizedEmojiName (emoji) { + if (!emoji.annotations) { + return emoji.displayText + } + + if (emoji.displayTextI18n) { + return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args) + } + + for (const lang of this.languages) { + if (emoji.annotations[lang]?.name) { + return emoji.annotations[lang].name + } + } + + return emoji.displayText } }, computed: { commonEmojis () { - return [ - { displayText: 'thumbsup', replacement: '👍' }, - { displayText: 'angry', replacement: '😠' }, - { displayText: 'eyes', replacement: '👀' }, - { displayText: 'joy', replacement: '😂' }, - { displayText: 'fire', replacement: '🔥' } - ] + const hardcodedSet = new Set(['👍', '😠', '👀', '😂', '🔥']) + return this.$store.getters.standardEmojiList.filter(emoji => hardcodedSet.has(emoji.replacement)) + }, + languages () { + return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage) }, emojis () { if (this.filterWord !== '') { - const filterWordLowercase = trim(this.filterWord.toLowerCase()) + const keywordLowercase = trim(this.filterWord.toLowerCase()) + const orderedEmojiList = [] - for (const emoji of this.$store.state.instance.emoji) { - if (emoji.replacement === this.filterWord) return [emoji] + for (const emoji of this.$store.getters.standardEmojiList) { + const indices = this.maybeLocalizedEmojiNamesAndKeywords(emoji) + .keywords + .map(k => k.toLowerCase().indexOf(keywordLowercase)) + .filter(k => k > -1) + + const indexOfKeyword = indices.length ? Math.min(...indices) : -1 - const indexOfFilterWord = emoji.displayText.toLowerCase().indexOf(filterWordLowercase) - if (indexOfFilterWord > -1) { - if (!Array.isArray(orderedEmojiList[indexOfFilterWord])) { - orderedEmojiList[indexOfFilterWord] = [] + if (indexOfKeyword > -1) { + if (!Array.isArray(orderedEmojiList[indexOfKeyword])) { + orderedEmojiList[indexOfKeyword] = [] } - orderedEmojiList[indexOfFilterWord].push(emoji) + orderedEmojiList[indexOfKeyword].push(emoji) } } return orderedEmojiList.flat() } - return this.$store.state.instance.emoji || [] + return this.$store.getters.standardEmojiList || [] }, mergedConfig () { return this.$store.getters.mergedConfig diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue @@ -7,7 +7,8 @@ :bound-to="{ x: 'container' }" remove-padding popover-class="ReactButton popover-default" - @show="focusInput" + @show="onShow" + @close="onClose" > <template #content="{close}"> <div class="reaction-picker-filter"> @@ -23,7 +24,7 @@ v-for="emoji in commonEmojis" :key="emoji.replacement" class="emoji-button" - :title="emoji.displayText" + :title="maybeLocalizedEmojiName(emoji)" @click="addReaction($event, emoji.replacement, close)" > {{ emoji.replacement }} @@ -33,7 +34,7 @@ v-for="(emoji, key) in emojis" :key="key" class="emoji-button" - :title="emoji.displayText" + :title="maybeLocalizedEmojiName(emoji)" @click="addReaction($event, emoji.replacement, close)" > {{ emoji.replacement }} @@ -46,10 +47,24 @@ class="button-unstyled popover-trigger" :title="$t('tool_tip.add_reaction')" > - <FAIcon - class="fa-scale-110 fa-old-padding" - :icon="['far', 'smile-beam']" - /> + <FALayers> + <FAIcon + class="fa-scale-110 fa-old-padding" + :icon="['far', 'smile-beam']" + /> + <FAIcon + v-show="!expanded" + class="focus-marker" + transform="shrink-6 up-9 right-17" + icon="plus" + /> + <FAIcon + v-show="expanded" + class="focus-marker" + transform="shrink-6 up-9 right-17" + icon="times" + /> + </FALayers> </span> </template> </Popover> @@ -58,7 +73,8 @@ <script src="./react_button.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; +@import "../../mixins"; .ReactButton { .reaction-picker-filter { @@ -88,20 +104,19 @@ text-align: center; align-content: flex-start; user-select: none; - - mask: linear-gradient(to top, white 0, transparent 100%) bottom no-repeat, - linear-gradient(to bottom, white 0, transparent 100%) top no-repeat, - linear-gradient(to top, white, white); + mask: + linear-gradient(to top, white 0, transparent 100%) bottom no-repeat, + linear-gradient(to bottom, white 0, transparent 100%) top no-repeat, + linear-gradient(to top, white, white); transition: mask-size 150ms; mask-size: 100% 20px, 100% 20px, auto; /* Autoprefixed seem to ignore this one, and also syntax is different */ - -webkit-mask-composite: xor; + mask-composite: xor; mask-composite: exclude; .emoji-button { cursor: pointer; - flex-basis: 20%; line-height: 1.5; align-content: center; @@ -112,11 +127,6 @@ } } - /* override of popover internal stuff */ - .popover-trigger-button { - width: auto; - } - .popover-trigger { padding: 10px; margin: -10px; @@ -126,6 +136,23 @@ color: var(--text, $fallback--text); } } + + .popover-trigger-button { + /* override of popover internal stuff */ + width: auto; + + @include unfocused-style { + .focus-marker { + visibility: hidden; + } + } + + @include focused-style { + .focus-marker { + visibility: visible; + } + } + } } </style> diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue @@ -158,10 +158,10 @@ class="form-error" > <ul> - <li v-if="!v$.user.confirm.required"> + <li v-if="v$.user.confirm.required.$invalid"> <span>{{ $t('registration.validations.password_confirmation_required') }}</span> </li> - <li v-if="!v$.user.confirm.sameAsPassword"> + <li v-if="v$.user.confirm.sameAs.$invalid"> <span>{{ $t('registration.validations.password_confirmation_match') }}</span> </li> </ul> @@ -277,7 +277,7 @@ <script src="./registration.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; $validations-cRed: #f04124; .registration-form { @@ -321,7 +321,7 @@ $validations-cRed: #f04124; .form-group--error { animation-name: shakeError; - animation-duration: .6s; + animation-duration: 0.6s; animation-timing-function: ease-in-out; } @@ -350,7 +350,7 @@ $validations-cRed: #f04124; } form textarea { - line-height:16px; + line-height: 16px; resize: vertical; } diff --git a/src/components/remote_user_resolver/remote_user_resolver.vue b/src/components/remote_user_resolver/remote_user_resolver.vue @@ -15,6 +15,3 @@ </template> <script src="./remote_user_resolver.js"></script> - -<style lang="scss"> -</style> diff --git a/src/components/remove_follower_button/remove_follower_button.js b/src/components/remove_follower_button/remove_follower_button.js @@ -0,0 +1,25 @@ +export default { + props: ['relationship'], + data () { + return { + inProgress: false + } + }, + computed: { + label () { + if (this.inProgress) { + return this.$t('user_card.follow_progress') + } else { + return this.$t('user_card.remove_follower') + } + } + }, + methods: { + onClick () { + this.inProgress = true + this.$store.dispatch('removeUserFromFollowers', this.relationship.id).then(() => { + this.inProgress = false + }) + } + } +} diff --git a/src/components/remove_follower_button/remove_follower_button.vue b/src/components/remove_follower_button/remove_follower_button.vue @@ -0,0 +1,13 @@ +<template> + <button + class="btn button-default follow-button" + :class="{ toggled: inProgress }" + :disabled="inProgress" + :title="$t('user_card.remove_follower')" + @click="onClick" + > + {{ label }} + </button> +</template> + +<script src="./remove_follower_button.js"></script> diff --git a/src/components/reply_button/reply_button.js b/src/components/reply_button/reply_button.js @@ -1,7 +1,15 @@ import { library } from '@fortawesome/fontawesome-svg-core' -import { faReply } from '@fortawesome/free-solid-svg-icons' +import { + faReply, + faPlus, + faTimes +} from '@fortawesome/free-solid-svg-icons' -library.add(faReply) +library.add( + faReply, + faPlus, + faTimes +) const ReplyButton = { name: 'ReplyButton', @@ -9,6 +17,9 @@ const ReplyButton = { computed: { loggedIn () { return !!this.$store.state.users.currentUser + }, + remoteInteractionLink () { + return this.$store.getters.remoteInteractionLink({ statusId: this.status.id }) } } } diff --git a/src/components/reply_button/reply_button.vue b/src/components/reply_button/reply_button.vue @@ -7,18 +7,38 @@ :title="$t('tool_tip.reply')" @click.prevent="$emit('toggle')" > - <FAIcon - class="fa-scale-110 fa-old-padding" - icon="reply" - /> + <FALayers class="fa-old-padding-layer"> + <FAIcon + class="fa-scale-110" + icon="reply" + /> + <FAIcon + v-if="!replying" + class="focus-marker" + transform="shrink-6 up-8 right-11" + icon="plus" + /> + <FAIcon + v-else + class="focus-marker" + transform="shrink-6 up-8 right-11" + icon="times" + /> + </FALayers> </button> - <span v-else> + <a + v-else + class="button-unstyled interactive" + target="_blank" + role="button" + :href="remoteInteractionLink" + > <FAIcon icon="reply" class="fa-scale-110 fa-old-padding" :title="$t('tool_tip.reply')" /> - </span> + </a> <span v-if="status.replies_count > 0" class="action-counter" @@ -31,7 +51,8 @@ <script src="./reply_button.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; +@import "../../mixins"; .ReplyButton { display: flex; @@ -52,7 +73,18 @@ color: $fallback--cBlue; color: var(--cBlue, $fallback--cBlue); } - } + @include unfocused-style { + .focus-marker { + visibility: hidden; + } + } + + @include focused-style { + .focus-marker { + visibility: visible; + } + } + } } </style> diff --git a/src/components/report/report.js b/src/components/report/report.js @@ -0,0 +1,34 @@ +import Select from '../select/select.vue' +import StatusContent from '../status_content/status_content.vue' +import Timeago from '../timeago/timeago.vue' +import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' + +const Report = { + props: [ + 'reportId' + ], + components: { + Select, + StatusContent, + Timeago + }, + computed: { + report () { + return this.$store.state.reports.reports[this.reportId] || {} + }, + state: { + get: function () { return this.report.state }, + set: function (val) { this.setReportState(val) } + } + }, + methods: { + generateUserProfileLink (user) { + return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames) + }, + setReportState (state) { + return this.$store.dispatch('setReportState', { id: this.report.id, state }) + } + } +} + +export default Report diff --git a/src/components/report/report.scss b/src/components/report/report.scss @@ -0,0 +1,43 @@ +@import "../../variables"; + +.Report { + .report-content { + margin: 0.5em 0 1em; + } + + .report-state { + margin: 0.5em 0 1em; + } + + .reported-status { + border: 1px solid $fallback--faint; + border-color: var(--faint, $fallback--faint); + border-radius: $fallback--inputRadius; + border-radius: var(--inputRadius, $fallback--inputRadius); + color: $fallback--text; + color: var(--text, $fallback--text); + display: block; + padding: 0.5em; + margin: 0.5em 0; + + .status-content { + pointer-events: none; + } + + .reported-status-heading { + display: flex; + width: 100%; + justify-content: space-between; + margin-bottom: 0.2em; + } + + .reported-status-name { + font-weight: bold; + } + } + + .note { + width: 100%; + margin-bottom: 0.5em; + } +} diff --git a/src/components/report/report.vue b/src/components/report/report.vue @@ -0,0 +1,74 @@ +<template> + <div class="Report"> + <div class="reported-user"> + <span>{{ $t('report.reported_user') }}</span> + <router-link :to="generateUserProfileLink(report.acct)"> + @{{ report.acct.screen_name }} + </router-link> + </div> + <div class="reporter"> + <span>{{ $t('report.reporter') }}</span> + <router-link :to="generateUserProfileLink(report.actor)"> + @{{ report.actor.screen_name }} + </router-link> + </div> + <div class="report-state"> + <span>{{ $t('report.state') }}</span> + <Select + :id="report-state" + v-model="state" + class="form-control" + > + <option + v-for="state in ['open', 'closed', 'resolved']" + :key="state" + :value="state" + > + {{ $t('report.state_' + state) }} + </option> + </Select> + </div> + <RichContent + class="report-content" + :html="report.content" + :emoji="[]" + /> + <div v-if="report.statuses.length"> + <small>{{ $t('report.reported_statuses') }}</small> + <router-link + v-for="status in report.statuses" + :key="status.id" + :to="{ name: 'conversation', params: { id: status.id } }" + class="reported-status" + > + <div class="reported-status-heading"> + <span class="reported-status-name">{{ status.user.name }}</span> + <Timeago + :time="status.created_at" + :auto-update="240" + class="faint" + /> + </div> + <status-content :status="status" /> + </router-link> + </div> + <div v-if="report.notes.length"> + <small>{{ $t('report.notes') }}</small> + <div + v-for="note in report.notes" + :key="note.id" + class="note" + > + <span>{{ note.content }}</span> + <Timeago + :time="note.created_at" + :auto-update="240" + class="faint" + /> + </div> + </div> + </div> +</template> + +<script src="./report.js"></script> +<style src="./report.scss" lang="scss"></style> diff --git a/src/components/retweet_button/retweet_button.js b/src/components/retweet_button/retweet_button.js @@ -1,7 +1,17 @@ import { library } from '@fortawesome/fontawesome-svg-core' -import { faRetweet } from '@fortawesome/free-solid-svg-icons' +import { + faRetweet, + faPlus, + faMinus, + faCheck +} from '@fortawesome/free-solid-svg-icons' -library.add(faRetweet) +library.add( + faRetweet, + faPlus, + faMinus, + faCheck +) const RetweetButton = { props: ['status', 'loggedIn', 'visibility'], @@ -26,6 +36,9 @@ const RetweetButton = { computed: { mergedConfig () { return this.$store.getters.mergedConfig + }, + remoteInteractionLink () { + return this.$store.getters.remoteInteractionLink({ statusId: this.status.id }) } } } diff --git a/src/components/retweet_button/retweet_button.vue b/src/components/retweet_button/retweet_button.vue @@ -7,11 +7,31 @@ :title="$t('tool_tip.repeat')" @click.prevent="retweet()" > - <FAIcon - class="fa-scale-110 fa-old-padding" - icon="retweet" - :spin="animated" - /> + <FALayers class="fa-old-padding-layer"> + <FAIcon + class="fa-scale-110" + icon="retweet" + :spin="animated" + /> + <FAIcon + v-if="status.repeated" + class="active-marker" + transform="shrink-6 up-9 right-12" + icon="check" + /> + <FAIcon + v-if="!status.repeated" + class="focus-marker" + transform="shrink-6 up-9 right-12" + icon="plus" + /> + <FAIcon + v-else + class="focus-marker" + transform="shrink-6 up-9 right-12" + icon="minus" + /> + </FALayers> </button> <span v-else-if="loggedIn"> <FAIcon @@ -20,13 +40,19 @@ :title="$t('timeline.no_retweet_hint')" /> </span> - <span v-else> + <a + v-else + class="button-unstyled interactive" + target="_blank" + role="button" + :href="remoteInteractionLink" + > <FAIcon class="fa-scale-110 fa-old-padding" icon="retweet" :title="$t('tool_tip.repeat')" /> - </span> + </a> <span v-if="!mergedConfig.hidePostStats && status.repeat_num > 0" class="no-event" @@ -39,7 +65,8 @@ <script src="./retweet_button.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; +@import "../../mixins"; .RetweetButton { display: flex; @@ -64,6 +91,26 @@ color: $fallback--cGreen; color: var(--cGreen, $fallback--cGreen); } + + @include unfocused-style { + .focus-marker { + visibility: hidden; + } + + .active-marker { + visibility: visible; + } + } + + @include focused-style { + .focus-marker { + visibility: visible; + } + + .active-marker { + visibility: hidden; + } + } } } </style> diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx @@ -150,6 +150,7 @@ export default { if (Array.isArray(item)) { const [opener, children, closer] = item const Tag = getTagName(opener) + const fullAttrs = getAttrs(opener, () => true) const attrs = getAttrs(opener) const previouslyMentions = currentMentions !== null /* During grouping of mentions we trim all the empty text elements @@ -171,7 +172,7 @@ export default { return ['', [mentionsLinePadding, renderImage(opener)], ''] case 'a': // replace mentions with MentionLink if (!this.handleLinks) break - if (attrs['class'] && attrs['class'].includes('mention')) { + if (fullAttrs.class && fullAttrs.class.includes('mention')) { // Handling mentions here return renderMention(attrs, children) } else { @@ -179,7 +180,7 @@ export default { break } case 'span': - if (this.handleLinks && attrs['class'] && attrs['class'].includes('h-card')) { + if (this.handleLinks && fullAttrs.class && fullAttrs.class.includes('h-card')) { return ['', children.map(processItem), ''] } } @@ -213,13 +214,14 @@ export default { const [opener, children] = item const Tag = opener === '' ? '' : getTagName(opener) switch (Tag) { - case 'a': // replace mentions with MentionLink + case 'a': { // replace mentions with MentionLink if (!this.handleLinks) break - const attrs = getAttrs(opener) + const fullAttrs = getAttrs(opener, () => true) + const attrs = getAttrs(opener, () => true) // should only be this if ( - (attrs['class'] && attrs['class'].includes('hashtag')) || // Pleroma style - (attrs['rel'] === 'tag') // Mastodon style + (fullAttrs.class && fullAttrs.class.includes('hashtag')) || // Pleroma style + (fullAttrs.rel === 'tag') // Mastodon style ) { return renderHashtag(attrs, children, encounteredTextReverse) } else { @@ -230,6 +232,7 @@ export default { { newChildren } </a> } + } case '': return [...children].reverse().map(processItemReverse).reverse() } diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss @@ -1,7 +1,11 @@ +@import "../../variables"; + .RichContent { blockquote { - margin: 0.2em 0 0.2em 2em; + margin: 0.2em 0 0.2em 0.2em; font-style: italic; + border-left: 0.2em solid var(--faint, $fallback--faint); + padding-left: 1em; } pre { @@ -17,11 +21,11 @@ } p { - margin: 0 0 1em 0; + margin: 0 0 1em; } p:last-child { - margin: 0 0 0 0; + margin: 0; } h1 { diff --git a/src/components/scope_selector/scope_selector.vue b/src/components/scope_selector/scope_selector.vue @@ -64,10 +64,9 @@ <script src="./scope_selector.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .ScopeSelector { - .scope { display: inline-block; cursor: pointer; diff --git a/src/components/search/search.js b/src/components/search/search.js @@ -8,6 +8,7 @@ import { faCircleNotch, faSearch } from '@fortawesome/free-solid-svg-icons' +import { uniqBy } from 'lodash' library.add( faCircleNotch, @@ -32,7 +33,11 @@ const Search = { userIds: [], statuses: [], hashtags: [], - currenResultTab: 'statuses' + currenResultTab: 'statuses', + + statusesOffset: 0, + lastStatusFetchCount: 0, + lastQuery: '' } }, computed: { @@ -61,26 +66,42 @@ const Search = { this.$router.push({ name: 'search', query: { query } }) this.$refs.searchInput.focus() }, - search (query) { + search (query, searchType = null) { if (!query) { this.loading = false return } this.loading = true - this.userIds = [] - this.statuses = [] - this.hashtags = [] this.$refs.searchInput.blur() + if (this.lastQuery !== query) { + this.userIds = [] + this.hashtags = [] + this.statuses = [] + + this.statusesOffset = 0 + this.lastStatusFetchCount = 0 + } - this.$store.dispatch('search', { q: query, resolve: true }) + this.$store.dispatch('search', { q: query, resolve: true, offset: this.statusesOffset, type: searchType }) .then(data => { this.loading = false - this.userIds = map(data.accounts, 'id') - this.statuses = data.statuses - this.hashtags = data.hashtags + + const oldLength = this.statuses.length + + // Always append to old results. If new results are empty, this doesn't change anything + this.userIds = this.userIds.concat(map(data.accounts, 'id')) + this.statuses = uniqBy(this.statuses.concat(data.statuses), 'id') + this.hashtags = this.hashtags.concat(data.hashtags) + this.currenResultTab = this.getActiveTab() this.loaded = true + + // Offset from whatever we already have + this.statusesOffset = this.statuses.length + // Because the amount of new statuses can actually be zero, compare to old lenght instead + this.lastStatusFetchCount = this.statuses.length - oldLength + this.lastQuery = query }) }, resultCount (tabName) { diff --git a/src/components/search/search.vue b/src/components/search/search.vue @@ -22,7 +22,7 @@ </button> </div> <div - v-if="loading" + v-if="loading && statusesOffset == 0" class="text-center loading-icon" > <FAIcon @@ -55,12 +55,6 @@ </div> <div class="panel-body"> <div v-if="currenResultTab === 'statuses'"> - <div - v-if="visibleStatuses.length === 0 && !loading && loaded" - class="search-result-heading" - > - <h4>{{ $t('search.no_results') }}</h4> - </div> <Status v-for="status in visibleStatuses" :key="status.id" @@ -71,6 +65,33 @@ :statusoid="status" :no-heading="false" /> + <button + v-if="!loading && loaded && lastStatusFetchCount > 0" + class="more-statuses-button button-unstyled -link -fullwidth" + @click.prevent="search(searchTerm, 'statuses')" + > + <div class="new-status-notification text-center"> + {{ $t('search.load_more') }} + </div> + </button> + <div + v-else-if="loading && statusesOffset > 0" + class="text-center loading-icon" + > + <FAIcon + icon="circle-notch" + spin + size="lg" + /> + </div> + <div + v-if="(visibleStatuses.length === 0 || lastStatusFetchCount === 0) && !loading && loaded" + class="search-result-heading" + > + <h4> + {{ visibleStatuses.length === 0 ? $t('search.no_results') : $t('search.no_more_results') }} + </h4> + </div> </div> <div v-else-if="currenResultTab === 'people'"> <div @@ -127,7 +148,7 @@ <script src="./search.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .search-result-heading { color: $fallback--faint; @@ -155,7 +176,7 @@ } .search-result-footer { - border-width: 1px 0 0 0; + border-width: 1px 0 0; border-style: solid; border-color: var(--border, $fallback--border); padding: 10px; @@ -210,4 +231,9 @@ } } +.more-statuses-button { + height: 3.5em; + line-height: 3.5em; +} + </style> diff --git a/src/components/search_bar/search_bar.vue b/src/components/search_bar/search_bar.vue @@ -47,6 +47,8 @@ class="cancel-icon fa-scale-110 fa-old-padding" /> </button> + <span class="spacer" /> + <span class="spacer" /> </template> </div> </template> @@ -54,7 +56,7 @@ <script src="./search_bar.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .SearchBar { display: inline-flex; diff --git a/src/components/select/select.vue b/src/components/select/select.vue @@ -21,22 +21,20 @@ <script src="./select.js"> </script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; /* TODO fix order of styles */ label.Select { padding: 0; select { - -webkit-appearance: none; - -moz-appearance: none; appearance: none; background: transparent; border: none; color: $fallback--text; color: var(--inputText, --text, $fallback--text); margin: 0; - padding: 0 2em 0 .2em; + padding: 0 2em 0 0.2em; font-family: sans-serif; font-family: var(--inputFont, sans-serif); font-size: 1em; @@ -59,6 +57,5 @@ label.Select { z-index: 0; pointer-events: none; } - } </style> diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue @@ -51,7 +51,7 @@ <script src="./selectable_list.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .selectable-list { &-item-inner { @@ -67,6 +67,7 @@ background-color: $fallback--lightBg; background-color: var(--selectedMenu, $fallback--lightBg); color: var(--selectedMenuText, $fallback--text); + --faint: var(--selectedMenuFaintText, $fallback--faint); --faintLink: var(--selectedMenuFaintLink, $fallback--faint); --lightText: var(--selectedMenuLightText, $fallback--lightText); diff --git a/src/components/settings_modal/helpers/boolean_setting.js b/src/components/settings_modal/helpers/boolean_setting.js @@ -41,7 +41,16 @@ export default { }, methods: { update (e) { + const [firstSegment, ...rest] = this.path.split('.') set(this.$parent, this.path, e) + // Updating nested properties does not trigger update on its parent. + // probably still not as reliable, but works for depth=1 at least + if (rest.length > 0) { + set(this.$parent, firstSegment, { ...get(this.$parent, firstSegment) }) + } + }, + reset () { + set(this.$parent, this.path, this.defaultState) } } } diff --git a/src/components/settings_modal/helpers/boolean_setting.vue b/src/components/settings_modal/helpers/boolean_setting.vue @@ -15,7 +15,12 @@ <slot /> </span> {{ ' ' }} - <ModifiedIndicator :changed="isChanged" /><ServerSideIndicator :server-side="isServerSide" /> </Checkbox> + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> + <ServerSideIndicator :server-side="isServerSide" /> + </Checkbox> </label> </template> diff --git a/src/components/settings_modal/helpers/choice_setting.js b/src/components/settings_modal/helpers/choice_setting.js @@ -43,6 +43,9 @@ export default { methods: { update (e) { set(this.$parent, this.path, e) + }, + reset () { + set(this.$parent, this.path, this.defaultState) } } } diff --git a/src/components/settings_modal/helpers/choice_setting.vue b/src/components/settings_modal/helpers/choice_setting.vue @@ -19,14 +19,12 @@ {{ option.value === defaultState ? $t('settings.instance_default_simple') : '' }} </option> </Select> - <ModifiedIndicator :changed="isChanged" /> + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> <ServerSideIndicator :server-side="isServerSide" /> </label> </template> <script src="./choice_setting.js"></script> - -<style lang="scss"> -.ChoiceSetting { -} -</style> diff --git a/src/components/settings_modal/helpers/integer_setting.js b/src/components/settings_modal/helpers/integer_setting.js @@ -36,6 +36,9 @@ export default { methods: { update (e) { set(this.$parent, this.path, parseInt(e.target.value)) + }, + reset () { + set(this.$parent, this.path, this.defaultState) } } } diff --git a/src/components/settings_modal/helpers/integer_setting.vue b/src/components/settings_modal/helpers/integer_setting.vue @@ -17,7 +17,10 @@ @change="update" > {{ ' ' }} - <ModifiedIndicator :changed="isChanged" /> + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> </span> </template> diff --git a/src/components/settings_modal/helpers/size_setting.js b/src/components/settings_modal/helpers/size_setting.js @@ -0,0 +1,67 @@ +import { get, set } from 'lodash' +import ModifiedIndicator from './modified_indicator.vue' +import Select from 'src/components/select/select.vue' + +export const allCssUnits = ['cm', 'mm', 'in', 'px', 'pt', 'pc', 'em', 'ex', 'ch', 'rem', 'vw', 'vh', 'vmin', 'vmax', '%'] +export const defaultHorizontalUnits = ['px', 'rem', 'vw'] +export const defaultVerticalUnits = ['px', 'rem', 'vh'] + +export default { + components: { + ModifiedIndicator, + Select + }, + props: { + path: String, + disabled: Boolean, + min: Number, + units: { + type: [String], + default: () => allCssUnits + }, + expert: [Number, String] + }, + computed: { + pathDefault () { + const [firstSegment, ...rest] = this.path.split('.') + return [firstSegment + 'DefaultValue', ...rest].join('.') + }, + stateUnit () { + return (this.state || '').replace(/\d+/, '') + }, + stateValue () { + return (this.state || '').replace(/\D+/, '') + }, + state () { + const value = get(this.$parent, this.path) + if (value === undefined) { + return this.defaultState + } else { + return value + } + }, + defaultState () { + return get(this.$parent, this.pathDefault) + }, + isChanged () { + return this.state !== this.defaultState + }, + matchesExpertLevel () { + return (this.expert || 0) <= this.$parent.expertLevel + } + }, + methods: { + update (e) { + set(this.$parent, this.path, e) + }, + reset () { + set(this.$parent, this.path, this.defaultState) + }, + updateValue (e) { + set(this.$parent, this.path, parseInt(e.target.value) + this.stateUnit) + }, + updateUnit (e) { + set(this.$parent, this.path, this.stateValue + e.target.value) + } + } +} diff --git a/src/components/settings_modal/helpers/size_setting.vue b/src/components/settings_modal/helpers/size_setting.vue @@ -0,0 +1,55 @@ +<template> + <span + v-if="matchesExpertLevel" + class="SizeSetting" + > + <label + :for="path" + class="size-label" + > + <slot /> + </label> + <input + :id="path" + class="number-input" + type="number" + step="1" + :disabled="disabled" + :min="min || 0" + :value="stateValue" + @change="updateValue" + > + <Select + :id="path" + :model-value="stateUnit" + :disabled="disabled" + class="css-unit-input" + @change="updateUnit" + > + <option + v-for="option in units" + :key="option" + :value="option" + > + {{ option }} + </option> + </Select> + {{ ' ' }} + <ModifiedIndicator + :changed="isChanged" + :onclick="reset" + /> + </span> +</template> + +<script src="./size_setting.js"></script> + +<style lang="scss"> +.css-unit-input, +.css-unit-input select { + margin-left: 0.5em; + width: 4em; + max-width: 4em; + min-width: 4em; +} +</style> diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss @@ -1,4 +1,5 @@ -@import 'src/_variables.scss'; +@import "src/variables"; + .settings-modal { overflow: hidden; @@ -6,32 +7,13 @@ .option-list { list-style-type: none; padding-left: 2em; + li { margin-bottom: 0.5em; } - .suboptions { - margin-top: 0.3em - } - } - - &.peek { - .settings-modal-panel { - /* Explanation: - * Modal is positioned vertically centered. - * 100vh - 100% = Distance between modal's top+bottom boundaries and screen - * (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen - * + 100% - we move modal completely off-screen, it's top boundary touches - * bottom of the screen - * - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible - */ - transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px)); - @media all and (max-width: 800px) { - /* For mobile, the modal takes 100% of the available screen. - This ensures the minimized modal is always 50px above the browser bottom bar regardless of whether or not it is visible. - */ - transform: translateY(calc(100% - 50px)); - } + .suboptions { + margin-top: 0.3em; } } @@ -63,6 +45,7 @@ .settings-footer { display: flex; + >* { margin-right: 0.5em; } @@ -72,4 +55,26 @@ flex-grow: 1; } } + + &.peek { + .settings-modal-panel { + /* Explanation: + * Modal is positioned vertically centered. + * 100vh - 100% = Distance between modal's top+bottom boundaries and screen + * (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen + * + 100% - we move modal completely off-screen, it's top boundary touches + * bottom of the screen + * - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible + */ + transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px)); + + @media all and (max-width: 800px) { + /* For mobile, the modal takes 100% of the available screen. + This ensures the minimized modal is always 50px above the browser bottom + bar regardless of whether or not it is visible. + */ + transform: translateY(calc(100% - 50px)); + } + } + } } diff --git a/src/components/settings_modal/settings_modal_content.scss b/src/components/settings_modal/settings_modal_content.scss @@ -1,4 +1,5 @@ -@import 'src/_variables.scss'; +@import "src/variables"; + .settings_tab-switcher { height: 100%; @@ -10,7 +11,8 @@ > div, > label { display: block; - margin-bottom: .5em; + margin-bottom: 0.5em; + &:last-child { margin-bottom: 0; } @@ -21,7 +23,7 @@ .option-list { margin: 0; - padding-left: .5em; + padding-left: 0.5em; } } diff --git a/src/components/settings_modal/tabs/data_import_export_tab.vue b/src/components/settings_modal/tabs/data_import_export_tab.vue @@ -78,6 +78,16 @@ {{ $t('settings.download_backup') }} </a> <span + v-else-if="backup.state === 'running'" + > + {{ $tc('settings.backup_running', backup.processed_number, { number: backup.processed_number }) }} + </span> + <span + v-else-if="backup.state === 'failed'" + > + {{ $t('settings.backup_failed') }} + </span> + <span v-else > {{ $t('settings.backup_not_ready') }} diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js @@ -1,4 +1,4 @@ -import { filter, trim } from 'lodash' +import { filter, trim, debounce } from 'lodash' import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue' @@ -29,24 +29,20 @@ const FilteringTab = { }, set (value) { this.muteWordsStringLocal = value + this.debouncedSetMuteWords(value) + } + }, + debouncedSetMuteWords () { + return debounce((value) => { this.$store.dispatch('setOption', { name: 'muteWords', value: filter(value.split('\n'), (word) => trim(word).length > 0) }) - } + }, 1000) } }, // Updating nested properties watch: { - notificationVisibility: { - handler (value) { - this.$store.dispatch('setOption', { - name: 'notificationVisibility', - value: this.$store.getters.mergedConfig.notificationVisibility - }) - }, - deep: true - }, replyVisibility () { this.$store.dispatch('queueFlushAll') } diff --git a/src/components/settings_modal/tabs/general_tab.js b/src/components/settings_modal/tabs/general_tab.js @@ -2,6 +2,7 @@ import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' import ScopeSelector from 'src/components/scope_selector/scope_selector.vue' import IntegerSetting from '../helpers/integer_setting.vue' +import SizeSetting, { defaultHorizontalUnits } from '../helpers/size_setting.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' @@ -43,6 +44,11 @@ const GeneralTab = { value: mode, label: this.$t(`settings.third_column_mode_${mode}`) })), + userPopoverAvatarActionOptions: ['close', 'zoom', 'open'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.user_popover_avatar_action_${mode}`) + })), loopSilentAvailable: // Firefox Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || @@ -56,11 +62,15 @@ const GeneralTab = { BooleanSetting, ChoiceSetting, IntegerSetting, + SizeSetting, InterfaceLanguageSwitcher, ScopeSelector, ServerSideIndicator }, computed: { + horizontalUnits () { + return defaultHorizontalUnits + }, postFormats () { return this.$store.state.instance.postFormats || [] }, @@ -71,6 +81,17 @@ const GeneralTab = { label: this.$t(`post_status.content_type["${format}"]`) })) }, + columns () { + const mode = this.$store.getters.mergedConfig.thirdColumnMode + + const notif = mode === 'none' ? [] : ['notifs'] + + if (this.$store.getters.mergedConfig.sidebarRight || mode === 'postform') { + return [...notif, 'content', 'sidebar'] + } else { + return ['sidebar', 'content', ...notif] + } + }, instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, instanceWallpaperUsed () { return this.$store.state.instance.background && diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue @@ -15,11 +15,6 @@ {{ $t('settings.hide_isp') }} </BooleanSetting> </li> - <li> - <BooleanSetting path="sidebarRight"> - {{ $t('settings.right_sidebar') }} - </BooleanSetting> - </li> <li v-if="instanceWallpaperUsed"> <BooleanSetting path="hideInstanceWallpaper"> {{ $t('settings.hide_wallpaper') }} @@ -65,22 +60,14 @@ </BooleanSetting> </li> <li> - <BooleanSetting path="disableStickyHeaders"> - {{ $t('settings.disable_sticky_headers') }} - </BooleanSetting> - </li> - <li> - <BooleanSetting path="showScrollbars"> - {{ $t('settings.show_scrollbars') }} - </BooleanSetting> - </li> - <li> - <BooleanSetting - path="userPopoverZoom" + <ChoiceSetting + id="userPopoverAvatarAction" + path="userPopoverAvatarAction" + :options="userPopoverAvatarActionOptions" expert="1" > - {{ $t('settings.user_popover_avatar_zoom') }} - </BooleanSetting> + {{ $t('settings.user_popover_avatar_action') }} + </ChoiceSetting> </li> <li> <BooleanSetting @@ -91,16 +78,6 @@ </BooleanSetting> </li> <li> - <ChoiceSetting - v-if="user" - id="thirdColumnMode" - path="thirdColumnMode" - :options="thirdColumnModeOptions" - > - {{ $t('settings.third_column_mode') }} - </ChoiceSetting> - </li> - <li> <BooleanSetting path="alwaysShowNewPostButton" expert="1" @@ -124,6 +101,53 @@ {{ $t('settings.hide_shoutbox') }} </BooleanSetting> </li> + <li> + <h3>{{ $t('settings.columns') }}</h3> + </li> + <li> + <BooleanSetting path="disableStickyHeaders"> + {{ $t('settings.disable_sticky_headers') }} + </BooleanSetting> + </li> + <li> + <BooleanSetting path="showScrollbars"> + {{ $t('settings.show_scrollbars') }} + </BooleanSetting> + </li> + <li> + <BooleanSetting path="sidebarRight"> + {{ $t('settings.right_sidebar') }} + </BooleanSetting> + </li> + <li> + <BooleanSetting path="navbarColumnStretch"> + {{ $t('settings.navbar_column_stretch') }} + </BooleanSetting> + </li> + <li> + <ChoiceSetting + v-if="user" + id="thirdColumnMode" + path="thirdColumnMode" + :options="thirdColumnModeOptions" + > + {{ $t('settings.third_column_mode') }} + </ChoiceSetting> + </li> + <li v-if="expertLevel > 0"> + {{ $t('settings.column_sizes') }} + <div class="column-settings"> + <SizeSetting + v-for="column in columns" + :key="column" + :path="column + 'ColumnWidth'" + :units="horizontalUnits" + expert="1" + > + {{ $t('settings.column_sizes_' + column) }} + </SizeSetting> + </div> + </li> </ul> </div> <div class="setting-item"> @@ -433,3 +457,17 @@ </template> <script src="./general_tab.js"></script> + +<style lang="scss"> +.column-settings { + display: flex; + justify-content: space-evenly; + flex-wrap: wrap; +} + +.column-settings .size-label { + display: block; + margin-bottom: 0.5em; + margin-top: 0.5em; +} +</style> diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.scss b/src/components/settings_modal/tabs/mutes_and_blocks_tab.scss @@ -1,29 +1,29 @@ .mutes-and-blocks-tab { - height: 100%; + height: 100%; - .usersearch-wrapper { - padding: 1em; - } + .usersearch-wrapper { + padding: 1em; + } - .bulk-actions { - text-align: right; - padding: 0 1em; - min-height: 2em; - } + .bulk-actions { + text-align: right; + padding: 0 1em; + min-height: 2em; + } - .bulk-action-button { - width: 10em - } + .bulk-action-button { + width: 10em; + } - .domain-mute-form { - padding: 1em; - display: flex; - flex-direction: column - } + .domain-mute-form { + padding: 1em; + display: flex; + flex-direction: column; + } - .domain-mute-button { - align-self: flex-end; - margin-top: 1em; - width: 10em - } + .domain-mute-button { + align-self: flex-end; + margin-top: 1em; + width: 10em; + } } diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue @@ -56,7 +56,7 @@ <div :label="$t('settings.mutes_tab')"> <tab-switcher> - <div label="Users"> + <div :label="$t('settings.user_mutes')"> <div class="usersearch-wrapper"> <Autosuggest :filter="filterUnMutedUsers" diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js @@ -66,7 +66,7 @@ const ProfileTab = { emojiUserSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ], store: this.$store @@ -75,7 +75,7 @@ const ProfileTab = { emojiSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ] }) @@ -157,7 +157,7 @@ const ProfileTab = { return false }, deleteField (index, event) { - this.$delete(this.newFields, index) + this.newFields.splice(index, 1) }, uploadFile (slot, e) { const file = e.target.files[0] diff --git a/src/components/settings_modal/tabs/profile_tab.scss b/src/components/settings_modal/tabs/profile_tab.scss @@ -1,4 +1,5 @@ -@import '../../../_variables.scss'; +@import "../../../variables"; + .profile-tab { .bio { margin: 0; @@ -8,7 +9,7 @@ padding-top: 5px; } - input[type=file] { + input[type="file"] { padding: 5px; height: auto; } @@ -52,7 +53,7 @@ right: 0.2em; border-radius: $fallback--tooltipRadius; border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - background-color: rgba(0, 0, 0, 0.6); + background-color: rgb(0 0 0 / 60%); opacity: 0.7; width: 1.5em; height: 1.5em; diff --git a/src/components/settings_modal/tabs/security_tab/mfa.vue b/src/components/settings_modal/tabs/security_tab/mfa.vue @@ -137,9 +137,11 @@ <script src="./mfa.js"></script> <style lang="scss"> -@import '../../../../_variables.scss'; +@import "../../../../variables"; + .mfa-settings { - .mfa-heading, .method-item { + .mfa-heading, + .method-item { display: flex; flex-wrap: wrap; justify-content: space-between; @@ -155,18 +157,19 @@ display: flex; justify-content: center; flex-wrap: wrap; + .qr-code { flex: 1; padding-right: 10px; } .verify { flex: 1; } - .error { margin: 4px 0 0 0; } + .error { margin: 4px 0 0; } + .confirm-otp-actions { button { width: 15em; margin-top: 5px; } - } } } diff --git a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue @@ -21,13 +21,14 @@ </template> <script src="./mfa_backup_codes.js"></script> <style lang="scss"> -@import '../../../../_variables.scss'; +@import "../../../../variables"; .mfa-backup-codes { .warning { color: $fallback--cOrange; color: var(--cOrange, $fallback--cOrange); } + .backup-codes { font-family: var(--postCodeFont, monospace); } diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.vue b/src/components/settings_modal/tabs/security_tab/security_tab.vue @@ -241,7 +241,7 @@ class="btn button-default" @click="confirmDelete" > - {{ $t('settings.save') }} + {{ $t('settings.delete_account') }} </button> </div> </div> diff --git a/src/components/settings_modal/tabs/theme_tab/preview.vue b/src/components/settings_modal/tabs/theme_tab/preview.vue @@ -33,10 +33,10 @@ scope="global" keypath="settings.style.preview.text" > - <code style="font-family: var(--postCodeFont)"> + <code style="font-family: var(--postCodeFont);"> {{ $t('settings.style.preview.mono') }} </code> - <a style="color: var(--link)"> + <a style="color: var(--link);"> {{ $t('settings.style.preview.link') }} </a> </i18n-t> @@ -44,25 +44,25 @@ <div class="icons"> <FAIcon fixed-width - style="color: var(--cBlue)" + style="color: var(--cBlue);" class="fa-scale-110 fa-old-padding" icon="reply" /> <FAIcon fixed-width - style="color: var(--cGreen)" + style="color: var(--cGreen);" class="fa-scale-110 fa-old-padding" icon="retweet" /> <FAIcon fixed-width - style="color: var(--cOrange)" + style="color: var(--cOrange);" class="fa-scale-110 fa-old-padding" icon="star" /> <FAIcon fixed-width - style="color: var(--cRed)" + style="color: var(--cRed);" class="fa-scale-110 fa-old-padding" icon="times" /> @@ -81,7 +81,7 @@ class="faint" scope="global" > - <a style="color: var(--faintLink)"> + <a style="color: var(--faintLink);"> {{ $t('settings.style.preview.faint_link') }} </a> </i18n-t> @@ -138,6 +138,7 @@ export default {} .preview-container { position: relative; } + .underlay-preview { position: absolute; top: 0; diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -279,6 +279,9 @@ export default { opacity ) + // Temporary patch for null-y value errors + if (layers.flat().some(v => v == null)) return acc + return { ...acc, ...textColors.reduce((acc, textColorKey) => { @@ -300,6 +303,7 @@ export default { return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {}) } catch (e) { console.warn('Failure computing contrasts', e) + return {} } }, previewRules () { diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss @@ -1,20 +1,17 @@ -@import 'src/_variables.scss'; +@import "src/variables"; + .theme-tab { padding-bottom: 2em; - .theme-warning { - display: flex; - align-items: baseline; - margin-bottom: .5em; - .buttons { - .btn { - margin-bottom: .5em; - } - } - } + .preset-switcher { margin-right: 1em; } + .btn { + margin-left: 0.25em; + margin-right: 0.25em; + } + .style-control { display: flex; align-items: baseline; @@ -24,35 +21,37 @@ flex: 1; } - &.disabled { - input, select { - opacity: .5 - } - } - .opt { - margin: .5em; + margin: 0.5em; } .color-input { flex: 0 0 0; } - input, select { + input, + select { min-width: 3em; margin: 0; flex: 0; - &[type=number] { + &[type="number"] { min-width: 5em; } - &[type=range] { + &[type="range"] { flex: 1; min-width: 3em; align-self: flex-start; } } + + &.disabled { + input, + select { + opacity: 0.5; + } + } } .reset-container { @@ -63,8 +62,7 @@ .reset-container, .apply-container, .radius-container, - .color-container, - { + .color-container, { display: flex; } @@ -73,10 +71,11 @@ flex-direction: column; } - .color-container{ + .color-container { > h4 { width: 99%; } + flex-wrap: wrap; justify-content: space-between; } @@ -100,7 +99,7 @@ p { flex: 1; margin: 0; - margin-right: .5em; + margin-right: 0.5em; } } @@ -112,15 +111,16 @@ min-width: 1px; flex: 0 auto; padding: 0 1em; - margin-bottom: .5em; + margin-bottom: 0.5em; } } .shadow-selector { .override { flex: 1; - margin-left: .5em; + margin-left: 0.5em; } + .select-container { margin-top: -4px; margin-bottom: -3px; @@ -136,7 +136,7 @@ .presets, .import-export { - margin-bottom: .5em; + margin-bottom: 0.5em; } .import-export { @@ -144,16 +144,17 @@ } .override { - margin-left: .5em; + margin-left: 0.5em; } } .save-load-options { flex-wrap: wrap; - margin-top: .5em; + margin-top: 0.5em; justify-content: center; + .keep-option { - margin: 0 .5em .5em; + margin: 0 0.5em 0.5em; min-width: 25%; } } @@ -179,11 +180,11 @@ flex: 1; h4 { - margin-bottom: .25em; + margin-bottom: 0.25em; } .icons { - margin-top: .5em; + margin-top: 0.5em; display: flex; i { @@ -199,8 +200,20 @@ align-items: center; } - .avatar, .avatar-alt{ - background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%); + .avatar, + .avatar-alt { + background: + linear-gradient( + 135deg, + #b8e1fc 0%, + #a9d2f3 10%, + #90bae4 25%, + #90bcea 37%, + #90bff0 50%, + #6ba8e5 51%, + #a2daf5 83%, + #bdf3fd 100% + ); color: black; font-family: sans-serif; text-align: center; @@ -251,33 +264,33 @@ } } + .radius-item { + flex-basis: auto; + } + .radius-item, .color-item { min-width: 20em; margin: 5px 6px 0 0; - display:flex; + display: flex; flex-direction: column; flex: 1 1 0; &.wide { - min-width: 60% + min-width: 60%; } &:not(.wide):nth-child(2n+1) { margin-right: 7px; - } - .color, .opacity { - display:flex; + .color, + .opacity { + display: flex; align-items: baseline; } } - .radius-item { - flex-basis: auto; - } - .theme-radius-rn, .theme-color-cl { border: 0; @@ -295,14 +308,11 @@ .theme-radius-in { min-width: 1em; - } - - .theme-radius-in { max-width: 7em; flex: 1; } - .theme-radius-lb{ + .theme-radius-lb { max-width: 50em; } @@ -310,9 +320,16 @@ padding: 20px; } - .btn { - margin-left: .25em; - margin-right: .25em; + .theme-warning { + display: flex; + align-items: baseline; + margin-bottom: 0.5em; + + .buttons { + .btn { + margin-bottom: 0.5em; + } + } } } @@ -323,6 +340,7 @@ justify-content: space-around; flex-grow: 1; + /* stylelint-disable-next-line no-descending-specificity */ .btn { flex-grow: 1; min-height: 2em; diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue @@ -218,7 +218,8 @@ <script src="./shadow_control.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; + .shadow-control { display: flex; flex-wrap: wrap; @@ -229,6 +230,7 @@ .shadow-tweak { margin: 5px 6px 0 0; } + .shadow-preview-container { flex: 0; display: flex; @@ -236,19 +238,19 @@ $side: 15em; - input[type=number] { + input[type="number"] { width: 5em; min-width: 2em; } + .x-shift-control, .y-shift-control { display: flex; flex: 0; - &[disabled=disabled] *{ - opacity: .5 + &[disabled="disabled"] * { + opacity: 0.5; } - } .x-shift-control { @@ -256,37 +258,40 @@ } .x-shift-control .wrap, - input[type=range] { + input[type="range"] { margin: 0; width: $side; height: 2em; } + .y-shift-control { flex-direction: column; align-items: flex-end; + .wrap { width: 2em; height: $side; } - input[type=range] { + + input[type="range"] { transform-origin: 1em 1em; transform: rotate(90deg); } } + .preview-window { flex: 1; - background-color: #999999; + background-color: #999; display: flex; align-items: center; justify-content: center; background-image: - linear-gradient(45deg, #666666 25%, transparent 25%), - linear-gradient(-45deg, #666666 25%, transparent 25%), - linear-gradient(45deg, transparent 75%, #666666 75%), - linear-gradient(-45deg, transparent 75%, #666666 75%); + linear-gradient(45deg, #666 25%, transparent 25%), + linear-gradient(-45deg, #666 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, #666 75%), + linear-gradient(-45deg, transparent 75%, #666 75%); background-size: 20px 20px; - background-position:0 0, 0 10px, 10px -10px, -10px 0; - + background-position: 0 0, 0 10px, 10px -10px, -10px 0; border-radius: $fallback--inputRadius; border-radius: var(--inputRadius, $fallback--inputRadius); @@ -312,14 +317,15 @@ flex: 1; } - .shadow-switcher, .btn { + .shadow-switcher, + .btn { min-width: 1px; margin-right: 5px; } .btn { - padding: 0 .4em; - margin: 0 .1em; + padding: 0 0.4em; + margin: 0 0.1em; } } } diff --git a/src/components/shout_panel/shout_panel.vue b/src/components/shout_panel/shout_panel.vue @@ -75,7 +75,7 @@ <script src="./shout_panel.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .floating-shout { position: fixed; diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js @@ -2,6 +2,7 @@ import { mapState, mapGetters } from 'vuex' import UserCard from '../user_card/user_card.vue' import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils' import GestureService from '../../services/gesture_service/gesture_service' +import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faSignInAlt, @@ -14,7 +15,9 @@ import { faSearch, faTachometerAlt, faCog, - faInfoCircle + faInfoCircle, + faCompass, + faList } from '@fortawesome/free-solid-svg-icons' library.add( @@ -28,7 +31,9 @@ library.add( faSearch, faTachometerAlt, faCog, - faInfoCircle + faInfoCircle, + faCompass, + faList ) const SideDrawer = { @@ -78,15 +83,22 @@ const SideDrawer = { return this.$store.state.instance.federating }, timelinesRoute () { + let name if (this.$store.state.interface.lastTimeline) { - return this.$store.state.interface.lastTimeline + name = this.$store.state.interface.lastTimeline + } + name = this.currentUser ? 'friends' : 'public-timeline' + if (USERNAME_ROUTES.has(name)) { + return { name, params: { username: this.currentUser.screen_name } } + } else { + return { name } } - return this.currentUser ? 'friends' : 'public-timeline' }, ...mapState({ - pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable + pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable, + supportsAnnouncements: state => state.announcements.supportsAnnouncements }), - ...mapGetters(['unreadChatCount']) + ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']) }, methods: { toggleDrawer () { diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue @@ -47,7 +47,7 @@ v-if="currentUser || !privateMode" @click="toggleDrawer" > - <router-link :to="{ name: timelinesRoute }"> + <router-link :to="timelinesRoute"> <FAIcon fixed-width class="fa-scale-110 fa-old-padding" @@ -56,12 +56,24 @@ </router-link> </li> <li + v-if="currentUser" + @click="toggleDrawer" + > + <router-link :to="{ name: 'lists' }"> + <FAIcon + fixed-width + class="fa-scale-110 fa-old-padding" + icon="list" + /> {{ $t("nav.lists") }} + </router-link> + </li> + <li v-if="currentUser && pleromaChatMessagesAvailable" @click="toggleDrawer" > <router-link :to="{ name: 'chats', params: { username: currentUser.screen_name } }" - style="position: relative" + style="position: relative;" > <FAIcon fixed-width @@ -180,6 +192,38 @@ </a> </li> <li + v-if="currentUser && supportsAnnouncements" + @click="toggleDrawer" + > + <router-link + :to="{ name: 'announcements' }" + > + <FAIcon + fixed-width + class="fa-scale-110 fa-old-padding" + icon="bullhorn" + /> {{ $t("nav.announcements") }} + <span + v-if="unreadAnnouncementCount" + class="badge badge-notification" + > + {{ unreadAnnouncementCount }} + </span> + </router-link> + </li> + <li + v-if="currentUser" + @click="toggleDrawer" + > + <router-link :to="{ name: 'edit-navigation' }"> + <FAIcon + fixed-width + class="fa-scale-110 fa-old-padding" + icon="compass" + /> {{ $t("nav.edit_nav_mobile") }} + </router-link> + </li> + <li v-if="currentUser" @click="toggleDrawer" > @@ -207,7 +251,7 @@ <script src="./side_drawer.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .side-drawer-container { position: fixed; @@ -240,11 +284,11 @@ z-index: -1; transition: 0.35s; transition-property: background-color; - background-color: rgba(0, 0, 0, 0.5); + background-color: rgb(0 0 0 / 50%); } .side-drawer-darken-closed { - background-color: rgba(0, 0, 0, 0); + background-color: rgb(0 0 0 / 0%); } .side-drawer-click-outside { @@ -253,20 +297,21 @@ .side-drawer { overflow-x: hidden; - transition-timing-function: cubic-bezier(0, 1, 0.5, 1); transition: 0.35s; + transition-timing-function: cubic-bezier(0, 1, 0.5, 1); transition-property: transform; margin: 0 0 0 -100px; padding: 0 0 1em 100px; width: 80%; max-width: 20em; flex: 0 0 80%; - box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6); + box-shadow: 1px 1px 4px rgb(0 0 0 / 60%); box-shadow: var(--panelShadow); background-color: $fallback--bg; background-color: var(--popover, $fallback--bg); color: $fallback--link; color: var(--popoverText, $fallback--link); + --faint: var(--popoverFaintText, $fallback--faint); --faintLink: var(--popoverFaintLink, $fallback--faint); --lightText: var(--popoverLightText, $fallback--lightText); @@ -316,7 +361,6 @@ list-style: none; margin: 0; padding: 0; - border-bottom: 1px solid; border-color: $fallback--border; border-color: var(--border, $fallback--border); @@ -329,7 +373,8 @@ .side-drawer li { padding: 0; - a, button { + a, + button { box-sizing: border-box; display: block; height: 3em; @@ -341,6 +386,7 @@ background-color: var(--selectedMenuPopover, $fallback--lightBg); color: $fallback--text; color: var(--selectedMenuPopoverText, $fallback--text); + --faint: var(--selectedMenuPopoverFaintText, $fallback--faint); --faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint); --lightText: var(--selectedMenuPopoverLightText, $fallback--lightText); diff --git a/src/components/staff_panel/staff_panel.js b/src/components/staff_panel/staff_panel.js @@ -13,7 +13,7 @@ const StaffPanel = { }, computed: { groupedStaffAccounts () { - const staffAccounts = map(this.staffAccounts, this.findUser).filter(_ => _) + const staffAccounts = map(this.staffAccounts, this.findUserByName).filter(_ => _) const groupedStaffAccounts = groupBy(staffAccounts, 'role') return [ @@ -22,7 +22,7 @@ const StaffPanel = { ].filter(group => group.users) }, ...mapGetters([ - 'findUser' + 'findUserByName' ]), ...mapState({ staffAccounts: state => state.instance.staffAccounts diff --git a/src/components/staff_panel/staff_panel.vue b/src/components/staff_panel/staff_panel.vue @@ -27,7 +27,6 @@ <script src="./staff_panel.js"></script> <style lang="scss"> - .staff-group { padding-left: 1em; padding-top: 1em; diff --git a/src/components/status/status.js b/src/components/status/status.js @@ -13,6 +13,7 @@ import StatusPopover from '../status_popover/status_popover.vue' import UserPopover from '../user_popover/user_popover.vue' import UserListPopover from '../user_list_popover/user_list_popover.vue' import EmojiReactions from '../emoji_reactions/emoji_reactions.vue' +import UserLink from '../user_link/user_link.vue' import MentionsLine from 'src/components/mentions_line/mentions_line.vue' import MentionLink from 'src/components/mention_link/mention_link.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' @@ -115,7 +116,8 @@ const Status = { RichContent, MentionLink, MentionsLine, - UserPopover + UserPopover, + UserLink }, props: [ 'statusoid', @@ -393,6 +395,12 @@ const Status = { }, visibilityLocalized () { return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility) + }, + isEdited () { + return this.status.edited_at !== null + }, + editingAvailable () { + return this.$store.state.instance.editingAvailable } }, methods: { diff --git a/src/components/status/status.scss b/src/components/status/status.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .Status { min-width: 0; @@ -156,7 +156,8 @@ margin-right: 0.2em; } - & .heading-reply-row { + & .heading-reply-row, + & .heading-edited-row { position: relative; align-content: baseline; font-size: 0.85em; @@ -180,7 +181,7 @@ .reply-to-popover { .reply-to:hover::before { - content: ''; + content: ""; display: block; position: absolute; bottom: 0; @@ -196,7 +197,7 @@ &.-strikethrough { .reply-to::after { - content: ''; + content: ""; display: block; position: absolute; top: 50%; @@ -335,7 +336,7 @@ margin-left: 0.2em; &::before { - content: ' '; + content: " "; } } @@ -373,7 +374,7 @@ align-items: center; &::before { - content: ''; + content: ""; position: absolute; height: 100%; width: 1px; diff --git a/src/components/status/status.vue b/src/components/status/status.vue @@ -25,9 +25,10 @@ class="fa-scale-110 fa-old-padding repeat-icon" icon="retweet" /> - <router-link :to="userProfileLink"> - {{ status.user.screen_name_ui }} - </router-link> + <user-link + :user="status.user" + :at="false" + /> </small> <small v-if="showReasonMutedThread" @@ -83,7 +84,7 @@ :user="statusoid.user" /> <div class="right-side faint"> - <span + <bdi class="status-username repeater-name" :title="retweeter" > @@ -100,7 +101,7 @@ v-else :to="retweeterProfileLink" >{{ retweeter }}</router-link> - </span> + </bdi> {{ ' ' }} <FAIcon icon="retweet" @@ -164,13 +165,12 @@ > {{ status.user.name }} </h4> - <router-link + <user-link class="account-name" :title="status.user.screen_name_ui" - :to="userProfileLink" - > - {{ status.user.screen_name_ui }} - </router-link> + :user="status.user" + :at="false" + /> <img v-if="!!(status.user && status.user.favicon)" class="status-favicon" @@ -261,7 +261,7 @@ v-if="!isPreview" :status-id="status.parent_visible && status.in_reply_to_status_id" class="reply-to-popover" - style="min-width: 0" + style="min-width: 0;" :class="{ '-strikethrough': !status.parent_visible }" > <button @@ -327,6 +327,24 @@ class="mentions-line" /> </div> + <div + v-if="isEdited && editingAvailable && !isPreview" + class="heading-edited-row" + > + <i18n-t + keypath="status.edited_at" + tag="span" + > + <template #time> + <Timeago + template-key="time.in_past" + :time="status.edited_at" + :auto-update="60" + :long-format="true" + /> + </template> + </i18n-t> + </div> </div> <StatusContent diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .StatusBody { display: flex; @@ -40,7 +40,7 @@ .summary-wrapper { margin-bottom: 0.5em; border-style: solid; - border-width: 0 0 1px 0; + border-width: 0 0 1px; border-color: var(--border, $fallback--border); flex-grow: 0; @@ -58,8 +58,7 @@ .text-wrapper { display: flex; - flex-direction: column; - flex-wrap: nowrap; + flex-flow: column nowrap; &.-tall-status { position: relative; @@ -75,7 +74,7 @@ linear-gradient(to top, white, white); /* Autoprefixed seem to ignore this one, and also syntax is different */ - -webkit-mask-composite: xor; + mask-composite: xor; mask-composite: exclude; } } @@ -144,7 +143,7 @@ mask-image: linear-gradient(to bottom, white 2em, transparent 3em); /* Autoprefixed seem to ignore this one, and also syntax is different */ - -webkit-mask-composite: xor; + mask-composite: xor; mask-composite: exclude; } @@ -158,7 +157,7 @@ .summary-wrapper { .summary::after { - content: ': '; + content: ": "; } line-height: inherit; diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue @@ -33,6 +33,7 @@ <gallery v-if="status.attachments.length !== 0" class="attachments media-body" + :compact="compact" :nsfw="nsfwClickthrough" :attachments="status.attachments" :limit="compact ? 1 : 0" diff --git a/src/components/status_history_modal/status_history_modal.js b/src/components/status_history_modal/status_history_modal.js @@ -0,0 +1,60 @@ +import { get } from 'lodash' +import Modal from '../modal/modal.vue' +import Status from '../status/status.vue' + +const StatusHistoryModal = { + components: { + Modal, + Status + }, + data () { + return { + statuses: [] + } + }, + computed: { + modalActivated () { + return this.$store.state.statusHistory.modalActivated + }, + params () { + return this.$store.state.statusHistory.params + }, + statusId () { + return this.params.id + }, + historyCount () { + return this.statuses.length + }, + history () { + return this.statuses + } + }, + watch: { + params (newVal, oldVal) { + const newStatusId = get(newVal, 'id') !== get(oldVal, 'id') + if (newStatusId) { + this.resetHistory() + } + + if (newStatusId || get(newVal, 'edited_at') !== get(oldVal, 'edited_at')) { + this.fetchStatusHistory() + } + } + }, + methods: { + resetHistory () { + this.statuses = [] + }, + fetchStatusHistory () { + this.$store.dispatch('fetchStatusHistory', this.params) + .then(data => { + this.statuses = data + }) + }, + closeModal () { + this.$store.dispatch('closeStatusHistoryModal') + } + } +} + +export default StatusHistoryModal diff --git a/src/components/status_history_modal/status_history_modal.vue b/src/components/status_history_modal/status_history_modal.vue @@ -0,0 +1,47 @@ +<template> + <Modal + v-if="modalActivated" + class="status-history-modal-view" + @backdropClicked="closeModal" + > + <div class="status-history-modal-panel panel"> + <div class="panel-heading"> + {{ $t('status.status_history') }} ({{ historyCount }}) + </div> + <div class="panel-body"> + <div + v-if="historyCount > 0" + class="history-body" + > + <status + v-for="status in history" + :key="status.id" + :statusoid="status" + :is-preview="true" + class="conversation-status status-fadein panel-body" + /> + </div> + </div> + </div> + </Modal> +</template> + +<script src="./status_history_modal.js"></script> + +<style lang="scss"> +.modal-view.status-history-modal-view { + align-items: flex-start; +} + +.status-history-modal-panel { + flex-shrink: 0; + margin-top: 25%; + margin-bottom: 2em; + width: 100%; + max-width: 700px; + + @media (orientation: landscape) { + margin-top: 8%; + } +} +</style> diff --git a/src/components/status_popover/status_popover.vue b/src/components/status_popover/status_popover.vue @@ -40,14 +40,13 @@ <script src="./status_popover.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; /* popover styles load on-demand, so we need to override */ .status-popover.popover { font-size: 1rem; min-width: 15em; max-width: 95%; - border-color: $fallback--border; border-color: var(--border, $fallback--border); border-style: solid; diff --git a/src/components/sticker_picker/sticker_picker.vue b/src/components/sticker_picker/sticker_picker.vue @@ -32,24 +32,29 @@ <script src="./sticker_picker.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .sticker-picker { width: 100%; + .contents { min-height: 250px; + .sticker-picker-content { display: flex; flex-wrap: wrap; padding: 0 4px; + .sticker { display: flex; flex: 1 1 auto; margin: 4px; width: 56px; height: 56px; + img { height: 100%; + &:hover { filter: drop-shadow(0 0 5px var(--accent, $fallback--link)); } diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js @@ -7,16 +7,24 @@ const StillImage = { 'imageLoadHandler', 'alt', 'height', - 'width' + 'width', + 'dataSrc', + 'loading' ], data () { return { + // for lazy loading, see loadLazy() + realSrc: this.src, stopGifs: this.$store.getters.mergedConfig.stopGifs } }, computed: { animated () { - return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif')) + if (!this.realSrc) { + return false + } + + return this.stopGifs && (this.mimetype === 'image/gif' || this.realSrc.endsWith('.gif')) }, style () { const appendPx = (str) => /\d$/.test(str) ? str + 'px' : str @@ -27,7 +35,15 @@ const StillImage = { } }, methods: { + loadLazy () { + if (this.dataSrc) { + this.realSrc = this.dataSrc + } + }, onLoad () { + if (!this.realSrc) { + return + } const image = this.$refs.src if (!image) return this.imageLoadHandler && this.imageLoadHandler(image) @@ -42,6 +58,14 @@ const StillImage = { onError () { this.imageLoadError && this.imageLoadError() } + }, + watch: { + src () { + this.realSrc = this.src + }, + dataSrc () { + this.$el.removeAttribute('data-loaded') + } } } diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue @@ -11,11 +11,13 @@ <!-- NOTE: key is required to force to re-render img tag when src is changed --> <img ref="src" - :key="src" + :key="realSrc" :alt="alt" :title="alt" - :src="src" + :data-src="dataSrc" + :src="realSrc" :referrerpolicy="referrerpolicy" + :loading="loading" @load="onLoad" @error="onError" > @@ -26,7 +28,7 @@ <script src="./still-image.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .still-image { position: relative; @@ -56,13 +58,13 @@ &.animated { &::before { zoom: var(--_still_image-label-scale, 1); - content: 'gif'; + content: "gif"; position: absolute; line-height: 1; font-size: 0.7em; top: 0.5em; left: 0.5em; - background: rgba(127, 127, 127, 0.5); + background: rgb(127 127 127 / 50%); color: #fff; display: block; padding: 2px 4px; diff --git a/src/components/swipe_click/swipe_click.js b/src/components/swipe_click/swipe_click.js @@ -5,6 +5,8 @@ import GestureService from '../../services/gesture_service/gesture_service' * direction: a vector that indicates the direction of the intended swipe * threshold: the minimum distance in pixels the swipe has moved on `direction' * for swipe-finished() to have a non-zero sign + * disableClickThreshold: the minimum distance in pixels for the swipe to + * not trigger a click * perpendicularTolerance: see gesture_service * * Events: @@ -34,6 +36,10 @@ const SwipeClick = { type: Function, default: () => 30 }, + disableClickThreshold: { + type: Function, + default: () => 1 + }, perpendicularTolerance: { type: Number, default: 1.0 @@ -72,6 +78,7 @@ const SwipeClick = { this.$gesture = new GestureService.SwipeAndClickGesture({ direction: this.direction, threshold: this.threshold, + disableClickThreshold: this.disableClickThreshold, perpendicularTolerance: this.perpendicularTolerance, swipePreviewCallback: this.preview, swipeEndCallback: this.end, diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss @@ -1,5 +1,6 @@ -@import '../../_variables.scss'; +@import "../../variables"; +/* stylelint-disable no-descending-specificity */ .tab-switcher { display: flex; @@ -17,9 +18,11 @@ overflow-x: auto; padding-top: 5px; flex-direction: row; + flex: 0 0 auto; - &::after, &::before { - content: ''; + &::after, + &::before { + content: ""; flex: 1 1 auto; border-bottom: 1px solid; border-bottom-color: $fallback--border; @@ -38,6 +41,7 @@ border-bottom-color: var(--border, $fallback--border); } } + .tab { width: 100%; min-width: 1px; @@ -47,6 +51,7 @@ margin-bottom: 6px - 99px; } } + .contents.scrollable-tabs { flex-basis: 0; } @@ -69,10 +74,11 @@ overflow-x: hidden; flex-direction: column; - &::after, &::before { + &::after, + &::before { flex-shrink: 0; - flex-basis: .5em; - content: ''; + flex-basis: 0.5em; + content: ""; border-right: 1px solid; border-right-color: $fallback--border; border-right-color: var(--border, $fallback--border); @@ -106,7 +112,7 @@ &::before { flex: 0 0 6px; - content: ''; + content: ""; border-right: 1px solid; border-right-color: $fallback--border; border-right-color: var(--border, $fallback--border); @@ -130,12 +136,13 @@ margin-left: 1em; @media all and (max-width: 800px) { - padding-left: .25em; - padding-right: calc(.25em + 200px); - margin-right: calc(.25em - 200px); - margin-left: .25em; + padding-left: 0.25em; + padding-right: calc(0.25em + 200px); + margin-right: calc(0.25em - 200px); + margin-left: 0.25em; + .text { - display: none + display: none; } } } @@ -144,15 +151,17 @@ .contents { flex: 1 0 auto; - min-height: 0px; + min-height: 0; .hidden { display: none; } + .full-height:not(.hidden) { height: 100%; display: flex; flex-direction: column; + > *:not(.mobile-label) { flex: 1; } @@ -195,7 +204,8 @@ position: relative; box-sizing: border-box; - &::after, &::before { + &::after, + &::before { display: block; flex: 1 1 auto; } @@ -208,7 +218,7 @@ &:not(.active) { &::after { - content: ''; + content: ""; position: absolute; z-index: 7; } @@ -216,11 +226,11 @@ } .mobile-label { - padding-left: .3em; - padding-bottom: .25em; - margin-top: .5em; - margin-left: .2em; - margin-bottom: .25em; + padding-left: 0.3em; + padding-bottom: 0.25em; + margin-top: 0.5em; + margin-left: 0.2em; + margin-bottom: 0.25em; border-bottom: 1px solid var(--border, $fallback--border); @media all and (min-width: 800px) { @@ -228,3 +238,4 @@ } } } +/* stylelint-enable no-descending-specificity */ diff --git a/src/components/terms_of_service_panel/terms_of_service_panel.vue b/src/components/terms_of_service_panel/terms_of_service_panel.vue @@ -17,6 +17,6 @@ <style lang="scss"> .tos-content { - margin: 1em + margin: 1em; } </style> diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue @@ -1,5 +1,5 @@ <template> - <div class="thread-tree"> + <article class="thread-tree"> <status :key="status.id" ref="statusComponent" @@ -113,13 +113,14 @@ </template> </i18n-t> </div> - </div> + </article> </template> <script src="./thread_tree.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; + .thread-tree-replies { margin-left: var(--status-margin, $status-margin); border-left: 2px solid var(--border, $fallback--border); @@ -127,6 +128,7 @@ .thread-tree-replies-hidden { padding: var(--status-margin, $status-margin); + /* Make the button stretch along the whole row */ display: flex; align-items: stretch; diff --git a/src/components/timeago/timeago.vue b/src/components/timeago/timeago.vue @@ -3,7 +3,7 @@ :datetime="time" :title="localeDateString" > - {{ $tc(relativeTime.key, relativeTime.num, [relativeTime.num]) }} + {{ relativeTimeString }} </time> </template> @@ -13,7 +13,7 @@ import localeService from 'src/services/locale/locale.service.js' export default { name: 'Timeago', - props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold'], + props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold', 'templateKey'], data () { return { relativeTime: { key: 'time.now', num: 0 }, @@ -26,6 +26,23 @@ export default { return typeof this.time === 'string' ? new Date(Date.parse(this.time)).toLocaleString(browserLocale) : this.time.toLocaleString(browserLocale) + }, + relativeTimeString () { + const timeString = this.$i18n.tc(this.relativeTime.key, this.relativeTime.num, [this.relativeTime.num]) + + if (typeof this.templateKey === 'string' && this.relativeTime.key !== 'time.now') { + return this.$i18n.t(this.templateKey, [timeString]) + } + + return timeString + } + }, + watch: { + time (newVal, oldVal) { + if (oldVal !== newVal) { + clearTimeout(this.interval) + this.refreshRelativeTimeObject() + } } }, created () { diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js @@ -1,15 +1,21 @@ import Status from '../status/status.vue' +import { mapState } from 'vuex' import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js' import Conversation from '../conversation/conversation.vue' import TimelineMenu from '../timeline_menu/timeline_menu.vue' -import TimelineQuickSettings from './timeline_quick_settings.vue' +import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.vue' +import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue' import { debounce, throttle, keyBy } from 'lodash' import { library } from '@fortawesome/fontawesome-svg-core' -import { faCircleNotch, faCog } from '@fortawesome/free-solid-svg-icons' +import { faCircleNotch, faCirclePlus, faCog, faMinus, faArrowUp, faCheck } from '@fortawesome/free-solid-svg-icons' library.add( faCircleNotch, - faCog + faCog, + faMinus, + faArrowUp, + faCirclePlus, + faCheck ) const Timeline = { @@ -18,6 +24,7 @@ const Timeline = { 'timelineName', 'title', 'userId', + 'listId', 'tag', 'embedded', 'count', @@ -27,6 +34,7 @@ const Timeline = { ], data () { return { + showScrollTop: false, paused: false, unfocused: false, bottomedOut: false, @@ -38,7 +46,8 @@ const Timeline = { Status, Conversation, TimelineMenu, - TimelineQuickSettings + QuickFilterSettings, + QuickViewSettings }, computed: { filteredVisibleStatuses () { @@ -60,6 +69,13 @@ const Timeline = { return `${this.$t('timeline.show_new')} (${this.newStatusCount})` } }, + mobileLoadButtonString () { + if (this.timeline.flushMarker !== 0) { + return '+' + } else { + return this.newStatusCount > 99 ? '∞' : this.newStatusCount + } + }, classes () { let rootClasses = !this.embedded ? ['panel', 'panel-default'] : ['-nonpanel'] if (this.blockingClicks) rootClasses = rootClasses.concat(['-blocked', '_misclick-prevention']) @@ -84,7 +100,10 @@ const Timeline = { }, virtualScrollingEnabled () { return this.$store.getters.mergedConfig.virtualScrolling - } + }, + ...mapState({ + mobileLayout: state => state.interface.layoutType === 'mobile' + }) }, created () { const store = this.$store @@ -101,6 +120,7 @@ const Timeline = { timeline: this.timelineName, showImmediately, userId: this.userId, + listId: this.listId, tag: this.tag }) }, @@ -119,6 +139,9 @@ const Timeline = { this.$store.commit('setLoading', { timeline: this.timelineName, value: false }) }, methods: { + scrollToTop () { + window.scrollTo({ top: this.$el.offsetTop }) + }, stopBlockingClicks: debounce(function () { this.blockingClicks = false }, 1000), @@ -156,6 +179,7 @@ const Timeline = { older: true, showImmediately: true, userId: this.userId, + listId: this.listId, tag: this.tag }).then(({ statuses }) => { if (statuses && statuses.length === 0) { @@ -217,6 +241,7 @@ const Timeline = { } }, handleScroll: throttle(function (e) { + this.showScrollTop = this.$el.offsetTop < window.scrollY this.determineVisibleStatuses() this.scrollLoad(e) }, 200), diff --git a/src/components/timeline/timeline.scss b/src/components/timeline/timeline.scss @@ -1,8 +1,35 @@ -@import '../../_variables.scss'; +@import "../../variables"; .Timeline { - .loadmore-text { - opacity: 1; + .alert-dot { + border-radius: 100%; + height: 8px; + width: 8px; + position: absolute; + left: calc(50% - 4px); + top: calc(50% - 4px); + margin-left: 6px; + margin-top: -6px; + background-color: var(--badgeNeutral); + } + + .alert-badge { + font-size: 0.75em; + line-height: 1; + text-align: right; + border-radius: var(--tooltipRadius); + position: absolute; + left: calc(50% - 0.5em); + top: calc(50% - 0.4em); + padding: 0.2em; + margin-left: 0.7em; + margin-top: -1em; + background-color: var(--badgeNeutral); + color: var(--badgeNeutralText); + } + + .loadmore-button { + position: relative; } &.-blocked { @@ -19,10 +46,9 @@ text-align: center; line-height: 2.75em; padding: 0 0.5em; - } - .timeline-heading { - .button-default, .alert { + .button-default, + .alert { line-height: 2em; width: 100%; } diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue @@ -1,31 +1,96 @@ <template> <div :class="['Timeline', classes.root]"> <div :class="classes.header"> - <TimelineMenu v-if="!embedded" /> - <button - v-if="showLoadButton" - class="button-default loadmore-button" - @click.prevent="showNewStatuses" - > - {{ loadButtonString }} - </button> + <TimelineMenu + v-if="!embedded" + :timeline-name="timelineName" + /> <div - v-else-if="!embedded" - class="loadmore-text faint" - @click.prevent + v-if="showScrollTop && !embedded" + class="rightside-button" > - {{ $t('timeline.up_to_date') }} + <button + class="button-unstyled scroll-to-top-button" + type="button" + :title="$t('general.scroll_to_top')" + @click="scrollToTop" + > + <FALayers class="fa-scale-110 fa-old-padding-layer"> + <FAIcon icon="arrow-up" /> + <FAIcon + icon="minus" + transform="up-7" + /> + </FALayers> + </button> </div> - <TimelineQuickSettings v-if="!embedded" /> + <template v-if="mobileLayout && !embedded"> + <div + v-if="showLoadButton" + class="rightside-button" + > + <button + class="button-unstyled loadmore-button" + :title="loadButtonString" + @click.prevent="showNewStatuses" + > + <FAIcon + fixed-width + icon="circle-plus" + /> + <div class="alert-badge"> + {{ mobileLoadButtonString }} + </div> + </button> + </div> + <div + v-else-if="!embedded" + class="loadmore-text faint veryfaint rightside-icon" + :title="$t('timeline.up_to_date')" + :aria-disabled="true" + @click.prevent + > + <FAIcon + fixed-width + icon="check" + /> + </div> + </template> + <template v-else> + <button + v-if="showLoadButton" + class="button-default loadmore-button" + @click.prevent="showNewStatuses" + > + {{ loadButtonString }} + </button> + <div + v-else-if="!embedded" + class="loadmore-text faint" + @click.prevent + > + {{ $t('timeline.up_to_date') }} + </div> + </template> + <QuickFilterSettings + v-if="!embedded" + class="rightside-button" + /> + <QuickViewSettings + v-if="!embedded" + class="rightside-button" + /> </div> <div :class="classes.body"> <div ref="timeline" class="timeline" + role="feed" > <conversation v-for="statusId in filteredPinnedStatusIds" :key="statusId + '-pinned'" + role="listitem" class="status-fadein" :status-id="statusId" :collapsable="true" @@ -36,6 +101,7 @@ <conversation v-for="status in filteredVisibleStatuses" :key="status.id" + role="listitem" class="status-fadein" :status-id="status.id" :collapsable="true" diff --git a/src/components/timeline/timeline_quick_settings.js b/src/components/timeline/timeline_quick_settings.js @@ -1,67 +0,0 @@ -import Popover from '../popover/popover.vue' -import { mapGetters } from 'vuex' -import { library } from '@fortawesome/fontawesome-svg-core' -import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons' - -library.add( - faFilter, - faFont, - faWrench -) - -const TimelineQuickSettings = { - components: { - Popover - }, - methods: { - setReplyVisibility (visibility) { - this.$store.dispatch('setOption', { name: 'replyVisibility', value: visibility }) - this.$store.dispatch('queueFlushAll') - }, - openTab (tab) { - this.$store.dispatch('openSettingsModalTab', tab) - } - }, - computed: { - ...mapGetters(['mergedConfig']), - loggedIn () { - return !!this.$store.state.users.currentUser - }, - replyVisibilitySelf: { - get () { return this.mergedConfig.replyVisibility === 'self' }, - set () { this.setReplyVisibility('self') } - }, - replyVisibilityFollowing: { - get () { return this.mergedConfig.replyVisibility === 'following' }, - set () { this.setReplyVisibility('following') } - }, - replyVisibilityAll: { - get () { return this.mergedConfig.replyVisibility === 'all' }, - set () { this.setReplyVisibility('all') } - }, - hideMedia: { - get () { return this.mergedConfig.hideAttachments || this.mergedConfig.hideAttachmentsInConv }, - set () { - const value = !this.hideMedia - this.$store.dispatch('setOption', { name: 'hideAttachments', value }) - this.$store.dispatch('setOption', { name: 'hideAttachmentsInConv', value }) - } - }, - hideMutedPosts: { - get () { return this.mergedConfig.hideFilteredStatuses }, - set () { - const value = !this.hideMutedPosts - this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value }) - } - }, - muteBotStatuses: { - get () { return this.mergedConfig.muteBotStatuses }, - set () { - const value = !this.muteBotStatuses - this.$store.dispatch('setOption', { name: 'muteBotStatuses', value }) - } - } - } -} - -export default TimelineQuickSettings diff --git a/src/components/timeline/timeline_quick_settings.vue b/src/components/timeline/timeline_quick_settings.vue @@ -1,109 +0,0 @@ -<template> - <Popover - trigger="click" - class="TimelineQuickSettings" - :bound-to="{ x: 'container' }" - > - <template #content> - <div class="dropdown-menu"> - <div v-if="loggedIn"> - <button - class="button-default dropdown-item" - @click="replyVisibilityAll = true" - > - <span - class="menu-checkbox -radio" - :class="{ 'menu-checkbox-checked': replyVisibilityAll }" - />{{ $t('settings.reply_visibility_all') }} - </button> - <button - class="button-default dropdown-item" - @click="replyVisibilityFollowing = true" - > - <span - class="menu-checkbox -radio" - :class="{ 'menu-checkbox-checked': replyVisibilityFollowing }" - />{{ $t('settings.reply_visibility_following_short') }} - </button> - <button - class="button-default dropdown-item" - @click="replyVisibilitySelf = true" - > - <span - class="menu-checkbox -radio" - :class="{ 'menu-checkbox-checked': replyVisibilitySelf }" - />{{ $t('settings.reply_visibility_self_short') }} - </button> - <div - role="separator" - class="dropdown-divider" - /> - </div> - <button - class="button-default dropdown-item" - @click="muteBotStatuses = !muteBotStatuses" - > - <span - class="menu-checkbox" - :class="{ 'menu-checkbox-checked': muteBotStatuses }" - />{{ $t('settings.mute_bot_posts') }} - </button> - <button - class="button-default dropdown-item" - @click="hideMedia = !hideMedia" - > - <span - class="menu-checkbox" - :class="{ 'menu-checkbox-checked': hideMedia }" - />{{ $t('settings.hide_media_previews') }} - </button> - <button - class="button-default dropdown-item" - @click="hideMutedPosts = !hideMutedPosts" - > - <span - class="menu-checkbox" - :class="{ 'menu-checkbox-checked': hideMutedPosts }" - />{{ $t('settings.hide_all_muted_posts') }} - </button> - <button - class="button-default dropdown-item dropdown-item-icon" - @click="openTab('filtering')" - > - <FAIcon icon="font" />{{ $t('settings.word_filter') }} - </button> - <button - class="button-default dropdown-item dropdown-item-icon" - @click="openTab('general')" - > - <FAIcon icon="wrench" />{{ $t('settings.more_settings') }} - </button> - </div> - </template> - <template #trigger> - <button class="button-unstyled"> - <FAIcon icon="filter" /> - </button> - </template> - </Popover> -</template> - -<script src="./timeline_quick_settings.js"></script> - -<style lang="scss"> - -.TimelineQuickSettings { - - > button { - line-height: 100%; - height: 100%; - width: var(--__panel-heading-height-inner); - text-align: center; - - svg { - font-size: 1.2em; - } - } -} - -</style> diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js @@ -1,6 +1,10 @@ import Popover from '../popover/popover.vue' -import TimelineMenuContent from './timeline_menu_content.vue' +import NavigationEntry from 'src/components/navigation/navigation_entry.vue' +import { mapState } from 'vuex' +import { ListsMenuContent } from '../lists_menu/lists_menu_content.vue' import { library } from '@fortawesome/fontawesome-svg-core' +import { TIMELINES } from 'src/components/navigation/navigation.js' +import { filterNavigation } from 'src/components/navigation/filter.js' import { faChevronDown } from '@fortawesome/free-solid-svg-icons' @@ -22,7 +26,8 @@ export const timelineNames = () => { const TimelineMenu = { components: { Popover, - TimelineMenuContent + NavigationEntry, + ListsMenuContent }, data () { return { @@ -34,6 +39,28 @@ const TimelineMenu = { this.$store.dispatch('setLastTimeline', this.$route.name) } }, + computed: { + useListsMenu () { + const route = this.$route.name + return route === 'lists-timeline' + }, + ...mapState({ + currentUser: state => state.users.currentUser, + privateMode: state => state.instance.private, + federating: state => state.instance.federating + }), + timelinesList () { + return filterNavigation( + Object.entries(TIMELINES).map(([k, v]) => ({ ...v, name: k })), + { + hasChats: this.pleromaChatMessagesAvailable, + isFederating: this.federating, + isPrivate: this.privateMode, + currentUser: this.currentUser + } + ) + } + }, methods: { openMenu () { // $nextTick is too fast, animation won't play back but @@ -58,6 +85,9 @@ const TimelineMenu = { if (route === 'tag-timeline') { return '#' + this.$route.params.tag } + if (route === 'lists-timeline') { + return this.$store.getters.findListTitle(this.$route.params.id) + } const i18nkey = timelineNames()[this.$route.name] return i18nkey ? this.$t(i18nkey) : route } diff --git a/src/components/timeline_menu/timeline_menu.vue b/src/components/timeline_menu/timeline_menu.vue @@ -10,7 +10,19 @@ @close="() => isOpen = false" > <template #content> - <TimelineMenuContent /> + <ListsMenuContent + v-if="useListsMenu" + :show-pin="false" + class="timelines" + /> + <ul v-else> + <NavigationEntry + v-for="item in timelinesList" + :key="item.name" + :show-pin="false" + :item="item" + /> + </ul> </template> <template #trigger> <span class="button-unstyled title timeline-menu-title"> @@ -33,56 +45,7 @@ <script src="./timeline_menu.js"></script> <style lang="scss"> -@import '../../_variables.scss'; - -.TimelineMenu { - margin-right: auto; - min-width: 0; - - .popover-trigger-button { - vertical-align: bottom; - } - - .panel::after { - border-top-right-radius: 0; - border-top-left-radius: 0; - } - - .timeline-menu-title { - margin: 0; - cursor: pointer; - user-select: none; - width: 100%; - display: flex; - - .timeline-menu-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - svg { - margin-left: 0.6em; - transition: transform 100ms; - } - - .click-blocker { - cursor: default; - flex-grow: 1; - } - } - - &.open .timeline-menu-title svg { - color: $fallback--text; - color: var(--panelText, $fallback--text); - transform: rotate(180deg); - } - - .panel { - box-shadow: var(--popoverShadow); - } - -} +@import "../../variables"; .timeline-menu-popover { min-width: 24rem; @@ -98,24 +61,6 @@ padding: 0; } - li { - border-bottom: 1px solid; - border-color: $fallback--border; - border-color: var(--border, $fallback--border); - padding: 0; - - &:last-child a { - border-bottom-right-radius: $fallback--panelRadius; - border-bottom-right-radius: var(--panelRadius, $fallback--panelRadius); - border-bottom-left-radius: $fallback--panelRadius; - border-bottom-left-radius: var(--panelRadius, $fallback--panelRadius); - } - - &:last-child { - border: none; - } - } - a { display: block; padding: 0 0.65em; @@ -127,6 +72,7 @@ background-color: var(--selectedMenu, $fallback--lightBg); color: $fallback--link; color: var(--selectedMenuText, $fallback--link); + --faint: var(--selectedMenuFaintText, $fallback--faint); --faintLink: var(--selectedMenuFaintLink, $fallback--faint); --lightText: var(--selectedMenuLightText, $fallback--lightText); @@ -139,6 +85,7 @@ background-color: var(--selectedMenu, $fallback--lightBg); color: $fallback--text; color: var(--selectedMenuText, $fallback--text); + --faint: var(--selectedMenuFaintText, $fallback--faint); --faintLink: var(--selectedMenuFaintLink, $fallback--faint); --lightText: var(--selectedMenuLightText, $fallback--lightText); @@ -154,6 +101,71 @@ margin-left: -0.2em; } } + + li { + border-bottom: 1px solid; + border-color: $fallback--border; + border-color: var(--border, $fallback--border); + padding: 0; + + &:last-child a { + border-bottom-right-radius: $fallback--panelRadius; + border-bottom-right-radius: var(--panelRadius, $fallback--panelRadius); + border-bottom-left-radius: $fallback--panelRadius; + border-bottom-left-radius: var(--panelRadius, $fallback--panelRadius); + } + + &:last-child { + border: none; + } + } } +.TimelineMenu { + margin-right: auto; + min-width: 0; + + .popover-trigger-button { + vertical-align: bottom; + } + + .panel::after { + border-top-right-radius: 0; + border-top-left-radius: 0; + } + + .timeline-menu-title { + margin: 0; + cursor: pointer; + user-select: none; + width: 100%; + display: flex; + + .timeline-menu-name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + svg { + margin-left: 0.6em; + transition: transform 100ms; + } + + .click-blocker { + cursor: default; + flex-grow: 1; + } + } + + &.open .timeline-menu-title svg { + color: $fallback--text; + color: var(--panelText, $fallback--text); + transform: rotate(180deg); + } + + .panel { + box-shadow: var(--popoverShadow); + } +} </style> diff --git a/src/components/timeline_menu/timeline_menu_content.js b/src/components/timeline_menu/timeline_menu_content.js @@ -1,29 +0,0 @@ -import { mapState } from 'vuex' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faUsers, - faGlobe, - faBookmark, - faEnvelope, - faHome -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faUsers, - faGlobe, - faBookmark, - faEnvelope, - faHome -) - -const TimelineMenuContent = { - computed: { - ...mapState({ - currentUser: state => state.users.currentUser, - privateMode: state => state.instance.private, - federating: state => state.instance.federating - }) - } -} - -export default TimelineMenuContent diff --git a/src/components/timeline_menu/timeline_menu_content.vue b/src/components/timeline_menu/timeline_menu_content.vue @@ -1,66 +0,0 @@ -<template> - <ul> - <li v-if="currentUser"> - <router-link - class="menu-item" - :to="{ name: 'friends' }" - > - <FAIcon - fixed-width - class="fa-scale-110 fa-old-padding " - icon="home" - />{{ $t("nav.home_timeline") }} - </router-link> - </li> - <li v-if="currentUser || !privateMode"> - <router-link - class="menu-item" - :to="{ name: 'public-timeline' }" - > - <FAIcon - fixed-width - class="fa-scale-110 fa-old-padding " - icon="users" - />{{ $t("nav.public_tl") }} - </router-link> - </li> - <li v-if="federating && (currentUser || !privateMode)"> - <router-link - class="menu-item" - :to="{ name: 'public-external-timeline' }" - > - <FAIcon - fixed-width - class="fa-scale-110 fa-old-padding " - icon="globe" - />{{ $t("nav.twkn") }} - </router-link> - </li> - <li v-if="currentUser"> - <router-link - class="menu-item" - :to="{ name: 'bookmarks'}" - > - <FAIcon - fixed-width - class="fa-scale-110 fa-old-padding " - icon="bookmark" - />{{ $t("nav.bookmarks") }} - </router-link> - </li> - <li v-if="currentUser"> - <router-link - class="menu-item" - :to="{ name: 'dms', params: { username: currentUser.screen_name } }" - > - <FAIcon - fixed-width - class="fa-scale-110 fa-old-padding " - icon="envelope" - />{{ $t("nav.dms") }} - </router-link> - </li> - </ul> -</template> - -<script src="./timeline_menu_content.js"></script> diff --git a/src/components/unicode_domain_indicator/unicode_domain_indicator.vue b/src/components/unicode_domain_indicator/unicode_domain_indicator.vue @@ -0,0 +1,26 @@ +<template> + <FAIcon + v-if="user && user.screen_name_ui_contains_non_ascii" + icon="code" + :title="$t('unicode_domain_indicator.tooltip')" + /> +</template> + +<script> +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faCode +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faCode +) + +const UnicodeDomainIndicator = { + props: { + user: Object + } +} + +export default UnicodeDomainIndicator +</script> diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js @@ -0,0 +1,69 @@ +import Modal from 'src/components/modal/modal.vue' +import { library } from '@fortawesome/fontawesome-svg-core' +import pleromaTan from 'src/assets/pleromatan_apology.png' +import pleromaTanFox from 'src/assets/pleromatan_apology_fox.png' +import pleromaTanMask from 'src/assets/pleromatan_apology_mask.png' +import pleromaTanFoxMask from 'src/assets/pleromatan_apology_fox_mask.png' + +import { + faTimes +} from '@fortawesome/free-solid-svg-icons' +library.add( + faTimes +) + +export const CURRENT_UPDATE_COUNTER = 1 + +const UpdateNotification = { + data () { + return { + showingImage: false, + pleromaTanVariant: Math.random() > 0.5 ? pleromaTan : pleromaTanFox, + showingMore: false + } + }, + components: { + Modal + }, + computed: { + pleromaTanStyles () { + const mask = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask + return { + 'shape-outside': 'url(' + mask + ')' + } + }, + shouldShow () { + return !this.$store.state.instance.disableUpdateNotification && + this.$store.state.users.currentUser && + this.$store.state.serverSideStorage.flagStorage.updateCounter < CURRENT_UPDATE_COUNTER && + !this.$store.state.serverSideStorage.prefsStorage.simple.dontShowUpdateNotifs + } + }, + methods: { + toggleShow () { + this.showingMore = !this.showingMore + }, + neverShowAgain () { + this.toggleShow() + this.$store.commit('setFlag', { flag: 'updateCounter', value: CURRENT_UPDATE_COUNTER }) + this.$store.commit('setPreference', { path: 'simple.dontShowUpdateNotifs', value: true }) + this.$store.dispatch('pushServerSideStorage') + }, + dismiss () { + this.$store.commit('setFlag', { flag: 'updateCounter', value: CURRENT_UPDATE_COUNTER }) + this.$store.dispatch('pushServerSideStorage') + } + }, + mounted () { + this.contentHeightNoImage = this.$refs.animatedText.scrollHeight + + // Workaround to get the text height only after mask loaded. A bit hacky. + const newImg = new Image() + newImg.onload = () => { + setTimeout(() => { this.showingImage = true }, 100) + } + newImg.src = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask + } +} + +export default UpdateNotification diff --git a/src/components/update_notification/update_notification.scss b/src/components/update_notification/update_notification.scss @@ -0,0 +1,115 @@ +@import "src/variables"; + +.UpdateNotification { + overflow: hidden; +} + +.UpdateNotificationModal { + --__top-fringe: 15em; // how much pleroma-tan should stick her head above + --__bottom-fringe: 80em; // just reserving as much as we can, number is mostly irrelevant + --__right-fringe: 8em; + + font-size: 15px; + position: relative; + transition: transform; + transition-timing-function: ease-in-out; + transition-duration: 500ms; + + .text { + max-width: 40em; + padding-left: 1em; + } + + @media all and (max-width: 800px) { + /* For mobile, the modal takes 100% of the available screen. + This ensures the minimized modal is always 50px above the browser + bottom bar regardless of whether or not it is visible. + */ + width: 100vw; + } + + @media all and (max-height: 600px) { + display: none; + } + + .content { + overflow: hidden; + margin-top: calc(-1 * var(--__top-fringe)); + margin-bottom: calc(-1 * var(--__bottom-fringe)); + margin-right: calc(-1 * var(--__right-fringe)); + + &.-noImage { + .text { + padding-right: var(--__right-fringe); + } + } + } + + .panel-body { + border-width: 0 0 1px; + border-style: solid; + border-color: var(--border, $fallback--border); + } + + .panel-footer { + z-index: 22; + position: relative; + border-width: 0; + grid-template-columns: auto; + } + + .pleroma-tan { + object-fit: cover; + object-position: top; + transition: position, left, right, top, bottom, max-width, max-height; + transition-timing-function: ease-in-out; + transition-duration: 500ms; + width: 25em; + float: right; + z-index: 20; + position: relative; + shape-margin: 0.5em; + filter: drop-shadow(5px 5px 10px rgb(0 0 0 / 50%)); + pointer-events: none; + } + + .spacer-top { + min-height: var(--__top-fringe); + } + + .spacer-bottom { + min-height: var(--__bottom-fringe); + } + + .extra-info-group { + transition: max-height, padding, height; + transition-timing-function: ease-in; + transition-duration: 700ms; + max-height: 70vh; + mask: + linear-gradient(to top, white, transparent) bottom/100% 2px no-repeat, + linear-gradient(to top, white, white); + } + + .art-credit { + text-align: right; + } + + &.-peek { + /* Explanation: + * 100vh - 100% = Distance between modal's top+bottom boundaries and screen + * (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen + */ + transform: translateY(calc(((100vh - 100%) / 2))); + + .pleroma-tan { + float: right; + z-index: 10; + shape-image-threshold: 70%; + } + + .extra-info-group { + max-height: 0; + } + } +} diff --git a/src/components/update_notification/update_notification.vue b/src/components/update_notification/update_notification.vue @@ -0,0 +1,103 @@ +<template> + <Modal + :is-open="!!shouldShow" + class="UpdateNotification" + :no-background="true" + > + <div + class="UpdateNotificationModal panel" + :class="{ '-peek': !showingMore }" + > + <div class="panel-heading"> + <span class="title"> + {{ $t('update.big_update_title') }} + </span> + </div> + <div class="panel-body"> + <div + class="content" + :class="{ '-noImage': !showingImage }" + > + <img + v-if="showingImage" + class="pleroma-tan" + :src="pleromaTanVariant" + :style="pleromaTanStyles" + > + <div class="spacer-top" /> + <div class="text"> + <p> + {{ $t('update.big_update_content') }} + </p> + <div + ref="animatedText" + class="extra-info-group" + > + <i18n-t + keypath="update.update_bugs" + tag="p" + > + <template #pleromaGitlab> + <a + target="_blank" + href="https://git.pleroma.social/" + >{{ $t('update.update_bugs_gitlab') }}</a> + </template> + </i18n-t> + <i18n-t + keypath="update.update_changelog" + tag="p" + > + <template #theFullChangelog> + <a + target="_blank" + href="https://pleroma.social/announcements/" + >{{ $t('update.update_changelog_here') }}</a> + </template> + </i18n-t> + <p class="art-credit"> + <i18n-t + keypath="update.art_by" + tag="small" + > + <template #linkToArtist> + <a + target="_blank" + href="https://post.ebin.club/users/pipivovott" + >pipivovott</a> + </template> + </i18n-t> + </p> + </div> + </div> + <div class="spacer-bottom" /> + </div> + </div> + <div class="panel-footer"> + <button + class="button-default" + @click.prevent="neverShowAgain" + > + {{ $t("general.never_show_again") }} + </button> + <button + v-if="!showingMore" + class="button-default" + @click.prevent="toggleShow" + > + {{ $t("general.show_more") }} + </button> + <button + class="button-default" + @click.prevent="dismiss" + > + {{ $t("general.dismiss") }} + </button> + </div> + </div> + </Modal> +</template> + +<script src="./update_notification.js"></script> + +<style src="./update_notification.scss" lang="scss"></style> diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue @@ -27,7 +27,7 @@ <script src="./user_avatar.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .Avatar { --_avatarShadowBox: var(--avatarStatusShadow); @@ -85,10 +85,9 @@ right: 0; margin: -0.2em; padding: 0.2em; - background: rgba(127, 127, 127, 0.5); + background: rgb(127 127 127 / 50%); color: #fff; border-radius: var(--tooltipRadius); } - } </style> diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js @@ -4,7 +4,9 @@ import ProgressButton from '../progress_button/progress_button.vue' import FollowButton from '../follow_button/follow_button.vue' import ModerationTools from '../moderation_tools/moderation_tools.vue' import AccountActions from '../account_actions/account_actions.vue' +import UserNote from '../user_note/user_note.vue' import Select from '../select/select.vue' +import UserLink from '../user_link/user_link.vue' import RichContent from 'src/components/rich_content/rich_content.jsx' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import { mapGetters } from 'vuex' @@ -38,7 +40,8 @@ export default { 'rounded', 'bordered', 'avatarAction', // default - open profile, 'zoom' - zoom, function - call function - 'onClose' + 'onClose', + 'hasNoteEditor' ], data () { return { @@ -124,6 +127,16 @@ export default { hideFollowersCount () { return this.isOtherUser && this.user.hide_followers_count }, + showModerationMenu () { + const privileges = this.loggedIn.privileges + return this.loggedIn.role === 'admin' || privileges.includes('users_manage_activation_state') || privileges.includes('users_delete') || privileges.includes('users_manage_tags') + }, + hasNote () { + return this.relationship.note + }, + supportsNote () { + return 'note' in this.relationship + }, ...mapGetters(['mergedConfig']) }, components: { @@ -134,7 +147,9 @@ export default { ProgressButton, FollowButton, Select, - RichContent + RichContent, + UserLink, + UserNote }, methods: { muteUser () { diff --git a/src/components/user_card/user_card.scss b/src/components/user_card/user_card.scss @@ -1,4 +1,4 @@ -@import '../../_variables.scss'; +@import "../../variables"; .user-card { position: relative; @@ -11,7 +11,7 @@ } .panel-heading { - padding: .5em 0; + padding: 0.5em 0; text-align: center; box-shadow: none; background: transparent; @@ -35,10 +35,11 @@ left: 0; right: 0; bottom: 0; - mask: linear-gradient(to top, white, transparent) bottom no-repeat, - linear-gradient(to top, white, white); + mask: + linear-gradient(to top, white, transparent) bottom no-repeat, + linear-gradient(to top, white, white); // Autoprefixer seem to ignore this one, and also syntax is different - -webkit-mask-composite: xor; + mask-composite: xor; mask-composite: exclude; background-size: cover; mask-size: 100% 60%; @@ -159,17 +160,17 @@ top: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.3); + background-color: rgb(0 0 0 / 30%); display: flex; justify-content: center; align-items: center; border-radius: $fallback--avatarRadius; border-radius: var(--avatarRadius, $fallback--avatarRadius); opacity: 0; - transition: opacity .2s ease; + transition: opacity 0.2s ease; svg { - color: #FFF; + color: #fff; } } @@ -178,7 +179,8 @@ } } - .external-link-button, .edit-profile-button { + .external-link-button, + .edit-profile-button { cursor: pointer; width: 2.5em; text-align: center; @@ -191,34 +193,6 @@ } } - .user-summary { - display: block; - margin-left: 0.6em; - text-align: left; - text-overflow: ellipsis; - white-space: nowrap; - flex: 1 1 0; - // This is so that text doesn't get overlapped by avatar's shadow if it has - // big one - z-index: 1; - line-height: 2em; - - --emoji-size: 1.7em; - - .top-line, - .bottom-line { - display: flex; - } - } - - .user-name { - text-overflow: ellipsis; - overflow: hidden; - flex: 1 1 auto; - margin-right: 1em; - font-size: 1.1em; - } - .bottom-line { font-weight: light; font-size: 1.1em; @@ -253,8 +227,36 @@ } } + .user-summary { + display: block; + margin-left: 0.6em; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1 1 0; + // This is so that text doesn't get overlapped by avatar's shadow if it has + // big one + z-index: 1; + line-height: 2em; + + --emoji-size: 1.7em; + + .top-line, + .bottom-line { + display: flex; + } + } + + .user-name { + text-overflow: ellipsis; + overflow: hidden; + flex: 1 1 auto; + margin-right: 1em; + font-size: 1.1em; + } + .user-meta { - margin-bottom: .15em; + margin-bottom: 0.15em; display: flex; align-items: baseline; line-height: 22px; @@ -263,7 +265,7 @@ .following { flex: 1 0 auto; margin: 0; - margin-bottom: .25em; + margin-bottom: 0.25em; text-align: left; } @@ -271,7 +273,7 @@ flex: 0 1 auto; display: flex; flex-wrap: wrap; - margin-right: -.5em; + margin-right: -0.5em; align-self: start; .userHighlightCl { @@ -294,19 +296,20 @@ .userHighlightText, .userHighlightSel { vertical-align: top; - margin-right: .5em; - margin-bottom: .25em; + margin-right: 0.5em; + margin-bottom: 0.25em; } } } + .user-interactions { position: relative; display: flex; flex-flow: row wrap; - margin-right: -.75em; + margin-right: -0.75em; > * { - margin: 0 .75em .6em 0; + margin: 0 0.75em 0.6em 0; white-space: nowrap; min-width: 95px; } @@ -315,6 +318,10 @@ margin: 0; } } + + .user-note { + margin: 0 0.75em 0.6em 0; + } } .sidebar .edit-profile-button { @@ -323,8 +330,8 @@ .user-counts { display: flex; - line-height:16px; - padding: .5em 1.5em 0em 1.5em; + line-height: 16px; + padding: 0.5em 1.5em 0; text-align: center; justify-content: space-between; color: $fallback--lightText; @@ -334,14 +341,16 @@ .user-count { flex: 1 0 auto; - padding: .5em 0 .5em 0; - margin: 0 .5em; + padding: 0.5em 0; + margin: 0 0.5em; h5 { - font-size:1em; + font-size: 1em; font-weight: bolder; margin: 0 0 0.25em; } + + /* stylelint-disable-next-line no-descending-specificity */ a { text-decoration: none; } diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue @@ -106,13 +106,10 @@ </button> </div> <div class="bottom-line"> - <router-link + <user-link class="user-screen-name" - :title="user.screen_name_ui" - :to="userProfileLink(user)" - > - @{{ user.screen_name_ui }} - </router-link> + :user="user" + /> <template v-if="!hideBio"> <span v-if="user.deactivated" @@ -261,7 +258,7 @@ </button> </div> <ModerationTools - v-if="loggedIn.role === &quot;admin&quot;" + v-if="showModerationMenu" :user="user" /> </div> @@ -271,6 +268,12 @@ > <RemoteFollow :user="user" /> </div> + <UserNote + v-if="loggedIn && isOtherUser && (hasNote || (hasNoteEditor && supportsNote))" + :user="user" + :relationship="relationship" + :editable="hasNoteEditor" + /> </div> </div> <div diff --git a/src/components/user_link/user_link.vue b/src/components/user_link/user_link.vue @@ -0,0 +1,38 @@ +<template> + <router-link + :title="user.screen_name_ui" + :to="userProfileLink(user)" + > + {{ at ? '@' : '' }}{{ user.screen_name_ui }}<UnicodeDomainIndicator + :user="user" + /> + </router-link> +</template> + +<script> +import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' +import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' + +const UserLink = { + props: { + user: Object, + at: { + type: Boolean, + default: true + } + }, + components: { + UnicodeDomainIndicator + }, + methods: { + userProfileLink (user) { + return generateProfileLink( + user.id, user.screen_name, + this.$store.state.instance.restrictedNicknames + ) + } + } +} + +export default UserLink +</script> diff --git a/src/components/user_list_menu/user_list_menu.js b/src/components/user_list_menu/user_list_menu.js @@ -0,0 +1,93 @@ +import { library } from '@fortawesome/fontawesome-svg-core' +import { faChevronRight } from '@fortawesome/free-solid-svg-icons' +import { mapState } from 'vuex' + +import DialogModal from '../dialog_modal/dialog_modal.vue' +import Popover from '../popover/popover.vue' + +library.add(faChevronRight) + +const UserListMenu = { + props: [ + 'user' + ], + data () { + return {} + }, + components: { + DialogModal, + Popover + }, + created () { + this.$store.dispatch('fetchUserInLists', this.user.id) + }, + computed: { + ...mapState({ + allLists: state => state.lists.allLists + }), + inListsSet () { + return new Set(this.user.inLists.map(x => x.id)) + }, + lists () { + if (!this.user.inLists) return [] + return this.allLists.map(list => ({ + ...list, + inList: this.inListsSet.has(list.id) + })) + } + }, + methods: { + toggleList (listId) { + if (this.inListsSet.has(listId)) { + this.$store.dispatch('removeListAccount', { accountId: this.user.id, listId }).then((response) => { + if (!response.ok) { return } + this.$store.dispatch('fetchUserInLists', this.user.id) + }) + } else { + this.$store.dispatch('addListAccount', { accountId: this.user.id, listId }).then((response) => { + if (!response.ok) { return } + this.$store.dispatch('fetchUserInLists', this.user.id) + }) + } + }, + toggleRight (right) { + const store = this.$store + if (this.user.rights[right]) { + store.state.api.backendInteractor.deleteRight({ user: this.user, right }).then(response => { + if (!response.ok) { return } + store.commit('updateRight', { user: this.user, right, value: false }) + }) + } else { + store.state.api.backendInteractor.addRight({ user: this.user, right }).then(response => { + if (!response.ok) { return } + store.commit('updateRight', { user: this.user, right, value: true }) + }) + } + }, + toggleActivationStatus () { + this.$store.dispatch('toggleActivationStatus', { user: this.user }) + }, + deleteUserDialog (show) { + this.showDeleteUserDialog = show + }, + deleteUser () { + const store = this.$store + const user = this.user + const { id, name } = user + store.state.api.backendInteractor.deleteUser({ user }) + .then(e => { + this.$store.dispatch('markStatusesAsDeleted', status => user.id === status.user.id) + const isProfile = this.$route.name === 'external-user-profile' || this.$route.name === 'user-profile' + const isTargetUser = this.$route.params.name === name || this.$route.params.id === id + if (isProfile && isTargetUser) { + window.history.back() + } + }) + }, + setToggled (value) { + this.toggled = value + } + } +} + +export default UserListMenu diff --git a/src/components/user_list_menu/user_list_menu.vue b/src/components/user_list_menu/user_list_menu.vue @@ -0,0 +1,38 @@ +<template> + <div class="UserListMenu"> + <Popover + trigger="hover" + placement="left" + remove-padding + > + <template #content> + <div class="dropdown-menu"> + <button + v-for="list in lists" + :key="list.id" + class="button-default dropdown-item" + @click="toggleList(list.id)" + > + <span + class="menu-checkbox" + :class="{ 'menu-checkbox-checked': list.inList }" + /> + {{ list.title }} + </button> + </div> + </template> + <template #trigger> + <button class="btn button-default dropdown-item -has-submenu"> + {{ $t('lists.manage_lists') }} + <FAIcon + class="chevron-icon" + size="lg" + icon="chevron-right" + /> + </button> + </template> + </Popover> + </div> +</template> + +<script src="./user_list_menu.js"></script> diff --git a/src/components/user_list_popover/user_list_popover.js b/src/components/user_list_popover/user_list_popover.js @@ -1,5 +1,6 @@ import { defineAsyncComponent } from 'vue' import RichContent from 'src/components/rich_content/rich_content.jsx' +import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' @@ -15,6 +16,7 @@ const UserListPopover = { ], components: { RichContent, + UnicodeDomainIndicator, Popover: defineAsyncComponent(() => import('../popover/popover.vue')), UserAvatar: defineAsyncComponent(() => import('../user_avatar/user_avatar.vue')) }, diff --git a/src/components/user_list_popover/user_list_popover.vue b/src/components/user_list_popover/user_list_popover.vue @@ -29,7 +29,7 @@ :emoji="user.emoji" /> <!-- eslint-enable vue/no-v-html --> - <span class="user-list-screen-name">{{ user.screen_name_ui }}</span> + <span class="user-list-screen-name">{{ user.screen_name_ui }}</span><UnicodeDomainIndicator :user="user" /> </div> </div> </template> @@ -48,7 +48,7 @@ <script src="./user_list_popover.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .user-list-popover { padding: 0.5em; diff --git a/src/components/user_note/user_note.js b/src/components/user_note/user_note.js @@ -0,0 +1,45 @@ +const UserNote = { + props: { + user: Object, + relationship: Object, + editable: Boolean + }, + data () { + return { + localNote: '', + editing: false, + frozen: false + } + }, + computed: { + shouldShow () { + return this.relationship.note || this.editing + } + }, + methods: { + startEditing () { + this.localNote = this.relationship.note + this.editing = true + }, + cancelEditing () { + this.editing = false + }, + finalizeEditing () { + this.frozen = true + + this.$store.dispatch('editUserNote', { + id: this.user.id, + comment: this.localNote + }) + .then(() => { + this.frozen = false + this.editing = false + }) + .catch(() => { + this.frozen = false + }) + } + } +} + +export default UserNote diff --git a/src/components/user_note/user_note.vue b/src/components/user_note/user_note.vue @@ -0,0 +1,88 @@ +<template> + <div + class="user-note" + > + <div class="heading"> + <span>{{ $t('user_card.note') }}</span> + <div class="buttons"> + <button + v-show="!editing && editable" + class="button-default btn" + @click="startEditing" + > + {{ $t('user_card.edit_note') }} + </button> + <button + v-show="editing" + class="button-default btn" + :disabled="frozen" + @click="finalizeEditing" + > + {{ $t('user_card.edit_note_apply') }} + </button> + <button + v-show="editing" + class="button-default btn" + :disabled="frozen" + @click="cancelEditing" + > + {{ $t('user_card.edit_note_cancel') }} + </button> + </div> + </div> + <textarea + v-show="editing" + v-model="localNote" + class="note-text" + /> + <span + v-show="!editing" + class="note-text" + :class="{ '-blank': !relationship.note }" + > + {{ relationship.note || $t('user_card.note_blank') }} + </span> + </div> +</template> + +<script src="./user_note.js"></script> + +<style lang="scss"> +@import "../../variables"; + +.user-note { + display: flex; + flex-direction: column; + + .heading { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 0.75em; + + .btn { + min-width: 95px; + } + + .buttons { + display: flex; + flex-direction: row; + justify-content: right; + + .btn { + margin-left: 0.5em; + } + } + } + + .note-text { + align-self: stretch; + } + + .note-text.-blank { + font-style: italic; + color: var(--faint, $fallback--faint); + } +} +</style> diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue @@ -1,5 +1,5 @@ <template> - <div class="user-panel"> + <aside class="user-panel"> <div v-if="signedIn" key="user-panel-signed" @@ -16,7 +16,7 @@ v-else key="user-panel" /> - </div> + </aside> </template> <script src="./user_panel.js"></script> diff --git a/src/components/user_popover/user_popover.js b/src/components/user_popover/user_popover.js @@ -11,8 +11,8 @@ const UserPopover = { Popover: defineAsyncComponent(() => import('../popover/popover.vue')) }, computed: { - userPopoverZoom () { - return this.$store.getters.mergedConfig.userPopoverZoom + userPopoverAvatarAction () { + return this.$store.getters.mergedConfig.userPopoverAvatarAction }, userPopoverOverlay () { return this.$store.getters.mergedConfig.userPopoverOverlay diff --git a/src/components/user_popover/user_popover.vue b/src/components/user_popover/user_popover.vue @@ -14,7 +14,7 @@ class="user-popover" :user-id="userId" :hide-bio="true" - :avatar-action="userPopoverZoom ? 'zoom' : close" + :avatar-action="userPopoverAvatarAction == 'close' ? close : userPopoverAvatarAction" :on-close="close" /> </template> @@ -24,10 +24,12 @@ <script src="./user_popover.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; /* popover styles load on-demand, so we need to override */ +/* stylelint-disable block-no-empty */ .user-popover.popover { } +/* stylelint-enable block-no-empty */ </style> diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js @@ -48,7 +48,7 @@ const UserProfile = { }, created () { const routeParams = this.$route.params - this.load(routeParams.name || routeParams.id) + this.load({ name: routeParams.name, id: routeParams.id }) this.tab = get(this.$route, 'query.tab', defaultTabKey) }, unmounted () { @@ -113,12 +113,17 @@ const UserProfile = { this.userId = null this.error = false + const maybeId = userNameOrId.id + const maybeName = userNameOrId.name + // Check if user data is already loaded in store - const user = this.$store.getters.findUser(userNameOrId) + const user = maybeId ? this.$store.getters.findUser(maybeId) : this.$store.getters.findUserByName(maybeName) if (user) { loadById(user.id) } else { - this.$store.dispatch('fetchUser', userNameOrId) + (maybeId + ? this.$store.dispatch('fetchUser', maybeId) + : this.$store.dispatch('fetchUserByName', maybeName)) .then(({ id }) => loadById(id)) .catch((reason) => { const errorMessage = get(reason, 'error.error') @@ -157,12 +162,12 @@ const UserProfile = { watch: { '$route.params.id': function (newVal) { if (newVal) { - this.switchUser(newVal) + this.switchUser({ id: newVal }) } }, '$route.params.name': function (newVal) { if (newVal) { - this.switchUser(newVal) + this.switchUser({ name: newVal }) } }, '$route.query': function (newVal) { diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue @@ -10,6 +10,7 @@ :selected="timeline.viewing" avatar-action="zoom" rounded="top" + :has-note-editor="true" /> <span v-if="!!user.birthday" @@ -149,7 +150,7 @@ <script src="./user_profile.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .user-profile { flex: 2; @@ -199,7 +200,8 @@ margin: 0 0 0 0.25em; } - .user-profile-field-name, .user-profile-field-value { + .user-profile-field-name, + .user-profile-field-value { line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; @@ -217,6 +219,7 @@ padding: 2em; } } + .user-profile-placeholder { .panel-body { display: flex; diff --git a/src/components/user_reporting_modal/user_reporting_modal.js b/src/components/user_reporting_modal/user_reporting_modal.js @@ -1,15 +1,16 @@ - import Status from '../status/status.vue' import List from '../list/list.vue' import Checkbox from '../checkbox/checkbox.vue' import Modal from '../modal/modal.vue' +import UserLink from '../user_link/user_link.vue' const UserReportingModal = { components: { Status, List, Checkbox, - Modal + Modal, + UserLink }, data () { return { @@ -21,14 +22,17 @@ const UserReportingModal = { } }, computed: { + reportModal () { + return this.$store.state.reports.reportModal + }, isLoggedIn () { return !!this.$store.state.users.currentUser }, isOpen () { - return this.isLoggedIn && this.$store.state.reports.modalActivated + return this.isLoggedIn && this.reportModal.activated }, userId () { - return this.$store.state.reports.userId + return this.reportModal.userId }, user () { return this.$store.getters.findUser(this.userId) @@ -37,10 +41,10 @@ const UserReportingModal = { return !this.user.is_local && this.user.screen_name.substr(this.user.screen_name.indexOf('@') + 1) }, statuses () { - return this.$store.state.reports.statuses + return this.reportModal.statuses }, preTickedIds () { - return this.$store.state.reports.preTickedIds + return this.reportModal.preTickedIds } }, watch: { diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue @@ -5,9 +5,13 @@ > <div class="user-reporting-panel panel"> <div class="panel-heading"> - <div class="title"> - {{ $t('user_reporting.title', [user.screen_name_ui]) }} - </div> + <i18n-t + tag="div" + keypath="user_reporting.title" + class="title" + > + <UserLink :user="user" /> + </i18n-t> </div> <div class="panel-body"> <div class="user-reporting-panel-left"> @@ -68,7 +72,7 @@ <script src="./user_reporting_modal.js"></script> <style lang="scss"> -@import '../../_variables.scss'; +@import "../../variables"; .user-reporting-panel { width: 90vw; @@ -117,7 +121,7 @@ } .alert { - margin: 1em 0 0 0; + margin: 1em 0 0; line-height: 1.3em; } } diff --git a/src/components/who_to_follow/who_to_follow.vue b/src/components/who_to_follow/who_to_follow.vue @@ -15,6 +15,3 @@ </template> <script src="./who_to_follow.js"></script> - -<style lang="scss"> -</style> diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.vue b/src/components/who_to_follow_panel/who_to_follow_panel.vue @@ -33,24 +33,28 @@ .who-to-follow * { vertical-align: middle; } + .who-to-follow img { width: 32px; height: 32px; } + .who-to-follow { - padding: 0em 1em; - margin: 0px; + padding: 0 1em; + margin: 0; } + .who-to-follow-items { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - padding: 0px; - margin: 1em 0em; + padding: 0; + margin: 1em 0; } + .who-to-follow-more { - padding: 0px; - margin: 1em 0em; + padding: 0; + margin: 1em 0; text-align: center; } </style> diff --git a/src/hocs/with_load_more/with_load_more.scss b/src/hocs/with_load_more/with_load_more.scss @@ -1,5 +1,4 @@ - -@import '../../_variables.scss'; +@import "../../variables"; .with-load-more { &-footer { diff --git a/src/hocs/with_subscription/with_subscription.scss b/src/hocs/with_subscription/with_subscription.scss @@ -7,4 +7,4 @@ font-size: 1rem; } } -} -\ No newline at end of file +} diff --git a/src/i18n/ar.json b/src/i18n/ar.json @@ -200,5 +200,22 @@ "who_to_follow": { "more": "المزيد", "who_to_follow": "للمتابعة" + }, + "about": { + "mrf": { + "keyword": { + "ftl_removal": "إزالة من الخط الزمني الخاص بجميع الشبكات المعروفة", + "reject": "رفض", + "replace": "إستبدال", + "is_replaced_by": "←", + "keyword_policies": "سياسة الكلمات الدلالية" + }, + "simple": { + "simple_policies": "سياسات الخادم" + }, + "federation": "الاتحاد", + "mrf_policies": "تفعيل سياسات إعادة كتابة المنشور", + "mrf_policies_desc": "خاصية إعادة كتابة المناشير تقوم بتعديل تفاعل الاتحاد مع هذا الخادم. السياسات التالية مفعّلة:" + } } } diff --git a/src/i18n/en.json b/src/i18n/en.json @@ -32,6 +32,27 @@ }, "staff": "Staff" }, + "announcements": { + "page_header": "Announcements", + "title": "Announcement", + "mark_as_read_action": "Mark as read", + "post_form_header": "Post announcement", + "post_placeholder": "Type your announcement content here...", + "post_action": "Post", + "post_error": "Error: {error}", + "close_error": "Close", + "delete_action": "Delete", + "start_time_prompt": "Start time: ", + "end_time_prompt": "End time: ", + "all_day_prompt": "This is an all-day event", + "published_time_display": "Published at {time}", + "start_time_display": "Starts at {time}", + "end_time_display": "Ends at {time}", + "edit_action": "Edit", + "submit_edit_action": "Submit", + "cancel_edit_action": "Cancel", + "inactive_message": "This announcement is inactive" + }, "shoutbox": { "title": "Shoutbox" }, @@ -66,11 +87,13 @@ "more": "More", "loading": "Loading…", "generic_error": "An error occured", + "generic_error_message": "An error occured: {0}", "error_retry": "Please try again", "retry": "Try again", "optional": "optional", "show_more": "Show more", "show_less": "Show less", + "never_show_again": "Never show again", "dismiss": "Dismiss", "cancel": "Cancel", "disable": "Disable", @@ -78,11 +101,17 @@ "confirm": "Confirm", "verify": "Verify", "close": "Close", + "undo": "Undo", + "yes": "Yes", + "no": "No", "peek": "Peek", + "scroll_to_top": "Scroll to top", "role": { "admin": "Admin", "moderator": "Moderator" }, + "unpin": "Unpin item", + "pin": "Pin item", "flash_content": "Click to show Flash content using Ruffle (Experimental, may not work).", "flash_security": "Note that this can be potentially dangerous since Flash content is still arbitrary code.", "flash_fail": "Failed to load flash content, see console for details.", @@ -146,7 +175,16 @@ "who_to_follow": "Who to follow", "preferences": "Preferences", "timelines": "Timelines", - "chats": "Chats" + "chats": "Chats", + "lists": "Lists", + "edit_nav_mobile": "Customize navigation bar", + "edit_pinned": "Edit pinned items", + "edit_finish": "Done editing", + "mobile_sidebar": "Toggle mobile sidebar", + "mobile_notifications": "Open notifications", + "mobile_notifications": "Open notifications (there are unread ones)", + "mobile_notifications_close": "Close notifications", + "announcements": "Announcements" }, "notifications": { "broken_favorite": "Unknown status, searching for it…", @@ -161,6 +199,7 @@ "no_more_notifications": "No more notifications", "migrated_to": "migrated to", "reacted_with": "reacted with {0}", + "submitted_report": "submitted a report", "poll_ended": "poll has ended" }, "polls": { @@ -186,9 +225,22 @@ "search_emoji": "Search for an emoji", "add_emoji": "Insert emoji", "custom": "Custom emoji", + "unpacked": "Unpacked emoji", "unicode": "Unicode emoji", + "unicode_groups": { + "activities": "Activities", + "animals-and-nature": "Animals & Nature", + "flags": "Flags", + "food-and-drink": "Food & Drink", + "objects": "Objects", + "people-and-body": "People & Body", + "smileys-and-emotion": "Smileys & Emotion", + "symbols": "Symbols", + "travel-and-places": "Travel & Places" + }, "load_all_hint": "Loaded first {saneAmount} emoji, loading all emoji may cause performance issues.", - "load_all": "Loading all {emojiAmount} emoji" + "load_all": "Loading all {emojiAmount} emoji", + "regional_indicator": "Regional indicator {letter}" }, "errors": { "storage_unavailable": "Pleroma could not access browser storage. Your login or your local settings won't be saved and you might encounter unexpected issues. Try enabling cookies." @@ -196,10 +248,13 @@ "interactions": { "favs_repeats": "Repeats and favorites", "follows": "New follows", + "emoji_reactions": "Emoji Reactions", + "reports": "Reports", "moves": "User migrates", "load_older": "Load older interactions" }, "post_status": { + "edit_status": "Edit status", "new_status": "Post new status", "account_not_locked_warning": "Your account is not {0}. Anyone can follow you to view your follower-only posts.", "account_not_locked_warning_link": "locked", @@ -215,6 +270,8 @@ "default": "Just landed in L.A.", "direct_warning_to_all": "This post will be visible to all the mentioned users.", "direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.", + "edit_remote_warning": "Other remote instances may not support editing and unable to receive the latest version of your post.", + "edit_unsupported_warning": "Pleroma does not support editing mentions or polls.", "posting": "Posting", "post": "Post", "preview": "Preview", @@ -264,6 +321,16 @@ "searching_for": "Searching for", "error": "Not found." }, + "report": { + "reporter": "Reporter:", + "reported_user": "Reported user:", + "reported_statuses": "Reported statuses:", + "notes": "Notes:", + "state": "State:", + "state_open": "Open", + "state_closed": "Closed", + "state_resolved": "Resolved" + }, "selectable_list": { "select_all": "Select all" }, @@ -298,6 +365,7 @@ "desc": "To enable two-factor authentication, enter the code from your two-factor app:" } }, + "lists_navigation": "Show lists in navigation", "allow_following_move": "Allow auto-follow when following account moves", "attachmentRadius": "Attachments", "attachments": "Attachments", @@ -323,6 +391,8 @@ "account_backup_table_head": "Backup", "download_backup": "Download", "backup_not_ready": "This backup is not ready yet.", + "backup_running": "This backup is in progress, processed {number} record. | This backup is in progress, processed {number} records.", + "backup_failed": "This backup has failed.", "remove_backup": "Remove", "list_backups_error": "Error fetching backup list: {error}", "add_backup": "Create a new backup", @@ -375,7 +445,7 @@ "filtering": "Filtering", "wordfilter": "Wordfilter", "filtering_explanation": "All statuses containing these words will be muted, one per line", - "word_filter": "Word filter", + "word_filter_and_more": "Word filter and more...", "follow_export": "Follow export", "follow_export_button": "Export your follows to a csv file", "follow_import": "Follow import", @@ -395,6 +465,7 @@ "hide_isp": "Hide instance-specific panel", "hide_shoutbox": "Hide instance shoutbox", "right_sidebar": "Reverse order of columns", + "navbar_column_stretch": "Stretch navbar to columns width", "always_show_post_button": "Always show floating New Post button", "hide_wallpaper": "Hide instance wallpaper", "preload_images": "Preload images", @@ -513,15 +584,22 @@ "subject_line_noop": "Do not copy", "conversation_display": "Conversation display style", "conversation_display_tree": "Tree-style", + "conversation_display_tree_quick": "Tree view", "disable_sticky_headers": "Don't stick column headers to top of the screen", "show_scrollbars": "Show side column's scrollbars", "third_column_mode": "When there's enough space, show third column containing", "third_column_mode_none": "Don't show third column at all", "third_column_mode_notifications": "Notifications column", "third_column_mode_postform": "Main post form and navigation", + "columns": "Columns", + "column_sizes": "Column sizes", + "column_sizes_sidebar": "Sidebar", + "column_sizes_content": "Content", + "column_sizes_notifs": "Notifications", "tree_advanced": "Allow more flexible navigation in tree view", "tree_fade_ancestors": "Display ancestors of the current status in faint text", "conversation_display_linear": "Linear-style", + "conversation_display_linear_quick": "Linear view", "conversation_other_replies_button": "Show the \"other replies\" button", "conversation_other_replies_button_below": "Below statuses", "conversation_other_replies_button_inside": "Inside statuses", @@ -530,8 +608,10 @@ "sensitive_by_default": "Mark posts as sensitive by default", "stop_gifs": "Pause animated images until you hover on them", "streaming": "Automatically show new posts when scrolled to the top", + "auto_update": "Show new posts automatically", "user_mutes": "Users", "useStreamingApi": "Receive posts and notifications real-time", + "use_websockets": "Use websockets (Realtime updates)", "text": "Text", "theme": "Theme", "theme_help": "Use hex color codes (#rrggbb) to customize your color theme.", @@ -553,9 +633,13 @@ "mention_link_display_full": "always as full names (e.g. {'@'}foo{'@'}example.org)", "mention_link_use_tooltip": "Show user card when clicking mention links", "mention_link_show_avatar": "Show user avatar beside the link", + "mention_link_show_avatar_quick": "Show user avatar next to mentions", "mention_link_fade_domain": "Fade domains (e.g. {'@'}example.org in {'@'}foo{'@'}example.org)", "mention_link_bolden_you": "Highlight mention of you when you are mentioned", - "user_popover_avatar_zoom": "Clicking on user avatar in popover zooms it instead of closing the popover", + "user_popover_avatar_action": "Popover avatar click action", + "user_popover_avatar_action_zoom": "Zoom the avatar", + "user_popover_avatar_action_close": "Close the popover", + "user_popover_avatar_action_open": "Open profile", "user_popover_avatar_overlay": "Show user popover over user avatar", "fun": "Fun", "greentext": "Meme arrows", @@ -756,12 +840,16 @@ "no_more_statuses": "No more statuses", "no_statuses": "No statuses", "socket_reconnected": "Realtime connection established", - "socket_broke": "Realtime connection lost: CloseEvent code {0}" + "socket_broke": "Realtime connection lost: CloseEvent code {0}", + "quick_view_settings": "Quick view settings", + "quick_filter_settings": "Quick filter settings" }, "status": { "favorites": "Favorites", "repeats": "Repeats", "delete": "Delete status", + "edit": "Edit status", + "edited_at": "(last edited {time})", "pin": "Pin on profile", "unpin": "Unpin from profile", "pinned": "Pinned", @@ -809,7 +897,8 @@ "ancestor_follow_with_icon": "{icon} {text}", "show_all_conversation_with_icon": "{icon} {text}", "show_all_conversation": "Show full conversation ({numStatus} other status) | Show full conversation ({numStatus} other statuses)", - "show_only_conversation_under_this": "Only show replies to this status" + "show_only_conversation_under_this": "Only show replies to this status", + "status_history": "Status history" }, "user_card": { "approve": "Approve", @@ -837,6 +926,7 @@ "muted": "Muted", "per_day": "per day", "remote_follow": "Remote follow", + "remove_follower": "Remove follower", "report": "Report", "statuses": "Statuses", "subscribe": "Subscribe", @@ -875,7 +965,12 @@ "solid": "Solid bg", "striped": "Striped bg", "side": "Side stripe" - } + }, + "note": "Note", + "note_blank": "(None)", + "edit_note": "Edit note", + "edit_note_apply": "Apply", + "edit_note_cancel": "Cancel" }, "user_profile": { "timeline_title": "User timeline", @@ -904,7 +999,9 @@ "user_settings": "User Settings", "accept_follow_request": "Accept follow request", "reject_follow_request": "Reject follow request", - "bookmark": "Bookmark" + "bookmark": "Bookmark", + "toggle_expand": "Expand or collapse notification to show post in full", + "toggle_mute": "Expand or collapse notification to reveal muted content" }, "upload": { "error": { @@ -926,7 +1023,9 @@ "hashtags": "Hashtags", "person_talking": "{count} person talking", "people_talking": "{count} people talking", - "no_results": "No results" + "no_results": "No results", + "no_more_results": "No more results", + "load_more": "Load more results" }, "password_reset": { "forgot_password": "Forgot password?", @@ -953,6 +1052,27 @@ "error_sending_message": "Something went wrong when sending the message.", "empty_chat_list_placeholder": "You don't have any chats yet. Start a new chat!" }, + "lists": { + "lists": "Lists", + "new": "New List", + "title": "List title", + "search": "Search users", + "create": "Create", + "save": "Save changes", + "delete": "Delete list", + "following_only": "Limit to Following", + "manage_lists": "Manage lists", + "manage_members": "Manage list members", + "add_members": "Search for more users", + "remove_from_list": "Remove from list", + "add_to_list": "Add to list", + "is_in_list": "Already in list", + "editing_list": "Editing list {listTitle}", + "creating_list": "Creating new list", + "update_title": "Save Title", + "really_delete": "Really delete list?", + "error": "Error manipulating lists: {0}" + }, "file_type": { "audio": "Audio", "video": "Video", @@ -961,5 +1081,17 @@ }, "display_date": { "today": "Today" + }, + "update": { + "big_update_title": "Please bear with us", + "big_update_content": "We haven't had a release in a while, so things might look and feel different than what you're used to.", + "update_bugs": "Please report any issues and bugs on {pleromaGitlab}, as we have changed a lot, and although we test thoroughly and use development versions ourselves, we may have missed some things. We welcome your feedback and suggestions on issues you might encounter, or how to improve Pleroma and Pleroma-FE.", + "update_bugs_gitlab": "Pleroma GitLab", + "update_changelog": "For more details on what's changed, see {theFullChangelog}.", + "update_changelog_here": "the full changelog", + "art_by": "Art by {linkToArtist}" + }, + "unicode_domain_indicator": { + "tooltip": "This domain contains non-ascii characters." } } diff --git a/src/i18n/eo.json b/src/i18n/eo.json @@ -11,7 +11,8 @@ "title": "Funkcioj", "who_to_follow": "Kiun aboni", "pleroma_chat_messages": "Babilejo de Pleroma", - "upload_limit": "Limo de alŝutoj" + "upload_limit": "Limo de alŝutoj", + "shout": "Kriujo" }, "finder": { "error_fetching_user": "Eraris alporto de uzanto", @@ -42,7 +43,21 @@ }, "flash_content": "Klaku por montri enhavon de Flash per Ruffle. (Eksperimente, eble ne funkcios.)", "flash_security": "Sciu, ke tio povas esti danĝera, ĉar la enhavo de Flash ja estas arbitra programo.", - "flash_fail": "Malsukcesis enlegi enhavon de Flash; vidu detalojn en konzolo." + "flash_fail": "Malsukcesis enlegi enhavon de Flash; vidu detalojn en konzolo.", + "scope_in_timeline": { + "direct": "Persona", + "private": "Nur abonantoj", + "public": "Publika", + "unlisted": "Nelistigita" + }, + "generic_error_message": "Eraris: {0}", + "never_show_again": "Neniam remontri", + "undo": "Malfari", + "yes": "Jes", + "no": "Ne", + "unpin": "Malfiksi eron", + "pin": "Fiksi eron", + "scroll_to_top": "Rulumi supren" }, "image_cropper": { "crop_picture": "Tondi bildon", @@ -70,7 +85,9 @@ }, "media_modal": { "previous": "Antaŭa", - "next": "Sekva" + "next": "Sekva", + "counter": "{current} / {total}", + "hide": "Fermi vidilon de vidaŭdaĵoj" }, "nav": { "about": "Pri", @@ -79,9 +96,9 @@ "friend_requests": "Petoj pri abono", "mentions": "Mencioj", "dms": "Rektaj mesaĝoj", - "public_tl": "Publika historio", + "public_tl": "Noda historio", "timeline": "Historio", - "twkn": "Konata reto", + "twkn": "Federa historio", "user_search": "Serĉi uzantojn", "who_to_follow": "Kiun aboni", "preferences": "Agordoj", @@ -91,24 +108,33 @@ "administration": "Administrado", "bookmarks": "Legosignoj", "timelines": "Historioj", - "home_timeline": "Hejma historio" + "home_timeline": "Hejma historio", + "edit_pinned": "Redakti fiksitajn erojn", + "lists": "Listoj", + "edit_nav_mobile": "Adapti navigan breton", + "edit_finish": "Fini redakton", + "mobile_notifications": "Malfermi sciigojn (estas nelegitaj)", + "mobile_notifications_close": "Fermi sciigojn", + "announcements": "Anoncoj" }, "notifications": { - "broken_favorite": "Nekonata stato, serĉante ĝin…", - "favorited_you": "ŝatis vian staton", + "broken_favorite": "Nekonata afiŝo, serĉante ĝin…", + "favorited_you": "ŝatis vian afiŝon", "followed_you": "ekabonis vin", "load_older": "Enlegi pli malnovajn sciigojn", "notifications": "Sciigoj", "read": "Legite!", - "repeated_you": "ripetis vian staton", + "repeated_you": "ripetis vian afiŝon", "no_more_notifications": "Neniuj pliaj sciigoj", "reacted_with": "reagis per {0}", "migrated_to": "migris al", "follow_request": "volas vin aboni", - "error": "Eraris akirado de sciigoj: {0}" + "error": "Eraris akirado de sciigoj: {0}", + "submitted_report": "sendis raporton", + "poll_ended": "enketo finiĝis" }, "post_status": { - "new_status": "Afiŝi novan staton", + "new_status": "Afiŝi", "account_not_locked_warning": "Via konto ne estas {0}. Iu ajn povas vin aboni por vidi eĉ viajn afiŝoj nur por abonantoj.", "account_not_locked_warning_link": "ŝlosita", "attachments_sensitive": "Marki kunsendaĵojn konsternaj", @@ -129,18 +155,21 @@ "unlisted": "Nelistigita – ne afiŝi al publikaj historioj" }, "scope_notice": { - "unlisted": "Ĉi tiu afiŝo ne estos videbla en la Publika historio kaj La tuta konata reto", + "unlisted": "Ĉi tiu afiŝo ne estos videbla en la Noda kaj la Federa historioj", "private": "Ĉi tiu afiŝo estos videbla nur al viaj abonantoj", "public": "Ĉi tiu afiŝo estos videbla al ĉiuj" }, "media_description_error": "Malsukcesis afiŝo de vidaŭdaĵoj; reprovu", - "empty_status_error": "Ne povas afiŝi malplenan staton sen dosieroj", + "empty_status_error": "Ne povas fari malplenan afiŝon sen dosieroj", "preview_empty": "Malplena", "preview": "Antaŭrigardo", "direct_warning_to_first_only": "Ĉi tiu afiŝo estas nur videbla al uzantoj menciitaj je la komenco de la mesaĝo.", "direct_warning_to_all": "Ĉi tiu afiŝo estos videbla al ĉiuj menciitaj uzantoj.", "media_description": "Priskribo de vidaŭdaĵo", - "post": "Afiŝo" + "post": "Afiŝo", + "edit_remote_warning": "Aliaj foraj nodoj eble ne subtenas redaktadon, kaj ne povos ricevi pli novan version de via afiŝo.", + "edit_unsupported_warning": "Pleroma ne subtenas redaktadon de mencioj aŭ enketoj.", + "edit_status": "Redakti afiŝon" }, "registration": { "bio": "Priskribo", @@ -164,7 +193,10 @@ }, "reason_placeholder": "Ĉi-node oni aprobas registriĝojn permane.\nSciigu la administrantojn kial vi volas registriĝi.", "reason": "Kialo registriĝi", - "register": "Registriĝi" + "register": "Registriĝi", + "bio_optional": "Prio (malnepra)", + "email_optional": "Retpoŝtadreso (malnepra)", + "email_language": "En kiu lingvo vi volus ricevi retleterojn de la servilo?" }, "settings": { "app_name": "Nomo de aplikaĵo", @@ -199,7 +231,7 @@ "avatar_size_instruction": "La rekomendata minimuma grando de profilbildoj estas 150×150 bilderoj.", "export_theme": "Konservi antaŭagordon", "filtering": "Filtrado", - "filtering_explanation": "Ĉiuj statoj kun tiuj ĉi vortoj silentiĝos; skribu po unu linie", + "filtering_explanation": "Ĉiuj afiŝoj kun tiuj ĉi vortoj silentiĝos; skribu po unu linie", "follow_export": "Elporto de abonoj", "follow_export_button": "Elporti viajn abonojn al CSV-dosiero", "follow_export_processing": "Traktante; baldaŭ vi ricevos peton elŝuti la dosieron", @@ -216,7 +248,7 @@ "use_one_click_nsfw": "Malfermi konsternajn kunsendaĵojn per nur unu klako", "hide_post_stats": "Kaŝi statistikon de afiŝoj (ekz. nombron de ŝatoj)", "hide_user_stats": "Kaŝi statistikon de uzantoj (ekz. nombron de abonantoj)", - "hide_filtered_statuses": "Kaŝi filtritajn statojn", + "hide_filtered_statuses": "Kaŝi ĉiujn filtritajn afiŝojn", "import_followers_from_a_csv_file": "Enporti abonojn el CSV-dosiero", "import_theme": "Enlegi antaŭagordojn", "inputRadius": "Enigaj kampoj", @@ -249,7 +281,7 @@ "hide_followers_description": "Ne montri kiu min sekvas", "show_admin_badge": "Montri la insignon de administranto en mia profilo", "show_moderator_badge": "Montri la insignon de reguligisto en mia profilo", - "nsfw_clickthrough": "Ŝalti traklakan kaŝadon de kunsendaĵoj kaj antaŭmontroj de ligiloj por konsternaj statoj", + "nsfw_clickthrough": "Ŝalti traklakan kaŝadon de kunsendaĵoj kaj antaŭmontroj de ligiloj por konsternaj afiŝoj", "oauth_tokens": "Pecoj de OAuth", "token": "Peco", "refresh_token": "Aktualiga peco", @@ -556,19 +588,97 @@ "hide_shoutbox": "Kaŝi kriujon de nodo", "always_show_post_button": "Ĉiam montri ŝvebantan butonon por nova afiŝo", "mentions_new_style": "Pli mojosaj menciligiloj", - "mentions_new_place": "Meti menciojn sur apartan linion" + "mentions_new_place": "Meti menciojn sur apartan linion", + "lists_navigation": "Montri listojn en navigiloj", + "account_backup": "Savkopio de konto", + "account_backup_description": "Ĉi tio povigas vin elŝuti arĥivon de viaj afiŝoj kaj ĉiuj informoj pri via konto, sed ili ne jam povas enportiĝi en konton de Pleroma.", + "list_aliases_error": "Eraris akirado de kromnomoj: {error}", + "move_account_notes": "Se vi volas movi la konton aliloken, vi devas iri al via celata konto, kaj aldoni kromnomon ligitan al tie ĉi.", + "navbar_column_stretch": "Etendi navigan breton laŭ larĝeco de kolumnoj", + "posts": "Afiŝoj", + "notification_visibility_polls": "Finoj de enketoj kun via voĉo", + "conversation_display": "Aspekto de interparoloj", + "disable_sticky_headers": "Ne alglui kapojn de kolumnoj al supro de la ekrano", + "conversation_display_linear_quick": "Linia vido", + "use_websockets": "Uzi teĥnikaron «websockets» (tuja ĝisdatigo)", + "mention_link_display_full_for_remote": "plene nur je uzantoj foraj (ekz. {'@'}zozo{'@'}ekzemplo.org)", + "expert_mode": "Montri altnivelajn", + "setting_server_side": "Ĉi tiu agordo estas ligita al via profilo, kaj efektiviĝon en ĉiuj viaj salutoj kaj klientoj", + "post_look_feel": "Aspekto de afiŝoj", + "mention_links": "Menciaj ligiloj", + "email_language": "Lingvo de leteroj ricevotaj de la servilo", + "account_backup_table_head": "Savkopio", + "download_backup": "Elŝuti", + "backup_not_ready": "Ĉi tiu savkopio ne jam pretas.", + "remove_backup": "Forigi", + "list_backups_error": "Eraris akirado de listo de savkopioj: {error}", + "add_backup": "Fari novan savkopion", + "added_backup": "Aldonis novan savkopion.", + "add_backup_error": "Eraris aldono de nova savkopio: {error}", + "account_alias": "Kromnomoj de konto", + "account_alias_table_head": "Kromnomo", + "hide_list_aliases_error_action": "Fermi", + "remove_alias": "Forigi ĉi tiun kromnomon", + "new_alias_target": "Aldoni novan kromnomon (ekz. {example})", + "added_alias": "Kromnomo estas aldonita.", + "add_alias_error": "Eraris aldono de kromnomo: {error}", + "move_account": "Movi konton", + "move_account_target": "Celata konto (ekz. {example})", + "moved_account": "Konto moviĝis.", + "move_account_error": "Eraris movado de konto: {error}", + "wordfilter": "Vortofiltrado", + "word_filter_and_more": "Vortofiltrado kaj pli…", + "mute_bot_posts": "Silentigi afiŝojn de robotoj", + "hide_bot_indication": "Kaŝi markon de roboteco en afiŝoj", + "hide_wordfiltered_statuses": "Kaŝi vorte filtritajn afiŝojn", + "hide_muted_threads": "Kaŝi silentigitajn fadenojn", + "account_privacy": "Privateco", + "user_profiles": "Profiloj de uzantoj", + "hide_favorites_description": "Ne montri liston de miaj ŝatatoj (oni tamen sciiĝas)", + "conversation_display_tree": "Arba stilo", + "conversation_display_tree_quick": "Arba vido", + "show_scrollbars": "Montri rulumskalojn de flankaj kolumnoj", + "third_column_mode_none": "Neniam montri trian kolumnon", + "third_column_mode_notifications": "Kolumno de sciigoj", + "columns": "Kolumnoj", + "column_sizes": "Grandeco de kolumnoj", + "column_sizes_sidebar": "Flanka breto", + "column_sizes_content": "Enhavo", + "column_sizes_notifs": "Sciigoj", + "tree_advanced": "Permesi pli flekseblan navigadon en arba vido", + "conversation_display_linear": "Linia stilo", + "conversation_other_replies_button": "Montri la butonon pri «aliaj respondoj»", + "conversation_other_replies_button_below": "Sub afiŝoj", + "conversation_other_replies_button_inside": "En afiŝoj", + "max_depth_in_thread": "Maksimuma nombro de niveloj implicite montrataj en fadeno", + "auto_update": "Montri novajn afiŝojn memage", + "use_at_icon": "Montri simbolon {'@'} kiel bildon anstataŭ teksto", + "mention_link_display": "Montri menciajn ligilojn", + "mention_link_display_short": "ĉiam mallonge (ekz. {'@'}zozo)", + "mention_link_display_full": "ĉiam plene (ekz. {'@'}zozo{'@'}ekzemplo.org)", + "mention_link_show_avatar": "Montri profilbildon de uzanto apud la ligilo", + "mention_link_show_avatar_quick": "Montri profilbildon de uzanto apud mencioj", + "mention_link_fade_domain": "Malvigligi retnomojn (ekz. {'@'}ekzemplo.org en {'@'}zozo{'@'}ekzemplo.org)", + "mention_link_bolden_you": "Emfazi vian mencion, se vi estas menciita", + "mention_link_use_tooltip": "Montri karton de uzanto per klako al mencia ligilo", + "user_popover_avatar_action_close": "Fermi la ŝprucaĵon", + "user_popover_avatar_action_open": "Malfermi la profilon", + "user_popover_avatar_overlay": "Aperigi ŝprucaĵon pri uzanto sur profilbildo", + "show_yous": "Montri la markon «(Vi)»", + "user_popover_avatar_action_zoom": "Zomi la profilbildon", + "third_column_mode": "Kun sufiĉo da spaco, montri trian kolumnon kun" }, "timeline": { "collapse": "Maletendi", "conversation": "Interparolo", "error_fetching": "Eraris ĝisdatigo", - "load_older": "Montri pli malnovajn statojn", + "load_older": "Montri pli malnovajn afiŝojn", "no_retweet_hint": "Afiŝo estas markita kiel rekta aŭ nur por abonantoj, kaj ne eblas ĝin ripeti", "repeated": "ripetis", "show_new": "Montri novajn", "up_to_date": "Ĝisdata", - "no_more_statuses": "Neniuj pliaj statoj", - "no_statuses": "Neniuj statoj", + "no_more_statuses": "Neniuj pliaj afiŝoj", + "no_statuses": "Neniuj afiŝoj", "reload": "Enlegi ree", "error": "Eraris akirado de historio: {0}", "socket_reconnected": "Realtempa konekto fariĝis", @@ -594,7 +704,7 @@ "muted": "Silentigita", "per_day": "tage", "remote_follow": "Fore aboni", - "statuses": "Statoj", + "statuses": "Afiŝoj", "unblock": "Malbloki", "unblock_progress": "Malblokante…", "block_progress": "Blokante…", @@ -621,7 +731,8 @@ "grant_moderator": "Nomumi reguligiston", "revoke_admin": "Malnomumi administranton", "grant_admin": "Nomumi administranton", - "moderation": "Reguligado" + "moderation": "Reguligado", + "delete_user_data_and_deactivate_confirmation": "Tio ĉi por ĉiam forigos datumojn de tiu ĉi konto, kaj malaktivigos ĝin. Ĉu vi plene certas?" }, "show_repeats": "Montri ripetojn", "hide_repeats": "Kaŝi ripetojn", @@ -634,7 +745,15 @@ "solid": "Unueca fono", "disabled": "Senemfaze" }, - "edit_profile": "Redakti profilon" + "edit_profile": "Redakti profilon", + "deactivated": "Malaktiva", + "follow_cancel": "Nuligi peton", + "remove_follower": "Forigi abonanton", + "note": "Noto", + "note_blank": "(Neniu)", + "edit_note_apply": "Apliki", + "edit_note_cancel": "Nuligi", + "edit_note": "Redakti noton" }, "user_profile": { "timeline_title": "Historio de uzanto", @@ -654,7 +773,9 @@ "bookmark": "Legosigno", "reject_follow_request": "Rifuzi abonpeton", "accept_follow_request": "Akcepti abonpeton", - "add_reaction": "Aldoni reagon" + "add_reaction": "Aldoni reagon", + "toggle_expand": "Etendi aŭ maletendi sciigon por montri plenan afiŝon", + "toggle_mute": "Etendi aŭ maletendi afiŝon por montri silentigitan enhavon" }, "upload": { "error": { @@ -680,7 +801,19 @@ "load_all": "Enlegante ĉiujn {emojiAmount} bildosignojn", "load_all_hint": "Enlegis la {saneAmount} unuajn bildosignojn; enlego de ĉiuj povus kaŭzi problemojn pri efikeco.", "unicode": "Unikoda bildosigno", - "custom": "Propra bildosigno" + "custom": "Propra bildosigno", + "unicode_groups": { + "activities": "Agado", + "animals-and-nature": "Bestoj kaj naturo", + "flags": "Flagoj", + "food-and-drink": "Manĝaĵoj kaj trinkaĵoj", + "objects": "Aĵoj", + "people-and-body": "Homoj kaj korpo", + "smileys-and-emotion": "Mienbildoj kaj sentoj", + "symbols": "Simboloj", + "travel-and-places": "Vojaĝoj kaj lokoj" + }, + "regional_indicator": "Regiona marko {letter}" }, "polls": { "not_enough_options": "Tro malmultaj unikaj elektebloj en la enketo", @@ -721,7 +854,7 @@ "media_nsfw": "Devige marki vidaŭdaĵojn konsternaj", "media_removal_desc": "Ĉi tiu nodo forigas vidaŭdaĵojn de afiŝoj el la jenaj nodoj:", "media_removal": "Forigo de vidaŭdaĵoj", - "ftl_removal": "Forigo el la historio de «Konata reto»", + "ftl_removal": "Forigo el la «Federa historio»", "quarantine_desc": "Ĉi tiu nodo sendos nur publikajn afiŝojn al la jenaj nodoj:", "quarantine": "Kvaranteno", "reject_desc": "Ĉi tiu nodo ne akceptos mesaĝojn de la jenaj nodoj:", @@ -729,14 +862,16 @@ "accept_desc": "Ĉi tiu nodo nur akceptas mesaĝojn de la jenaj nodoj:", "accept": "Akcepti", "simple_policies": "Specialaj politikoj de la nodo", - "ftl_removal_desc": "Ĉi tiu nodo forigas la jenajn nodojn el la historio de «Konata reto»:" + "ftl_removal_desc": "Ĉi tiu nodo forigas la jenajn nodojn el la «Federa historio»:", + "instance": "Nodo", + "reason": "Kialo" }, "mrf_policies": "Ŝaltis politikon de Mesaĝa ŝanĝilaro (MRF)", "keyword": { "is_replaced_by": "→", "replace": "Anstataŭigi", "reject": "Rifuzi", - "ftl_removal": "Forigo el la historio de «La tuta konata reto»", + "ftl_removal": "Forigo el la historio de la «Federa historio»", "keyword_policies": "Politiko pri ĉefvortoj" }, "federation": "Federado", @@ -755,7 +890,9 @@ "load_older": "Enlegi pli malnovajn interagojn", "moves": "Migrado de uzantoj", "follows": "Novaj abonoj", - "favs_repeats": "Ripetoj kaj ŝatoj" + "favs_repeats": "Ripetoj kaj ŝatoj", + "emoji_reactions": "Bildosignaj reagoj", + "reports": "Raportoj" }, "errors": { "storage_unavailable": "Pleroma ne povis aliri deponejon de la foliumilo. Via saluto kaj viaj lokaj agordoj ne estos konservitaj, kaj vi eble renkontos neatenditajn problemojn. Provu permesi kuketojn." @@ -767,19 +904,19 @@ "show_full_subject": "Montri plenan temon", "thread_muted_and_words": ", enhavas vortojn:", "thread_muted": "Fadeno silentigita", - "copy_link": "Kopii ligilon al stato", - "status_unavailable": "Stato ne estas disponebla", + "copy_link": "Kopii ligilon al afiŝo", + "status_unavailable": "Afiŝo ne estas disponebla", "unmute_conversation": "Malsilentigi interparolon", "mute_conversation": "Silentigi interparolon", "replies_list": "Respondoj:", "reply_to": "Responde al", - "delete_confirm": "Ĉu vi certe volas forigi ĉi tiun staton?", + "delete_confirm": "Ĉu vi certe volas forigi ĉi tiun afiŝon?", "unbookmark": "Senlegosigni", "bookmark": "Legosigni", "pinned": "Fiksita", "unpin": "Malfiksi de profilo", "pin": "Fiksi al profilo", - "delete": "Forigi staton", + "delete": "Forigi afiŝon", "repeats": "Ripetoj", "favorites": "Ŝatoj", "status_deleted": "Ĉi tiu afiŝo foriĝis", @@ -788,7 +925,33 @@ "external_source": "Ekstera fonto", "mentions": "Mencioj", "you": "(Vi)", - "plus_more": "+{number} pli" + "plus_more": "+{number} pli", + "show_all_attachments": "Montri ĉiujn kunsendaĵojn", + "collapse_attachments": "Kaŝi iujn kunsendaĵojn", + "many_attachments": "Afiŝo havas {number} kunsendaĵo(j)n", + "show_attachment_in_modal": "Montri en vidilo de vidaŭdaĵoj", + "edit": "Redakti afiŝon", + "replies_list_with_others": "Respondoj (+{numReplies} alia): | Respondoj (+{numReplies} aliaj):", + "thread_show": "Malkaŝi ĉi tiun fadenon", + "thread_show_full": "Montri ĉion en ĉi tiu fadeno ({numStatus} afiŝon sume, maksimume en profundeco {depth}) | Montri ĉion en ĉi tiu fadeno ({numStatus} afiŝojn sume, maksimume en profundeco {depth})", + "show_all_conversation": "Montri plenan interparolon ({numStatus} alian afiŝon) | Montri plenan interparolon ({numStatus} aliajn afiŝojn)", + "edited_at": "(lastafoje redaktita je {time})", + "remove_attachment": "Forigi kunsendaĵon", + "show_attachment_description": "Antaŭvidi priskribon (malfermu kunsendaĵon por vidi plenan priskribon)", + "hide_attachment": "Kaŝi kunsendaĵon", + "attachment_stop_flash": "Ĉesigi ludilon de [Flash]", + "move_up": "Ŝovi kunsendaĵon antaŭen", + "move_down": "Ŝovi kunsendaĵon posten", + "thread_hide": "Kaŝi ĉi tiun fadenon", + "thread_show_full_with_icon": "{icon} {text}", + "thread_follow": "Montri ceteron de ĉi tiu fadeno ({numStatus} afiŝon sume) | Montri ceteron de ĉi tiu fadeno ({numStatus} afiŝojn sume)", + "thread_follow_with_icon": "{icon} {text}", + "ancestor_follow": "Vidi {numReplies} alian respondon sub ĉi tiu afiŝo | Vidi {numReplies} aliajn respondojn sub ĉi tiu afiŝo", + "ancestor_follow_with_icon": "{icon} {text}", + "show_all_conversation_with_icon": "{icon} {text}", + "show_only_conversation_under_this": "Montri nur respondojn al ĉi tiu afiŝo", + "status_history": "Historio de afiŝo", + "open_gallery": "Malfermi galerion" }, "time": { "years_short": "{0}j", @@ -822,14 +985,32 @@ "days_short": "{0}t", "day_short": "{0}t", "days": "{0} tagoj", - "day": "{0} tago" + "day": "{0} tago", + "unit": { + "days": "{0} tago | {0} tagoj", + "minutes": "{0} minuto | {0} minutoj", + "days_short": "{0}t", + "hours": "{0} horo | {0} horoj", + "hours_short": "{0}h", + "minutes_short": "{0}min", + "months": "{0} monato | {0} monatoj", + "months_short": "{0}mo", + "seconds": "{0} sekundo | {0} sekundoj", + "seconds_short": "{0}sek", + "weeks": "{0} semajno | {0} semajnoj", + "weeks_short": "{0}sem", + "years": "{0} jaro | {0} jaroj", + "years_short": "{0}j" + } }, "search": { "people": "Personoj", "no_results": "Neniuj rezultoj", "people_talking": "{count} personoj parolas", "person_talking": "{count} persono parolas", - "hashtags": "Kradvortoj" + "hashtags": "Kradvortoj", + "no_more_results": "Neniuj pliaj rezultoj", + "load_more": "Enlegi pliajn rezultojn" }, "display_date": { "today": "Hodiaŭ" @@ -876,5 +1057,68 @@ }, "shoutbox": { "title": "Kriujo" + }, + "report": { + "reporter": "Raportinto:", + "reported_user": "Raportito:", + "reported_statuses": "Raportitaj afiŝoj:", + "notes": "Notoj:", + "state": "Afiŝo:", + "state_open": "Malfermita", + "state_closed": "Fermita", + "state_resolved": "Solvita" + }, + "lists": { + "editing_list": "Redaktado de listo {listTitle}", + "lists": "Listoj", + "new": "Nova listo", + "title": "Nomo de listo", + "search": "Serĉi uzantojn", + "create": "Krei", + "save": "Konservi ŝanĝojn", + "delete": "Forigi liston", + "following_only": "Limigi al abonatoj", + "manage_lists": "Mastrumi listojn", + "manage_members": "Mastrumi listanojn", + "add_members": "Serĉi pliajn uzantojn", + "remove_from_list": "Forigi de listo", + "add_to_list": "Aldoni al listo", + "is_in_list": "Jam en listo", + "creating_list": "Kreado de nova listo", + "update_title": "Konservi nomon", + "really_delete": "Ĉu vi certe volas forigi la liston?", + "error": "Eraris umado je listoj: {0}" + }, + "update": { + "big_update_content": "Ni longe ne eldonis novan version, kaj tial aferoj eble aspektos iom malsame, ol antaŭe.", + "update_bugs": "Bonvolu raporti problemojn kaj erarojn ĉe {pleromaGitlab}, ĉar ni ŝanĝis multon, kaj kvankam ni zorge testas kaj mem uzas la prilaboratajn versiojn, ni tamen povas preteratenti ion. Ni bonvenigas viajn rimarkojn kaj proponojn pri renkontitaj eraroj aŭ proponoj plibonigi Pleromon.", + "big_update_title": "Bonvolu pacienci", + "update_bugs_gitlab": "GitLab de Pleroma", + "update_changelog": "Por legi detalojn pri ŝanĝoj, vidu {theFullChangelog}.", + "update_changelog_here": "la plenan ŝanĝaron", + "art_by": "Arto de {linkToArtist}" + }, + "unicode_domain_indicator": { + "tooltip": "Ĉi tiu retnomo enhavas signojn ekster ASCII." + }, + "announcements": { + "all_day_prompt": "Ĉi tio estas tuttaga okazo", + "page_header": "Anoncoj", + "title": "Anonco", + "mark_as_read_action": "Marki legita", + "post_placeholder": "Entajpu vian anoncon tie ĉi…", + "post_action": "Afiŝi", + "post_error": "Eraro: {error}", + "close_error": "Fermi", + "delete_action": "Forigi", + "start_time_prompt": "Komenca tempo: ", + "end_time_prompt": "Fina tempo: ", + "published_time_display": "Publikigita je {time}", + "start_time_display": "Komenciĝas je {time}", + "end_time_display": "Finiĝas je {time}", + "edit_action": "Redakti", + "submit_edit_action": "Afiŝi", + "cancel_edit_action": "Nuligi", + "inactive_message": "Ĉi tiu anonco estas neaktiva" } } diff --git a/src/i18n/fr.json b/src/i18n/fr.json @@ -53,7 +53,15 @@ "public": "Publique", "private": "Abonné⋅e⋅s seulement", "unlisted": "Non-listé" - } + }, + "undo": "Défaire", + "yes": "Oui", + "no": "Non", + "unpin": "Dégrafer l'élément", + "scroll_to_top": "Défiler au début", + "pin": "Agrafer l'élément", + "generic_error_message": "Une erreur est apparue : {0}", + "never_show_again": "Ne plus afficher" }, "image_cropper": { "crop_picture": "Rogner l'image", @@ -109,7 +117,14 @@ "chats": "Chats", "bookmarks": "Marques-Pages", "timelines": "Flux", - "home_timeline": "Flux personnel" + "home_timeline": "Flux personnel", + "edit_nav_mobile": "Personnaliser la barre de navigation", + "mobile_notifications": "Ouvrir les notifications (il y en a de nouvelles)", + "lists": "Listes", + "edit_pinned": "Éditer les éléments agrafés", + "edit_finish": "Édition terminée", + "mobile_sidebar": "(Dés)activer le panneau latéral", + "mobile_notifications_close": "Fermer les notifications" }, "notifications": { "broken_favorite": "Message inconnu, recherche en cours…", @@ -124,13 +139,16 @@ "reacted_with": "a réagi avec {0}", "follow_request": "veut vous suivre", "error": "Erreur de chargement des notifications : {0}", - "poll_ended": "Sondage terminé" + "poll_ended": "Sondage terminé", + "submitted_report": "Rapport envoyé" }, "interactions": { "favs_repeats": "Partages et favoris", "follows": "Nouveaux suivis", "load_older": "Chargez d'anciennes interactions", - "moves": "Migrations de comptes" + "moves": "Migrations de comptes", + "emoji_reactions": "Émoticônes de réaction", + "reports": "Rapports" }, "post_status": { "new_status": "Poster un nouveau statut", @@ -164,7 +182,10 @@ "preview_empty": "Vide", "preview": "Prévisualisation", "media_description": "Description de la pièce-jointe", - "post": "Post" + "post": "Post", + "edit_status": "Éditer le status", + "edit_remote_warning": "Des instances distantes pourraient ne pas supporter l'édition et seront incapables de recevoir la nouvelle version de votre post.", + "edit_unsupported_warning": "Pleroma ne supporte pas l'édition de mentions ni de sondages." }, "registration": { "bio": "Biographie", @@ -189,7 +210,9 @@ "reason_placeholder": "Cette instance modère les inscriptions manuellement.\nExpliquer ce qui motive votre inscription à l'administration.", "reason": "Motivation d'inscription", "register": "Enregistrer", - "email_language": "Dans quelle langue voulez-vous recevoir les emails du server ?" + "email_language": "Dans quelle langue voulez-vous recevoir les emails du server ?", + "bio_optional": "Biographie (optionnelle)", + "email_optional": "Courriel (optionnel)" }, "selectable_list": { "select_all": "Tout selectionner" @@ -645,7 +668,23 @@ "tree_fade_ancestors": "Montrer les parents du message courant en texte léger", "use_at_icon": "Montrer le symbole {'@'} comme une icône au lieu de textuelle", "mention_link_display_short": "toujours raccourcies (ex. {'@'}foo)", - "mention_link_show_tooltip": "Montrer le nom complet pour les comptes distants dans une info-bulle" + "mention_link_show_tooltip": "Montrer le nom complet pour les comptes distants dans une info-bulle", + "lists_navigation": "Afficher les listes dans la navigation", + "word_filter_and_more": "Filtrer par mots et plus ...", + "columns": "Colonnes", + "auto_update": "Afficher automatiquement les nouveaux posts", + "mention_link_use_tooltip": "Montrer le profil utilisateur en cliquant sur les liens de mentions", + "mention_link_show_avatar_quick": "Afficher l'avatar de l'utilisateur à côté des mentions", + "navbar_column_stretch": "Élargir la barre de navigation à la taille des colonnes", + "column_sizes": "Taille des colonnes", + "column_sizes_sidebar": "Panneau latéral", + "column_sizes_content": "Contenu", + "column_sizes_notifs": "Notifications", + "conversation_display_linear_quick": "Vue linéaire", + "use_websockets": "Utiliser les websockets (mises à jour en temps réel)", + "user_popover_avatar_action_zoom": "Zoomer sur l'avatar", + "user_popover_avatar_action_open": "Ouvrir le profil", + "conversation_display_tree_quick": "Vue arborescente" }, "timeline": { "collapse": "Fermer", @@ -661,7 +700,9 @@ "reload": "Recharger", "error": "Erreur lors de l'affichage du flux : {0}", "socket_broke": "Connexion temps-réel perdue : CloseEvent code {0}", - "socket_reconnected": "Connexion temps-réel établie" + "socket_reconnected": "Connexion temps-réel établie", + "quick_view_settings": "Afficher les réglages rapides", + "quick_filter_settings": "Afficher les filtres rapides" }, "status": { "favorites": "Favoris", @@ -700,7 +741,7 @@ "thread_hide": "Cacher ce fil", "thread_show": "Montrer ce fil", "thread_show_full_with_icon": "{icon} {text}", - "thread_follow": "Montrer le reste du fil ({numStatus} message, {depth} niveaux maximum) | Montrer le reste du fil ({numStatus} messages, {depth} niveaux maximum)", + "thread_follow": "Montrer le reste du fil ({numStatus} message) | Montrer le reste du fil ({numStatus} messages)", "thread_follow_with_icon": "{icon} {text}", "ancestor_follow": "Monter les {numReplies} autres réponses après ce message | Monter les {numReplies} autres réponses après ce message", "ancestor_follow_with_icon": "{icon} {text}", @@ -714,7 +755,10 @@ "move_up": "Décaler la pièce-jointe à gauche", "open_gallery": "Ouvrir la galerie", "thread_show_full": "Montrer tout le fil ({numStatus} message, {depth} niveaux maximum) | Montrer tout le fil ({numStatus} messages, {depth} niveaux maximum)", - "show_all_conversation": "Montrer tout le fil ({numStatus} autre message) | Montrer tout le fil ({numStatus} autre messages)" + "show_all_conversation": "Montrer tout le fil ({numStatus} autre message) | Montrer tout le fil ({numStatus} autre messages)", + "edit": "Éditer le status", + "edited_at": "(dernière édition {time})", + "status_history": "Historique du status" }, "user_card": { "approve": "Accepter", @@ -783,7 +827,8 @@ "bot": "Robot", "edit_profile": "Éditer le profil", "deactivated": "Désactivé", - "follow_cancel": "Annuler la requête" + "follow_cancel": "Annuler la requête", + "remove_follower": "Retirer l'abonné·e" }, "user_profile": { "timeline_title": "Flux du compte", @@ -893,7 +938,19 @@ "load_all": "Charger tout les {emojiAmount} émojis", "load_all_hint": "{saneAmount} émojis chargé, charger tout les émojis peuvent causer des problèmes de performances.", "stickers": "Stickers", - "keep_open": "Garder ouvert" + "keep_open": "Garder ouvert", + "unicode_groups": { + "activities": "Activités", + "animals-and-nature": "Animaux & nature", + "flags": "Drapeaux", + "food-and-drink": "Nourriture & boissons", + "objects": "Objets", + "people-and-body": "Personnes & Corps", + "smileys-and-emotion": "Emoticônes", + "symbols": "Symboles", + "travel-and-places": "Voyages & lieux" + }, + "regional_indicator": "Indicateur régional {letter}" }, "remote_user_resolver": { "error": "Non trouvé.", @@ -955,7 +1012,9 @@ "person_talking": "{count} personnes discutant", "hashtags": "Mot-dièses", "people_talking": "{count} personnes discutant", - "no_results": "Aucun résultats" + "no_results": "Aucun résultats", + "no_more_results": "Pas de résultats supplémentaires", + "load_more": "Charger plus de résultats" }, "password_reset": { "forgot_password": "Mot de passe oublié ?", @@ -996,5 +1055,47 @@ "delete": "Effacer", "message_user": "Message à {nickname}", "you": "Vous :" + }, + "lists": { + "new": "Nouvelle liste", + "title": "Titre de la liste", + "create": "Créer", + "save": "Sauvegarder les changements", + "delete": "Supprimer la liste", + "following_only": "Limiter aux abonné·e·s", + "manage_lists": "Gérer les listes", + "add_members": "Rechercher plus d'utilisateurs", + "remove_from_list": "Retirer de la liste", + "add_to_list": "Ajouter à la liste", + "is_in_list": "Déjà dans la liste", + "editing_list": "Édition de la liste {listTitle}", + "creating_list": "Création d'une nouvelle liste", + "really_delete": "Êtes-vous sûr·e de vouloir supprimer la liste ?", + "error": "Erreur en manipulant les listes : {0}", + "lists": "Listes", + "search": "Rechercher des utilisateurs", + "manage_members": "Gérer les membres des listes", + "update_title": "Sauvegarder le titre" + }, + "update": { + "update_bugs_gitlab": "GitLab du projet Pleroma", + "update_changelog": "Pour plus de détails sur les changements, consultez {theFullChangelog}.", + "update_changelog_here": "Liste compète des changements", + "art_by": "Œuvre par {linkToArtist}", + "big_update_content": "Nous n'avons pas fait de nouvelle version depuis un moment, les choses peuvent vous paraitre différentes de vos habitudes.", + "update_bugs": "Veuillez rapporter les problèmes sur {pleromaGitlab}, comme beaucoup de changements on été fait, même si nous testons entièrement et utilisons la version de dévelopement nous-même, nous avons pu en louper. Les retours et suggestions sont bienvenues sur ce que vous avez pu rencontrer, ou sur comment améliorer Pleroma (BE) et Pleroma-FE." + }, + "unicode_domain_indicator": { + "tooltip": "Ce domaine contient des caractères non ascii." + }, + "report": { + "reporter": "Rapporteur·euse :", + "reported_user": "Compte rapporté :", + "reported_statuses": "Status rapportés :", + "notes": "Notes :", + "state": "Status :", + "state_open": "Ouvert", + "state_closed": "Fermé", + "state_resolved": "Résolut" } } diff --git a/src/i18n/ko.json b/src/i18n/ko.json @@ -4,14 +4,15 @@ }, "features_panel": { "chat": "챗", - "gopher": "고퍼", + "gopher": "Gopher", "media_proxy": "미디어 프록시", "scope_options": "범위 옵션", "text_limit": "텍스트 제한", "title": "기능", "who_to_follow": "팔로우 추천", "upload_limit": "최대 파일용량", - "pleroma_chat_messages": "Pleroma 채트" + "pleroma_chat_messages": "Pleroma 채팅", + "shout": "외치기" }, "finder": { "error_fetching_user": "사용자 정보 불러오기 실패", @@ -21,12 +22,12 @@ "apply": "적용", "submit": "보내기", "loading": "로딩중…", - "peek": "숨기기", + "peek": "살짝 보기", "close": "닫기", "verify": "검사", "confirm": "확인", - "enable": "유효", - "disable": "무효", + "enable": "활성화", + "disable": "비활성화", "cancel": "취소", "dismiss": "무시", "show_less": "접기", @@ -34,18 +35,35 @@ "optional": "필수 아님", "retry": "다시 시도하십시오", "error_retry": "다시 시도하십시오", - "generic_error": "잘못되었습니다", + "generic_error": "에러가 발생했습니다", "more": "더 보기", "role": { "moderator": "중재자", "admin": "관리자" - } + }, + "undo": "취소", + "yes": "네", + "no": "아니오", + "unpin": "고정 해제", + "pin": "고정", + "scope_in_timeline": { + "private": "팔로워 전용", + "public": "공개", + "unlisted": "비표시", + "direct": "다이렉트" + }, + "flash_content": "클릭해서 플래시 컨텐츠 보기 (Ruffle 사용, 작동하지 않을 수 있습니다).", + "flash_security": "플래시 컨텐츠는 임의 코드 실행이 아직도 가능할 수 있기에 위험할 수 있습니다.", + "flash_fail": "플래시를 로드하지 못했습니다, 콘솔로 자세한 내용을 확인하세요.", + "scroll_to_top": "맨 위로 올라가기", + "generic_error_message": "에러가 발생했습니다: {0}", + "never_show_again": "다시 보지 않기" }, "login": { "login": "로그인", "description": "OAuth로 로그인", "logout": "로그아웃", - "password": "암호", + "password": "패스워드", "placeholder": "예시: lain", "register": "가입", "username": "사용자 이름", @@ -57,7 +75,7 @@ "enter_two_factor_code": "2단계인증 코드를 입력하십시오", "enter_recovery_code": "복구 코드를 입력하십시오", "authentication_code": "인증 코드", - "hint": "로그인하여 대화에 참가합시다" + "hint": "로그인해서 대화에 참여" }, "nav": { "about": "인스턴스 소개", @@ -71,68 +89,86 @@ "twkn": "알려진 네트워크", "user_search": "사용자 검색", "preferences": "환경설정", - "chats": "채트", + "chats": "채팅", "timelines": "타임라인", "who_to_follow": "추천된 사용자", "search": "검색", "bookmarks": "북마크", - "interactions": "대화", + "interactions": "알림", "administration": "관리", - "home_timeline": "홈 타임라인" + "home_timeline": "홈 타임라인", + "mobile_notifications": "알림 열기 (읽지 않은 알림이 있습니다)", + "lists": "리스트", + "edit_nav_mobile": "네비게이션 바 커스텀하기", + "edit_pinned": "상단 고정 편집", + "edit_finish": "편집 종료", + "mobile_notifications_close": "알림 닫기", + "mobile_sidebar": "모바일 사이드바 토글", + "announcements": "공지사항" }, "notifications": { "broken_favorite": "알 수 없는 게시물입니다, 검색합니다…", - "favorited_you": "당신의 게시물을 즐겨찾기", - "followed_you": "당신을 팔로우", - "load_older": "오래 된 알림 불러오기", + "favorited_you": "관심을 가짐", + "followed_you": "팔로우함", + "load_older": "이전 알림 불러오기", "notifications": "알림", "read": "읽음!", - "repeated_you": "당신의 게시물을 리핏", + "repeated_you": "리핏함", "no_more_notifications": "알림이 없습니다", "migrated_to": "이사했습니다", "reacted_with": "{0} 로 반응했습니다", "error": "알림 불러오기 실패: {0}", - "follow_request": "당신에게 팔로우 신청" + "follow_request": "팔로우 요청", + "submitted_report": "신고 내용을 전송함", + "poll_ended": "투표가 끝남" }, "post_status": { "new_status": "새 게시물 게시", - "account_not_locked_warning": "당신의 계정은 {0} 상태가 아닙니다. 누구나 당신을 팔로우 하고 팔로워 전용 게시물을 볼 수 있습니다.", + "account_not_locked_warning": "계정이 {0} 상태가 아닙니다. 누구나 당신을 팔로우 하고 팔로워 전용 게시물을 볼 수 있습니다.", "account_not_locked_warning_link": "잠김", "attachments_sensitive": "첨부물을 민감함으로 설정", "content_type": { "text/plain": "평문", "text/bbcode": "BBCode", - "text/markdown": "Markdown", + "text/markdown": "마크다운", "text/html": "HTML" }, - "content_warning": "주제 (필수 아님)", + "content_warning": "제목 (선택)", "default": "인천공항에 도착했습니다.", "direct_warning": "이 게시물을 멘션 된 사용자들에게만 보여집니다", - "posting": "게시", + "posting": "게시 중", "scope": { "direct": "다이렉트 - 멘션 된 사용자들에게만", "private": "팔로워 전용 - 팔로워들에게만", "public": "공개 - 공개 타임라인으로", - "unlisted": "비공개 - 공개 타임라인에 게시 안 함" + "unlisted": "비표시 - 공개 타임라인에는 안 보이게" }, - "preview_empty": "아무것도 없습니다", + "preview_empty": "비어있음", "preview": "미리보기", "scope_notice": { - "public": "이 글은 누구나 볼 수 있습니다" + "public": "누구나 볼 수 있습니다", + "private": "팔로워에게만 보여집니다", + "unlisted": "공개 타임라인이나 알려진 네트워크에는 보여지지 않습니다" }, - "media_description_error": "파일을 올리지 못하였습니다. 다시한번 시도하여 주십시오", - "empty_status_error": "글을 입력하십시오", - "media_description": "첨부파일 설명" + "media_description_error": "파일을 올리지 못했습니다, 다시 시도해 보세요", + "empty_status_error": "게시물이 비어 있습니다", + "media_description": "첨부파일 설명", + "direct_warning_to_all": "멘션한 모든 사용자에게 보여집니다.", + "edit_unsupported_warning": "Pleroma는 멘션이나 투표를 수정하는 기능을 지원하지 않습니다.", + "edit_status": "수정", + "edit_remote_warning": "수정 기능이 없는 다른 인스턴스에서는 수정한 사항이 반영되지 않을 수 있습니다.", + "post": "게시", + "direct_warning_to_first_only": "맨 앞에 멘션한 사용자들에게만 보여집니다." }, "registration": { "bio": "소개", "email": "이메일", - "fullname": "표시 되는 이름", - "password_confirm": "암호 확인", + "fullname": "표시될 이름", + "password_confirm": "패스워드 확인", "registration": "가입하기", "token": "초대 토큰", "captcha": "캡차", - "new_captcha": "이미지를 클릭해서 새로운 캡차", + "new_captcha": "이미지를 클릭해서 새로운 캡차 가져오기", "validations": { "username_required": "공백으로 둘 수 없습니다", "fullname_required": "공백으로 둘 수 없습니다", @@ -142,25 +178,32 @@ "password_confirmation_match": "패스워드와 일치해야 합니다" }, "fullname_placeholder": "예: 김례인", - "username_placeholder": "예: lain" + "username_placeholder": "예: lain", + "bio_placeholder": "예시\n안녕하세요, 례인입니다.\n일본 시외에서 애니메이션 아이돌을 하고 있습니다. Wired에서 절 보셨을 거예요.", + "bio_optional": "소개 (선택)", + "email_optional": "이메일 (선택)", + "reason": "가입하려는 이유", + "reason_placeholder": "이 인스턴스는 수동으로 가입을 승인하고 있습니다.\n왜 가입하고 싶은지 관리자에게 알려주세요.", + "register": "가입", + "email_language": "무슨 언어로 이메일을 받길 원하시나요?" }, "settings": { "attachmentRadius": "첨부물", "attachments": "첨부물", - "avatar": "아바타", - "avatarAltRadius": "아바타 (알림)", - "avatarRadius": "아바타", + "avatar": "프로필 사진", + "avatarAltRadius": "프로필 사진 (알림창)", + "avatarRadius": "프로필 사진", "background": "배경", "bio": "소개", "btnRadius": "버튼", "cBlue": "파랑 (답글, 팔로우)", "cGreen": "초록 (리트윗)", - "cOrange": "주황 (즐겨찾기)", + "cOrange": "주황 (관심글)", "cRed": "빨강 (취소)", - "change_password": "암호 바꾸기", - "change_password_error": "암호를 바꾸는 데 몇 가지 문제가 있습니다.", - "changed_password": "암호를 바꾸었습니다!", - "collapse_subject": "주제를 가진 게시물 접기", + "change_password": "패스워드 바꾸기", + "change_password_error": "패스워드를 바꾸는 데 문제가 있습니다.", + "changed_password": "패스워드가 바뀌었습니다!", + "collapse_subject": "제목이 있는 게시물 접기", "composing": "작성", "confirm_new_password": "새 패스워드 확인", "current_avatar": "현재 아바타", @@ -169,27 +212,27 @@ "data_import_export_tab": "데이터 불러오기 / 내보내기", "default_vis": "기본 공개 범위", "delete_account": "계정 삭제", - "delete_account_description": "데이터가 영구히 삭제되고 계정이 불활성화됩니다.", + "delete_account_description": "데이터가 영구히 삭제되고 계정이 비활성화됩니다.", "delete_account_error": "계정을 삭제하는데 문제가 있습니다. 계속 발생한다면 인스턴스 관리자에게 문의하세요.", - "delete_account_instructions": "계정 삭제를 확인하기 위해 아래에 패스워드 입력.", + "delete_account_instructions": "아래 패스워드를 입력하시면 계정이 삭제됩니다.", "export_theme": "프리셋 저장", "filtering": "필터링", - "filtering_explanation": "아래의 단어를 가진 게시물들은 뮤트 됩니다, 한 줄에 하나씩 적으세요", + "filtering_explanation": "이 단어를 가진 게시물들은 뮤트됩니다, 한 줄에 하나씩 적으세요", "follow_export": "팔로우 내보내기", - "follow_export_button": "팔로우 목록을 csv로 내보내기", + "follow_export_button": "팔로우 목록을 CSV 파일로 내보내기", "follow_export_processing": "진행 중입니다, 곧 다운로드 가능해 질 것입니다", "follow_import": "팔로우 불러오기", "follow_import_error": "팔로우 불러오기 실패", "follows_imported": "팔로우 목록을 불러왔습니다! 처리에는 시간이 걸립니다.", - "foreground": "전경", + "foreground": "표면", "general": "일반", "hide_attachments_in_convo": "대화의 첨부물 숨기기", "hide_attachments_in_tl": "타임라인의 첨부물 숨기기", "hide_isp": "인스턴스 전용 패널 숨기기", "preload_images": "이미지 미리 불러오기", - "hide_post_stats": "게시물 통계 숨기기 (즐겨찾기 수 등)", + "hide_post_stats": "게시물 통계 숨기기 (관심글 수 등)", "hide_user_stats": "사용자 통계 숨기기 (팔로워 수 등)", - "import_followers_from_a_csv_file": "csv 파일에서 팔로우 목록 불러오기", + "import_followers_from_a_csv_file": "CSV 파일에서 팔로우 목록 불러오기", "import_theme": "프리셋 불러오기", "inputRadius": "입력 칸", "checkboxRadius": "체크박스", @@ -197,58 +240,58 @@ "instance_default_simple": "(기본)", "interface": "인터페이스", "interfaceLanguage": "인터페이스 언어", - "invalid_theme_imported": "선택한 파일은 지원하는 플레로마 테마가 아닙니다. 아무런 변경도 일어나지 않았습니다.", + "invalid_theme_imported": "해당 파일은 지원되지 않는 Pleroma 테마입니다. 아무 일도 일어나지 않았습니다.", "limited_availability": "이 브라우저에서 사용 불가", "links": "링크", - "lock_account_description": "계정을 승인 된 팔로워들로 제한", + "lock_account_description": "팔로워를 승인해서 받도록 제한", "loop_video": "비디오 반복재생", - "loop_video_silent_only": "소리가 없는 비디오만 반복 재생 (마스토돈의 \"gifs\" 같은 것들)", + "loop_video_silent_only": "소리가 없는 비디오만 반복 재생 (마스토돈의 \"GIF\" 같은 것들)", "name": "이름", "name_bio": "이름 & 소개", - "new_password": "새 암호", - "notification_visibility": "보여 줄 알림 종류", + "new_password": "새 패스워드", + "notification_visibility": "보여질 알림 종류", "notification_visibility_follows": "팔로우", - "notification_visibility_likes": "좋아함", + "notification_visibility_likes": "관심글", "notification_visibility_mentions": "멘션", - "notification_visibility_repeats": "반복", + "notification_visibility_repeats": "리핏", "no_rich_text_description": "모든 게시물의 서식을 지우기", - "hide_follows_description": "내가 팔로우하는 사람을 표시하지 않음", - "hide_followers_description": "나를 따르는 사람을 숨기기", - "nsfw_clickthrough": "NSFW 이미지 \"클릭해서 보이기\"를 활성화", + "hide_follows_description": "팔로우 중인 사람 숨기기", + "hide_followers_description": "팔로워 숨기기", + "nsfw_clickthrough": "민감한 이미지를 숨기기", "oauth_tokens": "OAuth 토큰", "token": "토큰", "refresh_token": "토큰 새로 고침", - "valid_until": "까지 유효하다", + "valid_until": "만료일", "revoke_token": "취소", "panelRadius": "패널", - "pause_on_unfocused": "탭이 활성 상태가 아닐 때 스트리밍 멈추기", + "pause_on_unfocused": "탭이 포커스되지 않았을 땐 멈추기", "presets": "프리셋", "profile_background": "프로필 배경", "profile_banner": "프로필 배너", "profile_tab": "프로필", "radii_help": "인터페이스 모서리 둥글기 (픽셀 단위)", - "replies_in_timeline": "답글을 타임라인에", + "replies_in_timeline": "타임라인의 답글", "reply_visibility_all": "모든 답글 보기", - "reply_visibility_following": "나에게 직접 오는 답글이나 내가 팔로우 중인 사람에게서 오는 답글만 표시", - "reply_visibility_self": "나에게 직접 전송 된 답글만 보이기", - "saving_err": "설정 저장 실패", + "reply_visibility_following": "나에게 직접 오거나 내가 팔로우 중인 사람이 보낸 답글만 보기", + "reply_visibility_self": "나에게 직접 온 답글만 보기", + "saving_err": "설정을 저장하는 데 에러가 발생했습니다", "saving_ok": "설정 저장 됨", "security_tab": "보안", - "scope_copy": "답글을 달 때 공개 범위 따라가리 (다이렉트 메시지는 언제나 따라감)", - "set_new_avatar": "새 아바타 설정", + "scope_copy": "답글을 달 때 공개 범위 따라가기 (다이렉트 메시지는 언제나 따라감)", + "set_new_avatar": "새 프로필 사진 설정", "set_new_profile_background": "새 프로필 배경 설정", "set_new_profile_banner": "새 프로필 배너 설정", "settings": "설정", - "subject_input_always_show": "항상 주제 칸 보이기", - "subject_line_behavior": "답글을 달 때 주제 복사하기", - "subject_line_email": "이메일처럼: \"re: 주제\"", + "subject_input_always_show": "항상 제목 입력창 보이기", + "subject_line_behavior": "답글을 달 때 제목 복사하기", + "subject_line_email": "이메일처럼: \"re: 제목\"", "subject_line_mastodon": "마스토돈처럼: 그대로 복사", "subject_line_noop": "복사 안 함", - "stop_gifs": "GIF파일에 마우스를 올려서 재생", - "streaming": "최상단에 도달하면 자동으로 새 게시물 스트리밍", + "stop_gifs": "마우스를 올려서 GIF 재생", + "streaming": "최상단에 도달하면 알아서 새 게시물 가져오기", "text": "텍스트", "theme": "테마", - "theme_help": "16진수 색상코드(#rrggbb)를 사용해 색상 테마를 커스터마이즈.", + "theme_help": "16진수 색상코드(#rrggbb)를 사용해 색상을 조정하세요.", "theme_help_v2_1": "체크박스를 통해 몇몇 컴포넌트의 색상과 불투명도를 조절 가능, \"모두 지우기\" 버튼으로 덮어 씌운 것을 모두 취소.", "theme_help_v2_2": "몇몇 입력칸 밑의 아이콘은 전경/배경 대비 관련 표시등입니다, 마우스를 올려 자세한 정보를 볼 수 있습니다. 투명도 대비 표시등이 가장 최악의 경우를 나타낸다는 것을 유의하세요.", "tooltipRadius": "툴팁/경고", @@ -265,25 +308,42 @@ "keep_shadows": "그림자 유지", "keep_opacity": "불투명도 유지", "keep_roundness": "둥글기 유지", - "keep_fonts": "글자체 유지", + "keep_fonts": "글꼴 유지", "save_load_hint": "\"유지\" 옵션들은 다른 테마를 고르거나 불러 올 때 현재 설정 된 옵션들을 건드리지 않게 합니다, 테마를 내보내기 할 때도 이 옵션에 따라 저장합니다. 아무 것도 체크 되지 않았다면 모든 설정을 내보냅니다.", "reset": "초기화", "clear_all": "모두 지우기", - "clear_opacity": "불투명도 지우기" + "clear_opacity": "불투명도 지우기", + "help": { + "upgraded_from_v2": "PleromaFE가 업그레이드 되었기에, 테마가 기억하시던 것과 조금 다를 수 있습니다.", + "v2_imported": "불러온 파일은 이곳보다 이전 버전의 FE에서 만들어졌습니다. 호환성을 유지하겠지만 깨진 부분이 있을 수 있습니다.", + "migration_snapshot_ok": "혹시나 싶어서, 테마 스냅샷을 불러왔습니다. 테마 데이터를 불러와도 됩니다.", + "snapshot_source_mismatch": "버전이 충돌됩니다: 아마 FE가 롤백되고 다시 업데이트 되어서일 건데, 이전 버전 FE로 테마를 수정했다면 이전 버전 FE를 써보시는 게 좋고, 아니면 새 버전을 쓰세요.", + "future_version_imported": "불러온 파일은 이곳보다 새 버전의 FE에서 만들어졌습니다.", + "older_version_imported": "불러온 파일은 이곳보다 이전 버전의 FE에서 만들어졌습니다.", + "snapshot_present": "테마 스냅샷이 있어서, 모든 값이 덮어 씌워졌습니다. 직접 테마의 실제 데이터를 대신 불러와도 됩니다.", + "snapshot_missing": "파일에 스냅샷이 없어서 원래 보였던 것보다 다르게 보일 수 있습니다.", + "fe_upgraded": "버전 업데이트로 PleromaFE의 테마 엔진이 업그레이드 되었습니다.", + "fe_downgraded": "PleromaFE의 버전이 롤백되었습니다.", + "migration_napshot_gone": "뭔 일인진 모르겠지만 스냅샷이 없어서, 몇몇 개가 기억하신 것과 달리 보일 수 있습니다." + }, + "load_theme": "테마 불러오기", + "keep_as_is": "그대로 두기", + "use_snapshot": "이전 버전", + "use_source": "새 버전" }, "common": { "color": "색상", "opacity": "불투명도", "contrast": { - "hint": "대비율이 {ratio}입니다, 이것은 {context} {level}", + "hint": "색상 대비율이 {ratio}입니다, {context} {level}", "level": { - "aa": "AA등급 가이드라인에 부합합니다 (최소한도)", - "aaa": "AAA등급 가이드라인에 부합합니다 (권장)", - "bad": "아무런 가이드라인 등급에도 미치지 못합니다" + "aa": "접근성 가이드라인 AA등급을 충족합니다 (최소)", + "aaa": "접근성 가이드라인 AAA등급을 충족합니다 (권장)", + "bad": "접근성 가이드라인을 충족하지 못합니다" }, "context": { "18pt": "큰 (18pt 이상) 텍스트에 대해", - "text": "텍스트에 대해" + "text": "일반 텍스트에 대해" } } }, @@ -307,13 +367,23 @@ "faint_text": "흐려진 텍스트", "chat": { "border": "경계선", - "outgoing": "송신", - "incoming": "수신" + "outgoing": "보냄", + "incoming": "받음" }, "selectedMenu": "선택된 메뉴 요소", "selectedPost": "선택된 글", "icons": "아이콘", - "alert_warning": "경고" + "alert_warning": "경고", + "alert_neutral": "중립적", + "post": "게시물 / 유저 소개", + "popover": "툴팁, 메뉴, 프로필 카드", + "disabled": "비활성화", + "wallpaper": "배경사진", + "poll": "투표 그래프", + "highlight": "강조 요소", + "pressed": "눌렸을 때", + "toggled": "토글됨", + "tabs": "탭" }, "radii": { "_tab_label": "둥글기" @@ -344,23 +414,24 @@ "button": "버튼", "buttonHover": "버튼 (마우스 올렸을 때)", "buttonPressed": "버튼 (눌렸을 때)", - "buttonPressedHover": "Button (마우스 올림 + 눌림)", + "buttonPressedHover": "버튼 (마우스 올림 + 눌림)", "input": "입력칸" - } + }, + "hintV3": "그림자의 경우 {0} 표기법으로 다른 컬러 슬롯을 사용할 수 있습니다." }, "fonts": { - "_tab_label": "글자체", - "help": "인터페이스의 요소에 사용 될 글자체를 고르세요. \"커스텀\"은 시스템에 있는 폰트 이름을 정확히 입력해야 합니다.", + "_tab_label": "글꼴", + "help": "화면에 적용할 글꼴을 고르세요. \"직접 입력\"은 시스템에 있는 글꼴 이름을 정확히 입력해야 합니다.", "components": { "interface": "인터페이스", "input": "입력칸", "post": "게시물 텍스트", "postCode": "게시물의 고정폭 텍스트 (서식 있는 텍스트)" }, - "family": "글자체 이름", + "family": "글꼴 이름", "size": "크기 (px 단위)", "weight": "굵기", - "custom": "커스텀" + "custom": "직접 입력" }, "preview": { "header": "미리보기", @@ -371,8 +442,8 @@ "mono": "내용", "input": "인천공항에 도착했습니다.", "faint_link": "도움 되는 설명서", - "fine_print": "우리의 {0} 를 읽고 도움 되지 않는 것들을 배우자!", - "header_faint": "이건 괜찮아", + "fine_print": "우리의 {0}를 읽고 도움 되지 않는 것들을 배우자!", + "header_faint": "괜찮은 텍스트", "checkbox": "나는 약관을 대충 훑어보았습니다", "link": "작고 귀여운 링크" } @@ -381,44 +452,224 @@ "mfa": { "scan": { "secret_code": "키", - "title": "스캔" + "title": "스캔", + "desc": "2단계 인증 앱을 통해 QR 코드를 찍거나 키를 입력하세요:" }, "authentication_methods": "인증 방법", - "waiting_a_recovery_codes": "예비 코드를 수신하고 있습니다…", + "waiting_a_recovery_codes": "복구 코드를 가져오고 있습니다…", "recovery_codes": "복구 코드.", - "generate_new_recovery_codes": "새로운 복구 코드를 작성", - "title": "2단계인증", - "confirm_and_enable": "OTP 확인과 활성화", - "setup_otp": "OTP 설치", - "otp": "OTP" + "generate_new_recovery_codes": "새 복구 코드 생성", + "title": "2단계 인증", + "confirm_and_enable": "확인 & OTP 활성화", + "setup_otp": "OTP 설정", + "otp": "OTP", + "warning_of_generate_new_codes": "새 복구 코드를 생성하면, 이전 코드는 작동하지 않게 됩니다.", + "recovery_codes_warning": "복구 코드를 어딘가 안전한 곳에 적어 놓으세요 - 더 이상 이 코드를 보실 순 없습니다. 만약 2단계 인증 앱과 복구 코드 둘 다 접근할 수 없게 된다면 계정에 로그인할 수 없게 됩니다.", + "verify": { + "desc": "활성화하려면 2단계 인증 앱에서 받은 코드를 입력하세요:" + } }, "security": "보안", - "emoji_reactions_on_timeline": "이모지 반응을 타임라인으로 표시", - "avatar_size_instruction": "크기를 150x150 이상으로 설정할 것을 추장합니다.", + "emoji_reactions_on_timeline": "에모지 반응을 타임라인에 표시", + "avatar_size_instruction": "최소 150x150 픽셀보다 큰 사진을 업로드하시면 좋습니다.", "blocks_tab": "차단", "notification_setting_privacy": "보안", "user_mutes": "사용자", "notification_visibility_emoji_reactions": "반응", "profile_fields": { - "value": "내용" + "value": "내용", + "label": "프로필 추가정보", + "add_field": "필드 추가", + "name": "라벨" }, - "mutes_and_blocks": "침묵과 차단", - "chatMessageRadius": "챗 메시지", - "change_email": "메일주소 바꾸기", - "changed_email": "메일주소가 갱신되었습니다!", - "bot": "이 계정은 bot입니다", - "mutes_tab": "침묵", - "app_name": "앱 이름" + "mutes_and_blocks": "뮤트와 차단", + "chatMessageRadius": "채팅 메시지", + "change_email": "메일 주소 바꾸기", + "changed_email": "메일 주소가 바뀌었습니다!", + "bot": "이 계정은 자동 봇입니다", + "mutes_tab": "뮤트", + "app_name": "앱 이름", + "notification_setting_block_from_strangers": "팔로하지 않은 계정에서 보내는 알림 차단", + "autohide_floating_post_button": "알아서 새 게시물 버튼 숨기기 (모바일)", + "blocks_imported": "차단 목록을 가져왔습니다! 처리하는 데에 시간이 걸릴 수 있습니다.", + "mutes_imported": "뮤트 목록을 가져왔습니다! 처리하는 데에 시간이 걸릴 수 있습니다.", + "account_backup_description": "내 계정 정보와 게시물이 담긴 아카이브를 다운로드 받을 수 있지만, 아직 Pleroma로 다시 불러오는 기능은 지원하지 않습니다.", + "move_account_notes": "계정을 다른 곳으로 이사하려면, 이사 갈 계정으로 가셔서 별칭이 이 계정을 가리키도록 하세요.", + "hide_bot_indication": "게시물에서 봇 알림 숨기기", + "navbar_column_stretch": "상단 바를 컬럼 너비만큼 늘리기", + "show_admin_badge": "내 프로필에 \"관리자\" 배지 달기", + "sensitive_by_default": "게시물을 민감함으로 기본 설정", + "notification_mutes": "특정 사용자의 알림을 받지 않으려면, 뮤트를 사용하세요.", + "mention_link_fade_domain": "흐려진 도메인 (예: {'@'}foo{'@'}example.org 에서의 {'@'}example.org)", + "notification_blocks": "사용자를 차단하면 알림을 받지 않는데다 구독까지 취소하게 됩니다.", + "conversation_display_tree": "트리", + "save": "변경 사항을 저장", + "allow_following_move": "팔로우 중인 계정이 이사를 하면 자동으로 팔로우하기", + "expert_mode": "고급 설정 보기", + "setting_changed": "기본 설정과 다릅니다", + "setting_server_side": "이 설정은 계정과 묶여 있으며 연결된 모든 세션과 클라이언트에 영향을 줍니다", + "enter_current_password_to_confirm": "본인 확인을 위해 현재 패스워드를 입력하세요", + "post_look_feel": "게시물 모양새", + "mention_links": "멘션 링크", + "lists_navigation": "메뉴에 리스트 보이기", + "email_language": "서버로부터 이메일을 받을 언어", + "block_import": "차단 목록 가져오기", + "block_export_button": "차단 목록을 CSV 파일로 내보내기", + "block_import_error": "차단 목록을 가져오는 데에 문제가 발생했습니다", + "mute_export": "뮤트 목록 내보내기", + "mute_export_button": "뮤트 목록을 CSV 파일로 내보내기", + "mute_import": "뮤트 목록 가져오기", + "mute_import_error": "뮤트 목록을 가져오는 데에 문제가 발생했습니다", + "import_mutes_from_a_csv_file": "뮤트 목록을 CSV 파일에서 가져오기", + "account_backup": "계정 백업", + "account_backup_table_head": "백업", + "download_backup": "다운로드", + "backup_not_ready": "백업이 아직 준비되지 않았습니다.", + "remove_backup": "삭제", + "list_backups_error": "백업 리스트를 가져오는 데 에러가 발생했습니다: {error}", + "add_backup": "새 백업 만들기", + "added_backup": "새 백업 추가됨.", + "add_backup_error": "새 백업을 추가하는 데 에러가 발생했습니다: {error}", + "change_email_error": "메일 주소를 바꾸는 데 문제가 있습니다.", + "account_alias": "계정 별칭", + "always_show_post_button": "항상 떠다니는 게시물 작성 버튼 보기", + "mute_bot_posts": "봇 게시물 뮤트하기", + "hide_all_muted_posts": "뮤트한 게시물 숨기기", + "account_alias_table_head": "별칭", + "hide_list_aliases_error_action": "닫기", + "remove_alias": "이 별칭 삭제", + "new_alias_target": "새 별칭 추가 (예시. {example})", + "added_alias": "별칭이 추가되었습니다.", + "move_account": "계정 이사", + "move_account_target": "이사 갈 계정 (예시. {example})", + "moved_account": "계정을 이사했습니다.", + "discoverable": "검색 결과나 다른 서비스들에서 이 계정을 찾을 수 있도록 허용", + "pad_emoji": "에모지를 선택창에서 고를 때 띄어쓰기를 집어넣기", + "wordfilter": "단어 필터", + "word_filter_and_more": "단어 필터 그리고 더보기...", + "accent": "강조", + "hide_media_previews": "미디어 미리보기 숨기기", + "max_thumbnails": "게시물 하나 당 최대로 보여질 섬네일 개수 (비워두면 제한을 두지 않습니다)", + "hide_shoutbox": "인스턴스 외치기 숨기기", + "right_sidebar": "컬럼 순서 뒤집기", + "hide_wallpaper": "인스턴스 배경화면 가리기", + "use_one_click_nsfw": "민감한 첨부물을 클릭 한 번으로 열기", + "move_account_error": "계정을 이사하는 데 에러가 발생했습니다: {error}", + "hide_muted_posts": "뮤트한 사용자의 게시물 숨기기", + "hide_filtered_statuses": "필터된 모든 게시물 숨기기", + "hide_wordfiltered_statuses": "단어 필터된 게시물 숨기기", + "use_contain_fit": "첨부파일의 섬네일을 자르지 않음", + "hide_muted_threads": "뮤트한 스레드 숨기기", + "import_blocks_from_a_csv_file": "CSV 파일에서 차단 목록 불러오기", + "play_videos_in_modal": "팝업 프레임에서 비디오를 재생", + "file_export_import": { + "backup_restore": "설정 백업", + "backup_settings": "설정을 파일로 백업", + "backup_settings_theme": "설정과 테마를 파일로 백업", + "restore_settings": "파일에서 설정 복구하기", + "errors": { + "invalid_file": "해당 파일은 지원되지 않는 Pleroma 백업입니다. 아무 일도 일어나지 않았습니다.", + "file_too_new": "호환되지 않는 버전: {fileMajor}, 이 PleromaFE (설정 버전 {feMajor}) 가 너무 낡아서 처리할 수 없습니다", + "file_too_old": "호환되지 않는 버전: {fileMajor}, 파일 버전이 너무 낡아서 처리할 수 없습니다 (지원되는 최소 설정 버전 {feMajor})", + "file_slightly_new": "파일 마이너 버전이 달라서, 몇몇 설정들이 적용되지 않았을 수 있습니다" + } + }, + "account_privacy": "사생활 보안", + "new_email": "새 메일 주소", + "hide_favorites_description": "내 관심글을 보이지 않음 (알림은 갑니다)", + "hide_follows_count_description": "팔로우 중 숫자 숨기기", + "hide_followers_count_description": "팔로워 숫자 숨기기", + "no_mutes": "뮤트 없음", + "search_user_to_block": "차단할 사람 검색하기", + "search_user_to_mute": "뮤트할 사람 검색하기", + "posts": "게시물", + "notification_visibility_moves": "계정 이사", + "notification_visibility_polls": "참여한 투표가 끝남", + "no_blocks": "차단 없음", + "reply_visibility_self_short": "내 답글만 보기", + "reply_visibility_following_short": "팔로우 중인 사람들끼리의 답글 보기", + "user_profiles": "사용자 프로필", + "show_moderator_badge": "내 프로필에 \"중재자\" 배지 달기", + "type_domains_to_mute": "뮤트할 도메인 검색하기", + "disable_sticky_headers": "컬럼 헤더를 화면 상단에 고정하지 않음", + "auto_update": "알아서 새 게시물 가져오기", + "minimal_scopes_mode": "공개 범위 선택지 줄이기", + "reset_avatar": "프로필 사진 초기화", + "reset_avatar_confirm": "정말 프로필 사진을 초기화할까요?", + "reset_profile_background": "프로필 배경 초기화", + "reset_profile_banner": "프로필 배너 초기화", + "reset_banner_confirm": "정말 프로필 배너를 초기화할까요?", + "reset_background_confirm": "정말 프로필 배경을 초기화할까요?", + "useStreamingApi": "실시간으로 게시물과 알림 받기", + "use_websockets": "웹소켓 사용 (실시간 업데이트)", + "upload_a_photo": "사진 업로드", + "conversation_display": "대화 표시 모양", + "conversation_display_tree_quick": "트리 뷰", + "show_scrollbars": "측면 컬럼의 스크롤바 보기", + "conversation_other_replies_button_inside": "게시물 안에 놓기", + "notification_setting_hide_notification_contents": "푸시 알림에서 보낸 사람과 내용을 숨김", + "virtual_scrolling": "타임라인 렌더링 최적화", + "use_at_icon": "{'@'} 문자를 텍스트 대신 아이콘으로 표시", + "mention_link_display": "멘션에 링크 표시", + "mention_link_display_short": "항상 짧은 이름 사용 (예: {'@'}foo)", + "mention_link_display_full_for_remote": "다른 인스턴스 사용자만 이름 전부 보기 (예: {'@'}foo{'@'}example.org)", + "mention_link_display_full": "항상 이름 전부 보기 (예: {'@'}foo{'@'}example.org)", + "mention_link_use_tooltip": "멘션 링크를 누르면 사용자 카드 보기", + "mention_link_show_avatar": "링크 옆에 프로필 사진 보기", + "mention_link_bolden_you": "누가 날 멘션했을 때 멘션을 강조 표시", + "user_popover_avatar_action_zoom": "사진 키우기", + "greentext": "밈 화살표", + "show_yous": "\"(당신)\" 보이기", + "notification_setting_filters": "필터", + "more_settings": "추가 설정", + "user_popover_avatar_action_open": "프로필 열기", + "version": { + "frontend_version": "프론트엔드 버전", + "title": "버전", + "backend_version": "백엔드 버전" + }, + "fun": "즐겁다", + "domain_mutes": "도메인", + "third_column_mode": "공간이 충분하면, 세 번째 컬럼 채우기", + "third_column_mode_none": "세 번째 컬럼 안 보기", + "third_column_mode_notifications": "알림 컬럼", + "third_column_mode_postform": "게시물 편집창과 내비게이션", + "columns": "컬럼", + "column_sizes": "컬럼 크기", + "column_sizes_sidebar": "사이드바", + "column_sizes_content": "내용", + "column_sizes_notifs": "알림", + "tree_advanced": "트리 뷰에서 더 유연한 탐색을 허용", + "tree_fade_ancestors": "현재 게시물보다 상단의 게시물들을 흐린 텍스트로 표시", + "conversation_display_linear": "선형", + "conversation_display_linear_quick": "선형 뷰", + "conversation_other_replies_button": "\"답글 더 보기\" 버튼을", + "conversation_other_replies_button_below": "게시물 아래에 놓기", + "max_depth_in_thread": "기본적으로 보일 최대 깊이", + "user_popover_avatar_action": "프로필 카드의 사진 클릭 시", + "user_popover_avatar_action_close": "카드 닫기", + "user_popover_avatar_overlay": "프로필 카드를 프로필 사진 위에 띄우기", + "post_status_content_type": "게시물 내용 형식", + "list_aliases_error": "별칭을 가져오는 중 에러 발생: {error}", + "add_alias_error": "별칭을 추가하는 중 에러 발생: {error}", + "mention_link_show_avatar_quick": "멘션 옆에 유저 프로필 사진을 보임" }, "timeline": { "collapse": "접기", "conversation": "대화", "error_fetching": "업데이트 불러오기 실패", - "load_older": "더 오래 된 게시물 불러오기", - "no_retweet_hint": "팔로워 전용, 다이렉트 메시지는 반복할 수 없습니다", - "repeated": "반복 됨", - "show_new": "새로운 것 보기", - "up_to_date": "최신 상태" + "load_older": "이전 게시물 불러오기", + "no_retweet_hint": "팔로워 전용 게시물과 다이렉트 메시지는 리핏할 수 없습니다", + "repeated": "리핏함", + "show_new": "새 게시물 보기", + "up_to_date": "최신", + "error": "타임라인을 가져오지 못했습니다: {0}", + "reload": "새로고침", + "no_statuses": "게시물 없음", + "no_more_statuses": "새 게시물 없음", + "socket_reconnected": "실시간 연결 됨", + "socket_broke": "실시간 연결이 끊어짐: CloseEvent 코드 {0}", + "quick_filter_settings": "빠른 필터 설정" }, "user_card": { "approve": "승인", @@ -426,22 +677,70 @@ "blocked": "차단 됨!", "deny": "거부", "follow": "팔로우", - "follow_sent": "요청 보내짐!", + "follow_sent": "요청 보냄!", "follow_progress": "요청 중…", - "follow_unfollow": "팔로우 중지", + "follow_unfollow": "언팔로우", "followees": "팔로우 중", "followers": "팔로워", "following": "팔로우 중!", - "follows_you": "당신을 팔로우 합니다!", + "follows_you": "나를 팔로우 합니다!", "its_you": "당신입니다!", - "mute": "침묵", - "muted": "침묵 됨", - "per_day": "/ 하루", - "remote_follow": "원격 팔로우", - "statuses": "게시물" + "mute": "뮤트", + "muted": "뮤트 됨", + "per_day": "개 / 일", + "remote_follow": "다른 인스턴스에서 팔로우", + "statuses": "게시물", + "unmute_progress": "뮤트 해제 중…", + "unblock_progress": "차단 해제 중…", + "admin_menu": { + "revoke_moderator": "중재자 탄핵", + "sandbox": "게시물 공개 범위를 팔로워 전용으로 강제", + "disable_any_subscription": "누구도 팔로우를 못하도록 막기", + "delete_user_data_and_deactivate_confirmation": "영구적으로 이 계정의 데이터가 삭제되고 비활성화 됩니다. 정말로 괜찮겠습니까?", + "moderation": "관리", + "grant_admin": "관리자로 임명", + "grant_moderator": "중재자로 임명", + "disable_remote_subscription": "다른 인스턴스에서 팔로우하지 못하도록 막기", + "activate_account": "계정 활성화", + "deactivate_account": "계정 비활성화", + "delete_account": "계정 삭제", + "force_nsfw": "모든 게시물을 민감한 내용으로 표시", + "strip_media": "게시물에서 미디어 제거", + "revoke_admin": "관리자 탄핵", + "force_unlisted": "게시물 공개 범위를 비표시로 강제", + "quarantine": "연합 타임라인에서 사용자 게시물 비허용", + "delete_user": "사용자 삭제" + }, + "deactivated": "비활성화됨", + "edit_profile": "프로필 편집", + "favorites": "관심글", + "follow_cancel": "팔로우 요청 취소", + "unmute": "뮤트 해제", + "mute_progress": "뮤트 중…", + "hidden": "숨겨짐", + "media": "미디어", + "mention": "멘션", + "message": "메시지", + "remove_follower": "팔로워 삭제", + "report": "신고", + "subscribe": "구독", + "unsubscribe": "구독 해제", + "unblock": "차단 해제", + "block_progress": "차단 중…", + "hide_repeats": "리핏 숨기기", + "show_repeats": "리핏 보기", + "bot": "봇", + "highlight": { + "disabled": "강조 표시 없음", + "striped": "줄무늬 배경", + "solid": "단색 배경", + "side": "옆트임" + } }, "user_profile": { - "timeline_title": "사용자 타임라인" + "timeline_title": "사용자 타임라인", + "profile_does_not_exist": "죄송하지만, 이 프로필은 존재하지 않습니다.", + "profile_loading_error": "죄송하지만, 프로필을 불러오는 데 에러가 발생했습니다." }, "who_to_follow": { "more": "더 보기", @@ -449,38 +748,60 @@ }, "tool_tip": { "media_upload": "미디어 업로드", - "repeat": "반복", + "repeat": "리핏", "reply": "답글", - "favorite": "즐겨찾기", - "user_settings": "사용자 설정" + "favorite": "관심글", + "user_settings": "사용자 설정", + "add_reaction": "반응 추가", + "accept_follow_request": "팔로우 요청 승인", + "reject_follow_request": "팔로우 요청 거절", + "bookmark": "북마크" }, "upload": { "error": { "base": "업로드 실패.", "file_too_big": "파일이 너무 커요 [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]", - "default": "잠시 후에 다시 시도해 보세요" + "default": "잠시 후에 다시 시도해 보세요", + "message": "업로드 실패: {0}" }, "file_size_units": { - "B": "바이트", - "KiB": "키비바이트", - "MiB": "메비바이트", - "GiB": "기비바이트", - "TiB": "테비바이트" + "B": "B", + "KiB": "KiB", + "MiB": "MiB", + "GiB": "GiB", + "TiB": "TiB" } }, "interactions": { "follows": "새 팔로워", - "favs_repeats": "반복과 즐겨찾기", - "moves": "계정 통합" + "favs_repeats": "리핏과 관심", + "moves": "계정 이동", + "emoji_reactions": "에모지 반응", + "reports": "신고", + "load_older": "이전 반응 불러오기" }, "emoji": { - "load_all": "전체 {emojiAmount} 이모지 불러오기", - "unicode": "Unicode 이모지", - "custom": "전용 이모지", - "add_emoji": "이모지 넣기", - "search_emoji": "이모지 검색", - "emoji": "이모지", - "stickers": "스티커" + "load_all": "전체 {emojiAmount}개의 에모지 불러오기", + "unicode": "Unicode 에모지", + "custom": "전용 에모지", + "add_emoji": "에모지 넣기", + "search_emoji": "에모지 검색", + "emoji": "에모지", + "stickers": "스티커", + "load_all_hint": "첫 {saneAmount}개의 에모지를 불러왔습니다, 에모지를 전부 불러오면 성능 저하가 있을 수 있습니다.", + "unicode_groups": { + "people-and-body": "사람 & 몸", + "smileys-and-emotion": "웃는 얼굴 & 감정", + "travel-and-places": "여행 & 장소", + "activities": "활동", + "animals-and-nature": "동물 & 자연", + "flags": "깃발", + "food-and-drink": "음식 & 음료", + "objects": "사물", + "symbols": "기호" + }, + "keep_open": "열린 채로 두기", + "regional_indicator": "지역 표시기 {letter}" }, "polls": { "add_poll": "투표를 추가", @@ -493,11 +814,16 @@ "option": "선택지", "add_option": "선택지 추가", "expired": "투표는 {0} 전에 마감되었습니다", - "expires_in": "투표는 {0}에 마감됩니다" + "expires_in": "투표는 {0}에 마감됩니다", + "single_choice": "하나만 선택", + "multiple_choices": "여러 개 선택", + "not_enough_options": "선택지가 너무 적습니다" }, "media_modal": { "next": "다음", - "previous": "이전" + "previous": "이전", + "counter": "{current} / {total}", + "hide": "미디어 뷰어 닫기" }, "importer": { "error": "이 파일을 가져올 때 오류가 발생하였습니다.", @@ -511,14 +837,14 @@ "crop_picture": "사진 자르기" }, "exporter": { - "processing": "처리중입니다, 처리가 끝나면 파일을 다운로드하라는 지시가 있겠습니다", + "processing": "처리중입니다, 곧 파일을 다운로드할 수 있습니다", "export": "내보내기" }, "domain_mute_card": { - "unmute_progress": "침묵을 해제중…", - "unmute": "침묵 해제", - "mute_progress": "침묵으로 설정중…", - "mute": "침묵" + "unmute_progress": "뮤트 해제 중…", + "unmute": "뮤트 해제", + "mute_progress": "뮤트 중…", + "mute": "뮤트" }, "about": { "staff": "운영자", @@ -536,21 +862,25 @@ "accept_desc": "이 인스턴스에서는 아래의 인스턴스로부터 보내온 투고만이 접수됩니다:", "reject": "거부", "accept": "허가", - "simple_policies": "인스턴스 특유의 폴리시" + "simple_policies": "인스턴스 특유의 정책", + "instance": "인스턴스", + "reason": "사유", + "not_applicable": "없음" }, - "mrf_policies": "사용되는 MRF 폴리시", + "mrf_policies": "사용되는 MRF 정책", "keyword": { "is_replaced_by": "→", "replace": "바꾸기", "reject": "거부", "ftl_removal": "\"알려진 모든 네트워크\" 타임라인에서 제외", - "keyword_policies": "단어 폴리시" + "keyword_policies": "단어 정책" }, - "federation": "연합" + "federation": "연합", + "mrf_policies_desc": "MRF 정책은 이 인스턴스의 페더레이션 동작을 제어하고 있습니다. 적용되고 있는 정책은 다음과 같습니다:" } }, "shoutbox": { - "title": "Shoutbox" + "title": "외치기" }, "time": { "years_short": "{0} 년", @@ -565,8 +895,8 @@ "second_short": "{0} 초", "seconds": "{0} 초", "second": "{0} 초", - "now_short": "방금", - "now": "방끔", + "now_short": "지금", + "now": "방금", "months_short": "{0} 달 전", "month_short": "{0} 달 전", "months": "{0} 달 전", @@ -583,13 +913,205 @@ "days_short": "{0} 일", "day_short": "{0} 일", "days": "{0} 일", - "day": "{0} 일" + "day": "{0} 일", + "unit": { + "weeks": "{0}주 | {0}주", + "minutes": "{0}분 | {0}분", + "seconds": "{0}초 | {0}초", + "seconds_short": "{0}초", + "weeks_short": "{0}주", + "years": "{0}년 | {0}년", + "years_short": "{0}년", + "days": "{0}일 | {0}일", + "days_short": "{0}일", + "hours": "{0}시간 | {0}시간", + "hours_short": "{0}시간", + "minutes_short": "{0}분", + "months": "{0}달 | {0}달", + "months_short": "{0}달" + }, + "in_future": "{0} 후" }, "remote_user_resolver": { "error": "찾을 수 없습니다.", - "searching_for": "검색중" + "searching_for": "검색:", + "remote_user_resolver": "다른 인스턴스 사용자 안내기" }, "selectable_list": { "select_all": "모두 선택" + }, + "lists": { + "title": "리스트 제목", + "search": "사용자 검색하기", + "lists": "리스트", + "new": "리스트 만들기", + "create": "만들기", + "delete": "리스트 삭제", + "following_only": "팔로우 중인 사람들만", + "manage_lists": "리스트 관리", + "manage_members": "멤버 관리", + "remove_from_list": "리스트에서 제거", + "add_to_list": "리스트에 추가", + "is_in_list": "리스트에 이미 있음", + "editing_list": "{listTitle} 리스트 편집", + "update_title": "제목 저장", + "really_delete": "리스트를 삭제하시겠어요?", + "save": "변경 사항을 저장", + "creating_list": "새 리스트 만들기", + "add_members": "사용자 추가", + "error": "리스트를 조작하는 데 오류가 발생했습니다: {0}" + }, + "search": { + "no_more_results": "결과 더 없음", + "load_more": "결과 더 불러오기", + "people": "사람", + "hashtags": "해시태그", + "person_talking": "{count}명이 말하는 중", + "people_talking": "{count}명이 말하는 중", + "no_results": "결과 없음" + }, + "password_reset": { + "forgot_password": "패스워드를 잊으셨나요?", + "password_reset": "패스워드 재설정", + "placeholder": "이메일 주소 또는 사용자 이름", + "password_reset_required_but_mailer_is_disabled": "패스워드 초기화를 하셔야 하지만, 못 하게 막혀 있습니다. 인스턴스 관리자에게 문의해주세요.", + "check_email": "패스워드 초기화를 위해 이메일을 확인해주세요.", + "return_home": "홈으로 돌아가기", + "password_reset_required": "로그인하려면 패스워드를 초기화해야 합니다.", + "password_reset_disabled": "패스워드 초기화를 못 하게 되어 있습니다. 인스턴스 관리자에게 문의해주세요.", + "instruction": "이메일 주소 또는 사용자 이름을 입력하세요. 패스워드 초기화 링크를 메일로 보내드립니다.", + "too_many_requests": "너무 많은 시도를 했습니다, 나중에 다시 해주세요." + }, + "chats": { + "you": "당신:", + "delete": "삭제", + "new": "새 채팅", + "chats": "채팅", + "empty_message_error": "메시지가 비어 있습니다", + "more": "더 보기", + "error_loading_chat": "왜인진 모르겠는데 채팅을 불러오지 못했습니다.", + "error_sending_message": "왜인진 모르겠는데 메시지를 전송하지 못했습니다.", + "delete_confirm": "이 메시지를 정말 지울까요?", + "empty_chat_list_placeholder": "채팅이 없네요. 새 채팅을 시작해보세요!", + "message_user": "{nickname}에게 메시지" + }, + "file_type": { + "audio": "오디오", + "video": "영상", + "image": "사진", + "file": "파일" + }, + "display_date": { + "today": "오늘" + }, + "update": { + "big_update_title": "양해해주세요", + "update_bugs_gitlab": "Pleroma GitLab", + "update_changelog_here": "변경 내역", + "update_changelog": "무엇이 바뀌었는지 자세히 알아보시려면, {theFullChangelog}을 참조하세요.", + "big_update_content": "저희가 한동안 릴리즈를 안 해서, 익숙하셨던 생김새나 경험과 많이 달라졌을 수 있습니다.", + "update_bugs": "저희가 비록 테스트를 많이 하고 직접 개발 버전을 쓰기도 하지만, 많이 바꾸기도 했고, 몇몇 가지 놓친 점들이 있을 터이니, 사용하면서 불편한 점이나 문제는 {pleromaGitlab}에 제보해주시면 감사하겠습니다. 저희는 겪으신 문제점이나 Pleroma와 Pleroma-FE에 대한 피드백과 제안을 환영합니다." + }, + "unicode_domain_indicator": { + "tooltip": "이 도메인은 아스키 문자가 아닌 문자를 포함하고 있습니다." + }, + "status": { + "mute_conversation": "대화 뮤트", + "thread_muted_and_words": ", 단어 포함:", + "unpin": "프로필에서 고정 해제", + "replies_list_with_others": "답글 (+{numReplies}개): | 답글 (+{numReplies}개):", + "show_attachment_in_modal": "미디어 모달에서 보기", + "thread_hide": "이 스레드 숨기기", + "show_attachment_description": "설명 미리보기 (첨부물을 열어서 전체 설명 보기)", + "thread_show_full": "이 스레드를 전부 들춰보기 (총 {numStatus}개 있음, 최대 깊이 {depth}) | 이 스레드를 전부 들춰보기 (총 {numStatus}개 있음, 최대 깊이 {depth})", + "thread_follow": "이 스레드의 나머지 부분 보기 (총 {numStatus}개) | 이 스레드의 나머지 부분 보기 (총 {numStatus}개)", + "status_history": "게시물 이력", + "show_all_conversation": "전체 대화 보기 ({numStatus}개 더 있음) | 전체 대화 보기 ({numStatus}개 더 있음)", + "repeats": "리핏", + "delete": "삭제", + "edit": "수정", + "favorites": "관심글", + "edited_at": "({time}에 마지막으로 수정됨)", + "pin": "프로필에 고정", + "pinned": "고정됨", + "bookmark": "북마크", + "unbookmark": "북마크 해제", + "delete_confirm": "정말 지우시겠어요?", + "reply_to": "답글", + "mentions": "멘션", + "replies_list": "답글:", + "unmute_conversation": "대화 뮤트 해제", + "thread_muted": "스레드 뮤트됨", + "status_unavailable": "게시물 접근 불가", + "copy_link": "게시물 링크 복사", + "external_source": "원본 페이지", + "show_full_subject": "전체 제목 보기", + "hide_full_subject": "전체 제목 숨기기", + "show_content": "내용 보기", + "hide_content": "내용 숨기기", + "status_deleted": "지워진 게시물입니다", + "nsfw": "민감한 내용", + "expand": "펼치기", + "you": "(당신)", + "plus_more": "+{number}개 더 있음", + "many_attachments": "{number}개의 첨부물을 가짐", + "show_all_attachments": "첨부물 전부 보이기", + "hide_attachment": "첨부물 숨기기", + "collapse_attachments": "첨부물 접기", + "remove_attachment": "첨부물 지우기", + "attachment_stop_flash": "플래시 플레이어 정지", + "move_up": "첨부물 왼쪽으로 밀기", + "move_down": "첨부물 오른쪽으로 밀기", + "open_gallery": "갤러리 열기", + "thread_show": "이 스레드 보이기", + "thread_show_full_with_icon": "{icon} {text}", + "thread_follow_with_icon": "{icon} {text}", + "ancestor_follow_with_icon": "{icon} {text}", + "show_all_conversation_with_icon": "{icon} {text}", + "ancestor_follow": "이 게시물 아래 {numReplies}개 답글 더 보기 | 이 게시물 아래 {numReplies}개 답글 더 보기", + "show_only_conversation_under_this": "이 게시물의 답글만 보기" + }, + "errors": { + "storage_unavailable": "Pleroma가 브라우저 저장소에 접근할 수 없습니다. 로그인이 풀리거나 로컬 설정이 초기화 되는 등 예상치 못한 문제를 겪을 수 있습니다. 쿠키를 활성화 해보세요." + }, + "report": { + "reporter": "신고자:", + "reported_statuses": "신고된 게시물:", + "notes": "기타:", + "state": "상태:", + "state_open": "열림", + "state_closed": "닫힘", + "reported_user": "신고된 사용자:", + "state_resolved": "해결됨" + }, + "user_reporting": { + "title": "{0} 신고", + "add_comment_description": "이 신고서는 내 인스턴스의 중재자에게 전달됩니다. 왜 이 계정을 신고하려는지 좀 더 자세히 알려주세요:", + "additional_comments": "추가 설명", + "forward_description": "이 계정은 다른 서버에 있는 계정입니다. 그쪽으로도 신고를 보낼까요?", + "forward_to": "{0}로 전달하기", + "submit": "전송", + "generic_error": "요청을 처리하는 중 오류가 발생했습니다." + }, + "announcements": { + "end_time_prompt": "끝나는 시각: ", + "page_header": "공지사항", + "title": "공지사항", + "mark_as_read_action": "읽음으로 표시", + "post_form_header": "공지사항 작성", + "post_placeholder": "공지사항 내용을 작성하세요...", + "post_error": "오류: {error}", + "close_error": "닫기", + "delete_action": "삭제", + "post_action": "게시", + "start_time_prompt": "시작 시각: ", + "all_day_prompt": "온종일 있는 이벤트입니다", + "published_time_display": "{time}에 게시함", + "start_time_display": "{time}에 시작함", + "end_time_display": "{time}에 끝남", + "edit_action": "편집", + "submit_edit_action": "수정본 반영", + "cancel_edit_action": "취소", + "inactive_message": "이 공지사항은 비활성화 되었습니다" } } diff --git a/src/i18n/languages.js b/src/i18n/languages.js @@ -0,0 +1,53 @@ + +const languages = [ + 'ar', + 'ca', + 'cs', + 'de', + 'eo', + 'en', + 'es', + 'et', + 'eu', + 'fi', + 'fr', + 'ga', + 'he', + 'hu', + 'it', + 'ja', + 'ja_easy', + 'ko', + 'nb', + 'nl', + 'oc', + 'pl', + 'pt', + 'ro', + 'ru', + 'sk', + 'te', + 'uk', + 'zh', + 'zh_Hant' +] + +const specialJsonName = { + ja: 'ja_pedantic' +} + +const langCodeToJsonName = (code) => specialJsonName[code] || code + +const langCodeToCldrName = (code) => code + +const ensureFinalFallback = codes => { + const codeList = Array.isArray(codes) ? codes : [codes] + return codeList.includes('en') ? codeList : codeList.concat(['en']) +} + +module.exports = { + languages, + langCodeToJsonName, + langCodeToCldrName, + ensureFinalFallback +} diff --git a/src/i18n/messages.js b/src/i18n/messages.js @@ -7,46 +7,26 @@ // sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json // There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry. -const loaders = { - ar: () => import('./ar.json'), - ca: () => import('./ca.json'), - cs: () => import('./cs.json'), - de: () => import('./de.json'), - eo: () => import('./eo.json'), - es: () => import('./es.json'), - et: () => import('./et.json'), - eu: () => import('./eu.json'), - fi: () => import('./fi.json'), - fr: () => import('./fr.json'), - ga: () => import('./ga.json'), - he: () => import('./he.json'), - hu: () => import('./hu.json'), - it: () => import('./it.json'), - ja: () => import('./ja_pedantic.json'), - ja_easy: () => import('./ja_easy.json'), - ko: () => import('./ko.json'), - nb: () => import('./nb.json'), - nl: () => import('./nl.json'), - oc: () => import('./oc.json'), - pl: () => import('./pl.json'), - pt: () => import('./pt.json'), - ro: () => import('./ro.json'), - ru: () => import('./ru.json'), - sk: () => import('./sk.json'), - te: () => import('./te.json'), - uk: () => import('./uk.json'), - zh: () => import('./zh.json'), - zh_Hant: () => import('./zh_Hant.json') +import { languages, langCodeToJsonName } from './languages.js' + +const hasLanguageFile = (code) => languages.includes(code) + +const loadLanguageFile = (code) => { + return import( + /* webpackInclude: /\.json$/ */ + /* webpackChunkName: "i18n/[request]" */ + `./${langCodeToJsonName(code)}.json` + ) } const messages = { - languages: ['en', ...Object.keys(loaders)], + languages, default: { en: require('./en.json').default }, setLanguage: async (i18n, language) => { - if (loaders[language]) { - const messages = await loaders[language]() + if (hasLanguageFile(language)) { + const messages = await loadLanguageFile(language) i18n.setLocaleMessage(language, messages.default) } i18n.locale = language diff --git a/src/i18n/nl.json b/src/i18n/nl.json @@ -8,10 +8,11 @@ "media_proxy": "Mediaproxy", "scope_options": "Zichtbaarheidsopties", "text_limit": "Tekstlimiet", - "title": "Kenmerken", + "title": "Functies", "who_to_follow": "Wie te volgen", "upload_limit": "Upload limiet", - "pleroma_chat_messages": "Pleroma Chat" + "pleroma_chat_messages": "Pleroma Chat", + "shout": "Shoutbox" }, "finder": { "error_fetching_user": "Fout tijdens ophalen gebruiker", @@ -39,6 +40,15 @@ "role": { "moderator": "Moderator", "admin": "Beheerder" + }, + "flash_content": "Klik om Flash-content te laten zien met Ruffle (Experimenteel, werkt mogelijk niet).", + "flash_security": "Let op: Flash-inhoud is niet gescreend en kan malware bevatten.", + "flash_fail": "Laden van Flash-content is mislukt, zie console voor details.", + "scope_in_timeline": { + "direct": "Privé", + "private": "Alleen-volgers", + "public": "Openbaar", + "unlisted": "Niet-openbaar" } }, "login": { @@ -60,7 +70,7 @@ } }, "nav": { - "about": "Over", + "about": "Over ons", "back": "Terug", "chat": "Lokale Chat", "friend_requests": "Volgverzoeken", @@ -68,7 +78,7 @@ "dms": "Privéberichten", "public_tl": "Openbare tijdlijn", "timeline": "Tijdlijn", - "twkn": "Bekende Netwerk", + "twkn": "Globale Netwerk", "user_search": "Gebruiker Zoeken", "who_to_follow": "Wie te volgen", "preferences": "Voorkeuren", @@ -81,22 +91,23 @@ "bookmarks": "Bladwijzers" }, "notifications": { - "broken_favorite": "Onbekende status, aan het zoeken…", - "favorited_you": "vond je status leuk", + "broken_favorite": "Onbekend bericht, aan het zoeken…", + "favorited_you": "vond je bericht leuk", "followed_you": "volgt jou", "load_older": "Oudere meldingen laden", "notifications": "Meldingen", "read": "Gelezen!", - "repeated_you": "herhaalde je status", + "repeated_you": "herhaalde je bericht", "no_more_notifications": "Geen meldingen meer", "migrated_to": "is gemigreerd naar", "follow_request": "wil je volgen", "reacted_with": "reageerde met {0}", - "error": "Fout bij ophalen van meldingen: {0}" + "error": "Fout bij ophalen van meldingen: {0}", + "poll_ended": "peiling is beëindigd" }, "post_status": { - "new_status": "Nieuwe status plaatsen", - "account_not_locked_warning": "Je account is niet {0}. Iedereen kan je volgen om je alleen-volgers-berichten te lezen.", + "new_status": "Nieuw bericht plaatsen", + "account_not_locked_warning": "Je account is niet {0}. Iedereen kan je volgen om je alleen-volgersberichten te lezen.", "account_not_locked_warning_link": "gesloten", "attachments_sensitive": "Bijlagen als gevoelig markeren", "content_type": { @@ -108,10 +119,10 @@ "content_warning": "Onderwerp (optioneel)", "default": "Tijd voor anime!", "direct_warning": "Deze post zal enkel zichtbaar zijn voor de personen die genoemd zijn.", - "posting": "Plaatsen", + "posting": "Aan het plaatsen", "scope": { "direct": "Privé - bericht enkel naar vermelde gebruikers sturen", - "private": "Enkel volgers - bericht enkel naar volgers sturen", + "private": "Alleen-volgers - bericht is enkel leesbaar voor volgers", "public": "Openbaar - bericht op openbare tijdlijnen plaatsen", "unlisted": "Niet vermelden - niet tonen op openbare tijdlijnen" }, @@ -119,11 +130,11 @@ "direct_warning_to_first_only": "Dit bericht zal alleen zichtbaar zijn voor de vermelde gebruikers aan het begin van het bericht.", "scope_notice": { "public": "Dit bericht zal voor iedereen zichtbaar zijn", - "unlisted": "Dit bericht zal niet zichtbaar zijn in de Openbare Tijdlijn en Het Geheel Bekende Netwerk", + "unlisted": "Dit bericht zal niet zichtbaar zijn in de Openbare Tijdlijn en Het Globale Netwerk", "private": "Dit bericht zal voor alleen je volgers zichtbaar zijn" }, - "post": "Bericht", - "empty_status_error": "Kan geen lege status zonder bijlagen plaatsen", + "post": "Plaatsen", + "empty_status_error": "Kan geen leeg bericht zonder bijlagen plaatsen", "preview_empty": "Leeg", "preview": "Voorbeeld", "media_description": "Mediaomschrijving", @@ -149,13 +160,14 @@ "username_placeholder": "bijv. lain", "fullname_placeholder": "bijv. Lain Iwakura", "bio_placeholder": "bijv.\nHallo, ik ben Lain.\nIk ben een animemeisje woonachtig in een buitenwijk in Japan. Je kent me misschien van the Wired.", - "reason_placeholder": "Deze instantie keurt registraties handmatig goed.\nLaat de beheerder weten waarom je wilt registreren.", + "reason_placeholder": "Deze instantie keurt registraties handmatig goed.\nLaat de beheerder weten waarom je je wilt registreren.", "reason": "Reden voor registratie", - "register": "Registreren" + "register": "Registreren", + "email_language": "In welke taal wil je e-mails ontvangen van de server?" }, "settings": { - "attachmentRadius": "Bijlages", - "attachments": "Bijlages", + "attachmentRadius": "Bijlagen", + "attachments": "Bijlagen", "avatar": "Avatar", "avatarAltRadius": "Avatars (meldingen)", "avatarRadius": "Avatars", @@ -169,7 +181,7 @@ "change_password": "Wachtwoord wijzigen", "change_password_error": "Er is een fout opgetreden bij het wijzigen van je wachtwoord.", "changed_password": "Wachtwoord succesvol gewijzigd!", - "collapse_subject": "Klap berichten met een onderwerp in", + "collapse_subject": "Berichten met een onderwerp inklappen", "composing": "Opstellen", "confirm_new_password": "Nieuw wachtwoord bevestigen", "current_avatar": "Je huidige avatar", @@ -181,9 +193,9 @@ "delete_account_description": "Permanent je gegevens verwijderen en account deactiveren.", "delete_account_error": "Er is een fout opgetreden bij het verwijderen van je account. Indien dit probleem zich voor blijft doen, neem dan contact op met de beheerder van deze instantie.", "delete_account_instructions": "Voer je wachtwoord in het onderstaande invoerveld in om het verwijderen van je account te bevestigen.", - "export_theme": "Voorinstelling opslaan", + "export_theme": "Preset opslaan", "filtering": "Filtering", - "filtering_explanation": "Alle statussen die deze woorden bevatten worden genegeerd, één filter per regel", + "filtering_explanation": "Alle berichten die deze woorden bevatten worden genegeerd, één filter per regel", "follow_export": "Volgers exporteren", "follow_export_button": "Exporteer je volgers naar een csv-bestand", "follow_export_processing": "Aan het verwerken, binnen enkele ogenblikken wordt je gevraagd je bestand te downloaden", @@ -192,13 +204,13 @@ "follows_imported": "Volgers geïmporteerd! Het kan even duren voordat deze verwerkt zijn.", "foreground": "Voorgrond", "general": "Algemeen", - "hide_attachments_in_convo": "Bijlagen in conversaties verbergen", + "hide_attachments_in_convo": "Bijlagen in gesprekken verbergen", "hide_attachments_in_tl": "Bijlagen in tijdlijn verbergen", "hide_isp": "Instantie-specifiek paneel verbergen", "preload_images": "Afbeeldingen vooraf laden", - "hide_post_stats": "Bericht statistieken verbergen (bijv. het aantal favorieten)", + "hide_post_stats": "Bericht-statistieken verbergen (bijv. het aantal favorieten)", "hide_user_stats": "Gebruikers-statistieken verbergen (bijv. het aantal volgers)", - "import_followers_from_a_csv_file": "Gevolgden uit een csv bestand importeren", + "import_followers_from_a_csv_file": "Gevolgde gebruikers uit een csv bestand importeren", "import_theme": "Preset laden", "inputRadius": "Invoervelden", "checkboxRadius": "Checkboxen", @@ -216,13 +228,13 @@ "name_bio": "Naam & bio", "new_password": "Nieuw wachtwoord", "notification_visibility": "Type meldingen die getoond worden", - "notification_visibility_follows": "Gevolgden", + "notification_visibility_follows": "Gevolgde gebruikers", "notification_visibility_likes": "Favorieten", "notification_visibility_mentions": "Vermeldingen", "notification_visibility_repeats": "Herhalingen", "no_rich_text_description": "Verwijder rich text formattering van alle berichten", "hide_network_description": "Toon niet wie mij volgt en wie ik volg.", - "nsfw_clickthrough": "Doorklikbaar verbergen van gevoelige bijlages en link voorbeelden inschakelen", + "nsfw_clickthrough": "Gevoelige media verbergen", "oauth_tokens": "OAuth-tokens", "token": "Token", "refresh_token": "Token vernieuwen", @@ -249,15 +261,15 @@ "settings": "Instellingen", "subject_input_always_show": "Altijd onderwerpveld tonen", "subject_line_behavior": "Onderwerp kopiëren bij beantwoorden", - "subject_line_email": "Zoals email: \"re: onderwerp\"", - "subject_line_mastodon": "Zoals mastodon: kopieer zoals het is", + "subject_line_email": "Zoals e-mail: \"re: onderwerp\"", + "subject_line_mastodon": "Zoals mastodon: kopiëren zoals het is", "subject_line_noop": "Niet kopiëren", - "stop_gifs": "GIFs afspelen bij zweven", + "stop_gifs": "Geanimeerde afbeeldingen afspelen bij zweven", "streaming": "Automatisch streamen van nieuwe berichten inschakelen wanneer tot boven gescrold is", "text": "Tekst", "theme": "Thema", "theme_help": "Hex kleur codes (#rrggbb) gebruiken om je kleur thema te wijzigen.", - "theme_help_v2_1": "Je kan ook de kleur en transparantie van bepaalde componenten overschrijven door de checkbox aan te vinken, gebruik de \"Alles wissen\" knop om alle overschrijvingen te annuleren.", + "theme_help_v2_1": "Je kan ook de kleur en transparantie van bepaalde componenten overschrijven door de checkbox aan te vinken, gebruik de \"Alles wissen\" knop om alle overschrijvingen te herstellen.", "theme_help_v2_2": "Iconen onder sommige onderdelen zijn achtergrond/tekst contrast indicatoren, zweef er over voor gedetailleerde info. Hou er rekening mee dat bij doorzichtigheid de ergst mogelijke situatie wordt weer gegeven.", "tooltipRadius": "Tooltips/alarmen", "user_settings": "Gebruikersinstellingen", @@ -275,10 +287,10 @@ "keep_roundness": "Rondingen behouden", "keep_fonts": "Lettertypes behouden", "save_load_hint": "\"Behoud\" opties behouden de momenteel ingestelde opties bij het selecteren of laden van thema's, maar slaan ook de genoemde opties op bij het exporteren van een thema. Wanneer alle selectievakjes zijn uitgeschakeld, zal het exporteren van thema's alles opslaan.", - "reset": "Reset", + "reset": "Herstellen", "clear_all": "Alles wissen", "clear_opacity": "Transparantie wissen", - "keep_as_is": "Hou zoals het is", + "keep_as_is": "Houden zoals het is", "use_snapshot": "Oude versie", "use_source": "Nieuwe versie", "help": { @@ -289,7 +301,7 @@ "snapshot_source_mismatch": "Versie conflict: waarschijnlijk was FE terug gerold en opnieuw bijgewerkt, indien je het thema aangepast hebt met de oudere versie van FE wil je waarschijnlijk de oude versie gebruiken, gebruik anders de nieuwe versie.", "migration_napshot_gone": "Voor een onduidelijke reden mist de momentopname, dus sommige dingen kunnen anders uitzien dan je gewend bent.", "migration_snapshot_ok": "Voor de zekerheid is een momentopname van het thema geladen. Je kunt proberen om de thema gegevens te laden.", - "fe_downgraded": "PleromaFE's versie is terug gerold.", + "fe_downgraded": "PleromaFE's versie is terug gezet.", "fe_upgraded": "De thema-engine van PleromaFE is bijgewerkt na de versie update.", "snapshot_missing": "Het bestand bevat geen thema momentopname, dus het thema kan anders uitzien dan je oorspronkelijk bedacht had.", "snapshot_present": "Thema momentopname is geladen, alle waarden zijn overschreven. Je kunt in plaats daarvan ook de daadwerkelijke data van het thema laden." @@ -315,7 +327,7 @@ "common_colors": { "_tab_label": "Algemeen", "main": "Algemene kleuren", - "foreground_hint": "Zie \"Geavanceerd\" tab voor meer gedetailleerde controle", + "foreground_hint": "Zie \"Geavanceerd\" tab voor meer gedetailleerde opties", "rgbo": "Iconen, accenten, badges" }, "advanced_colors": { @@ -336,9 +348,9 @@ "selectedMenu": "Geselecteerd menu item", "selectedPost": "Geselecteerd bericht", "pressed": "Ingedrukt", - "highlight": "Gemarkeerde elementen", + "highlight": "Uitgelichte elementen", "icons": "Iconen", - "poll": "Poll grafiek", + "poll": "Peiling grafiek", "underlay": "Onderlaag", "popover": "Tooltips, menu's, popovers", "post": "Berichten / Gebruiker bios", @@ -352,7 +364,7 @@ "wallpaper": "Achtergrond" }, "radii": { - "_tab_label": "Rondheid" + "_tab_label": "Rondingen" }, "shadows": { "_tab_label": "Schaduw en belichting", @@ -374,8 +386,8 @@ "panel": "Paneel", "panelHeader": "Paneel koptekst", "topBar": "Top balk", - "avatar": "Gebruikers avatar (in profiel weergave)", - "avatarStatus": "Gebruikers avatar (in bericht weergave)", + "avatar": "Gebruikers-avatar (in profiel weergave)", + "avatarStatus": "Gebruikers-avatar (in bericht weergave)", "popup": "Popups en tooltips", "button": "Knop", "buttonHover": "Knop (zweven)", @@ -386,7 +398,7 @@ "hintV3": "Voor schaduwen kun je ook de {0} notatie gebruiken om de andere kleur invoer te gebruiken." }, "fonts": { - "_tab_label": "Lettertypes", + "_tab_label": "Lettertypen", "help": "Selecteer het lettertype om te gebruiken voor elementen van de UI. Voor \"aangepast\" dien je de exacte naam van het lettertype in te voeren zoals die in het systeem wordt weergegeven.", "components": { "interface": "Interface", @@ -426,10 +438,10 @@ "wait_pre_setup_otp": "OTP voorinstellen", "confirm_and_enable": "Bevestig en schakel OTP in", "title": "Twee-factorauthenticatie", - "generate_new_recovery_codes": "Genereer nieuwe herstelcodes", + "generate_new_recovery_codes": "Nieuwe herstelcodes genereren", "recovery_codes": "Herstelcodes.", "waiting_a_recovery_codes": "Back-upcodes ontvangen…", - "authentication_methods": "Authenticatiemethodes", + "authentication_methods": "Authenticatiemethoden", "scan": { "title": "Scannen", "desc": "Scan de QR-code of voer een sleutel in met je twee-factorapplicatie:", @@ -441,39 +453,39 @@ "warning_of_generate_new_codes": "Wanneer je nieuwe herstelcodes genereert, zullen je oude codes niet langer werken.", "recovery_codes_warning": "Schrijf de codes op of sla ze op een veilige locatie op - anders kun je ze niet meer inzien. Als je toegang tot je 2FA-app en herstelcodes verliest, zal je buitengesloten zijn van je account." }, - "allow_following_move": "Automatisch volgen toestaan wanneer een gevolgd account migreert", - "block_export": "Blokkades exporteren", - "block_import": "Blokkades importeren", - "blocks_imported": "Blokkades geïmporteerd! Het kan even duren voordat deze verwerkt zijn.", - "blocks_tab": "Blokkades", + "allow_following_move": "Automatisch volgen toestaan wanneer een gevolgd account verhuist", + "block_export": "Geblokkeerde gebruikers exporteren", + "block_import": "Geblokkeerde gebruikers importeren", + "blocks_imported": "Geblokkeerde gebruikers geïmporteerd! Het kan even duren voordat deze verwerkt zijn.", + "blocks_tab": "Geblokkeerde gebruikers", "change_email": "E-mail wijzigen", "change_email_error": "Er is een fout opgetreden tijdens het wijzigen van je e-mailadres.", "changed_email": "E-mailadres succesvol gewijzigd!", "domain_mutes": "Domeinen", "avatar_size_instruction": "De aangeraden minimale afmeting voor avatar-afbeeldingen is 150x150 pixels.", - "pad_emoji": "Vul emoji aan met spaties wanneer deze met de picker ingevoegd worden", + "pad_emoji": "Emoji aan met spaties aanvullen wanneer deze met de picker ingevoegd worden", "emoji_reactions_on_timeline": "Toon emoji-reacties op de tijdlijn", "accent": "Accent", "hide_muted_posts": "Berichten van genegeerde gebruikers verbergen", "max_thumbnails": "Maximaal aantal miniaturen per bericht", "use_one_click_nsfw": "Gevoelige bijlagen met slechts één klik openen", - "hide_filtered_statuses": "Gefilterde statussen verbergen", - "import_blocks_from_a_csv_file": "Blokkades van een csv bestand importeren", - "mutes_tab": "Genegeerden", - "play_videos_in_modal": "Video's in een popup frame afspelen", + "hide_filtered_statuses": "Gefilterde berichten verbergen", + "import_blocks_from_a_csv_file": "Geblokkeerde gebruikers van een csv bestand importeren", + "mutes_tab": "Genegeerde gebruikers", + "play_videos_in_modal": "Video's in een popup venster afspelen", "new_email": "Nieuwe e-mail", "notification_visibility_emoji_reactions": "Reacties", - "no_blocks": "Geen blokkades", - "no_mutes": "Geen genegeerden", + "no_blocks": "Geen geblokkeerde gebruikers", + "no_mutes": "Geen genegeerde gebruikers", "hide_followers_description": "Niet tonen wie mij volgt", "hide_followers_count_description": "Niet mijn volgers aantal tonen", - "hide_follows_count_description": "Niet mijn gevolgde aantal tonen", + "hide_follows_count_description": "Niet mijn gevolgden aantal tonen", "show_admin_badge": "\"Beheerder\" badge in mijn profiel tonen", - "autohide_floating_post_button": "Nieuw Bericht knop automatisch verbergen (mobiel)", + "autohide_floating_post_button": "\"Bericht opstellen\"-knop automatisch verbergen (mobiel)", "search_user_to_block": "Zoek wie je wilt blokkeren", "search_user_to_mute": "Zoek wie je wilt negeren", "minimal_scopes_mode": "Bericht bereik-opties minimaliseren", - "post_status_content_type": "Bericht status content type", + "post_status_content_type": "Standaard bericht content type", "user_mutes": "Gebruikers", "useStreamingApi": "Berichten en meldingen in real-time ontvangen", "useStreamingApiWarning": "(Afgeraden, experimenteel, kan berichten overslaan)", @@ -482,7 +494,7 @@ "fun": "Plezier", "greentext": "Meme pijlen", "block_export_button": "Exporteer je geblokkeerde gebruikers naar een csv-bestand", - "block_import_error": "Fout bij importeren blokkades", + "block_import_error": "Fout bij importeren geblokkeerde gebruikers", "discoverable": "Sta toe dat dit account ontdekt kan worden in zoekresultaten en andere diensten", "use_contain_fit": "Bijlage in miniaturen niet bijsnijden", "notification_visibility_moves": "Gebruiker Migraties", @@ -495,7 +507,7 @@ "backend_version": "Backend versie", "title": "Versie" }, - "mutes_and_blocks": "Negeringen en Blokkades", + "mutes_and_blocks": "Negeren en Blokkeren", "profile_fields": { "value": "Inhoud", "name": "Label", @@ -508,15 +520,15 @@ "hide_media_previews": "Media voorbeelden verbergen", "word_filter": "Woord filter", "chatMessageRadius": "Chatbericht", - "mute_export": "Genegeerden export", - "mute_export_button": "Exporteer je genegeerden naar een csv-bestand", - "mute_import_error": "Fout tijdens het importeren van genegeerden", - "mute_import": "Genegeerden import", - "mutes_imported": "Genegeerden geïmporteerd! Het kan even duren voordat deze verwerkt zijn.", + "mute_export": "Genegeerde gebruikers export", + "mute_export_button": "Genegeerde gebruikers naar een csv-bestand exporteren", + "mute_import_error": "Fout tijdens het importeren van genegeerde gebruikers", + "mute_import": "Genegeerde gebruikers import", + "mutes_imported": "Genegeerde gebruikers geïmporteerd! Het kan even duren voordat deze verwerkt zijn.", "more_settings": "Meer instellingen", - "notification_setting_hide_notification_contents": "Afzender en inhoud van push meldingen verbergen", + "notification_setting_hide_notification_contents": "Afzender en inhoud van push-meldingen verbergen", "notification_setting_block_from_strangers": "Meldingen van gebruikers die je niet volgt blokkeren", - "virtual_scrolling": "Tijdlijn rendering optimaliseren", + "virtual_scrolling": "Tijdlijn weergave optimaliseren", "sensitive_by_default": "Berichten standaard als gevoelig markeren", "reset_avatar_confirm": "Wil je echt de avatar herstellen?", "reset_banner_confirm": "Wil je echt de banner herstellen?", @@ -528,7 +540,7 @@ "reply_visibility_following_short": "Antwoorden naar mijn gevolgden tonen", "file_export_import": { "errors": { - "file_slightly_new": "Bestand minor versie is verschillend, sommige instellingen kunnen mogelijk niet worden geladen", + "file_slightly_new": "Minor versie van bestand is verschillend, sommige instellingen kunnen mogelijk niet worden geladen", "file_too_old": "Incompatibele hoofdversie: {fileMajor}, bestandsversie is te oud en wordt niet ondersteund (minimale versie {feMajor})", "file_too_new": "Incompatibele hoofdversie: {fileMajor}, deze PleromaFE (instellingen versie {feMajor}) is te oud om deze te ondersteunen", "invalid_file": "Het geselecteerde bestand is niet een door Pleroma ondersteunde instellingen back-up. Er zijn geen wijzigingen gemaakt." @@ -536,27 +548,95 @@ "restore_settings": "Instellingen uit bestand herstellen", "backup_settings_theme": "Instellingen en thema naar bestand back-uppen", "backup_settings": "Instellingen naar bestand back-uppen", - "backup_restore": "Instellingen backup" + "backup_restore": "Instellingen back-up" }, - "hide_wallpaper": "Instantie achtergrond verbergen", + "hide_wallpaper": "Achtergrond-afbeelding verbergen", "hide_all_muted_posts": "Genegeerde berichten verbergen", - "import_mutes_from_a_csv_file": "Importeer genegeerden van een csv bestand" + "import_mutes_from_a_csv_file": "Genegeerde gebruikers uit een csv bestand importeren", + "added_alias": "Alias is toegevoegd.", + "add_alias_error": "Fout bij het toevoegen van alias: {error}", + "move_account": "Account verhuizen", + "move_account_notes": "Indien je het account ergens anders heen wilt verplaatsen, dien je eerst een alias naar dit account te maken in het nieuwe account.", + "move_account_target": "Doelwit account (b.v. {example})", + "moved_account": "Het account is verhuisd.", + "move_account_error": "Fout tijdens account verhuizen: {error}", + "wordfilter": "Woordfilter", + "third_column_mode": "Indien er genoeg plaats is, derde kolom tonen met", + "third_column_mode_none": "Géén derde kolom tonen", + "third_column_mode_notifications": "Meldingen", + "third_column_mode_postform": "Berichtformulier en navigatie", + "tree_advanced": "Flexibelere navigatie toestaan in boom weergave", + "tree_fade_ancestors": "Ouders van huidige bericht met gedempte tekst tonen", + "conversation_display_linear": "Lineaire weergave", + "mention_link_display_full_for_remote": "als volledige namen alleen voor externe gebruikers (b.v. {'@'}foo{'@'}example.org)", + "mention_link_display_full": "altijd als volledige namen (b.v. {'@'}foo{'@'}example.org)", + "mention_link_show_avatar": "Profielfoto naast link tonen", + "mention_link_fade_domain": "Domeinen vervagen (b.v. {'@'}example.org in {'@'}foo{'@'}example.org)", + "mention_link_bolden_you": "Vermeldingen naar jezelf uitlichten", + "expert_mode": "Geavanceerde opties tonen", + "setting_server_side": "Deze instelling is gebonden aan je profiel en beïnvloed alle sessies en clients", + "post_look_feel": "Berichten Look & Feel", + "mention_links": "Vermelding-links", + "email_language": "Taal voor e-mails van de server", + "account_backup": "Account back-up", + "account_backup_description": "Hiermee kun je een archief van je account gegevens en berichten downloaden, maar deze kunnen nog niet geïmporteerd worden in een Pleroma account.", + "account_backup_table_head": "Back-up", + "download_backup": "Downloaden", + "backup_not_ready": "Deze back-up is nog niet gereed.", + "remove_backup": "Verwijderen", + "list_backups_error": "Fout bij het ophalen van back-ups: {error}", + "add_backup": "Nieuwe back-up aanmaken", + "added_backup": "Nieuwe back-up is toegevoegd.", + "add_backup_error": "Fout bij het maken van back-up: {error}", + "account_alias": "Account aliassen", + "account_alias_table_head": "Alias", + "list_aliases_error": "Fout bij het ophalen van aliassen: {error}", + "hide_list_aliases_error_action": "Sluiten", + "remove_alias": "Deze alias verwijderen", + "new_alias_target": "Nieuwe alias toevoegen (b.v. {example})", + "mute_bot_posts": "Bot-berichten negeren", + "hide_bot_indication": "Bot-indicatie in berichten verbergen", + "hide_shoutbox": "Shoutbox verbergen", + "right_sidebar": "Kolom-volgorde omdraaien", + "always_show_post_button": "Altijd de zwevende \"Bericht opstellen\"-knop tonen", + "hide_wordfiltered_statuses": "Berichten met gefilterde woorden verbergen", + "hide_muted_threads": "Genegeerde gesprekken verbergen", + "account_privacy": "Privacy", + "posts": "Berichten", + "user_profiles": "Gebruikersprofielen", + "notification_visibility_polls": "Einde van peilingen waar je in gestemd hebt", + "hide_favorites_description": "Lijst van favorieten verbergen (mensen krijgen wel nog meldingen)", + "conversation_display": "Gespreksweergave stijl", + "conversation_display_tree": "Boom weergave", + "disable_sticky_headers": "Kolomkopteksten niet bovenaan het scherm plakken", + "show_scrollbars": "Scrollbalk tonen in zijkolommen", + "conversation_other_replies_button": "\"Andere antwoorden\"-knop tonen", + "conversation_other_replies_button_below": "Onder berichten", + "conversation_other_replies_button_inside": "Binnen in berichten", + "max_depth_in_thread": "Maximum lagen van een gesprek welke standaard getoond dienen te worden", + "use_at_icon": "{'@'} symbool als icoon tonen in plaats van tekst", + "mention_link_display": "Vermelding-links tonen", + "mention_link_display_short": "altijd als korte namen (b.v. {'@'}foo)", + "mention_link_use_tooltip": "Volledige namen in tooltip tonen voor externe gebruikers", + "show_yous": "(Jij)'s tonen", + "user_popover_avatar_zoom": "Gebruikers-avatar inzoomen wanneer hier op geklikt wordt in een popover in plaats van de popover te sluiten", + "user_popover_avatar_overlay": "Gebruikers-popover tonen over gebruikers-avatar" }, "timeline": { - "collapse": "Inklappen", - "conversation": "Conversatie", + "collapse": "Invouwen", + "conversation": "Gesprek", "error_fetching": "Fout bij ophalen van updates", - "load_older": "Oudere statussen laden", - "no_retweet_hint": "Bericht is gemarkeerd als enkel volgers of direct en kan niet worden herhaald", + "load_older": "Oudere berichten laden", + "no_retweet_hint": "Bericht is gemarkeerd als enkel-volgers of privé en kan niet worden herhaald of geciteerd", "repeated": "herhaalde", "show_new": "Nieuwe tonen", "up_to_date": "Up-to-date", - "no_statuses": "Geen statussen", - "no_more_statuses": "Geen statussen meer", + "no_statuses": "Geen berichten", + "no_more_statuses": "Geen verdere berichten", "socket_broke": "Realtime verbinding verloren: CloseEvent code {0}", "socket_reconnected": "Realtime verbinding opgezet", "reload": "Verversen", - "error": "Fout tijdens het ophalen van tijdlijn: {0}" + "error": "Fout bij het ophalen van tijdlijn: {0}" }, "user_card": { "approve": "Goedkeuren", @@ -565,27 +645,27 @@ "deny": "Weigeren", "favorites": "Favorieten", "follow": "Volgen", - "follow_cancel": "Aanvraag annuleren", - "follow_sent": "Aanvraag verzonden!", + "follow_cancel": "Verzoek annuleren", + "follow_sent": "Verzoek verzonden!", "follow_progress": "Aanvragen…", - "follow_unfollow": "Stop volgen", - "followees": "Aan het volgen", + "follow_unfollow": "Ontvolgen", + "followees": "Volgen", "followers": "Volgers", - "following": "Aan het volgen!", + "following": "Gevolgd!", "follows_you": "Volgt jou!", "its_you": "'t is jij!", "mute": "Negeren", "muted": "Genegeerd", "per_day": "per dag", - "remote_follow": "Volg vanop afstand", - "statuses": "Statussen", + "remote_follow": "Van afstand volgen", + "statuses": "Berichten", "admin_menu": { "delete_user": "Gebruiker verwijderen", - "quarantine": "Federeren van gebruikers berichten verbieden", + "quarantine": "Federeren van berichten verbieden", "disable_any_subscription": "Volgen van gebruiker in zijn geheel verbieden", "disable_remote_subscription": "Volgen van gebruiker vanaf andere instanties verbieden", "sandbox": "Berichten forceren om alleen voor volgers zichtbaar te zijn", - "force_unlisted": "Berichten forceren om niet publiekelijk getoond te worden", + "force_unlisted": "Berichten forceren om niet openbaar getoond te worden", "strip_media": "Media van berichten verwijderen", "force_nsfw": "Alle berichten als gevoelig markeren", "delete_account": "Account verwijderen", @@ -595,30 +675,33 @@ "grant_moderator": "Moderatorsrechten toekennen", "revoke_admin": "Beheerdersrechten intrekken", "grant_admin": "Beheerdersrechten toekennen", - "moderation": "Moderatie" + "moderation": "Moderatie", + "delete_user_data_and_deactivate_confirmation": "Dit zal permanent alle data van dit account verwijderen en het account deactiveren. Weet je het zeker?" }, "show_repeats": "Herhalingen tonen", "hide_repeats": "Herhalingen verbergen", "mute_progress": "Negeren…", - "unmute_progress": "Negering opheffen…", - "unmute": "Negering opheffen", + "unmute_progress": "Negeren opheffen…", + "unmute": "Negeren opheffen", "block_progress": "Blokkeren…", - "unblock_progress": "Blokkade opheffen…", - "unblock": "Blokkade opheffen", + "unblock_progress": "Blokkeren opheffen…", + "unblock": "Blokkeren opheffen", "unsubscribe": "Abonnement opzeggen", "subscribe": "Abonneren", - "report": "Aangeven", - "mention": "Vermelding", + "report": "Rapporteren", + "mention": "Vermelden", "media": "Media", "hidden": "Verborgen", "highlight": { "side": "Zijstreep", "striped": "Gestreepte achtergrond", "solid": "Effen achtergrond", - "disabled": "Geen highlight" + "disabled": "Geen uitlichting" }, "bot": "Bot", - "message": "Bericht" + "message": "Bericht", + "edit_profile": "Profiel wijzigen", + "deactivated": "Gedeactiveerd" }, "user_profile": { "timeline_title": "Gebruikerstijdlijn", @@ -634,11 +717,11 @@ "repeat": "Herhalen", "reply": "Beantwoorden", "favorite": "Favoriet maken", - "user_settings": "Gebruikers Instellingen", - "reject_follow_request": "Volg-verzoek afwijzen", - "accept_follow_request": "Volg-aanvraag accepteren", + "user_settings": "Gebruikersinstellingen", + "reject_follow_request": "Volgverzoek afwijzen", + "accept_follow_request": "Volgverzoek accepteren", "add_reaction": "Reactie toevoegen", - "bookmark": "Bladwijzer" + "bookmark": "Bladwijzer maken" }, "upload": { "error": { @@ -663,27 +746,27 @@ "replace": "Vervangen", "is_replaced_by": "→", "keyword_policies": "Zoekwoordbeleid", - "ftl_removal": "Verwijdering van \"Het Geheel Bekende Netwerk\" Tijdlijn" + "ftl_removal": "Verwijderen van \"Het Globale Netwerk\" Tijdlijn" }, "mrf_policies_desc": "MRF-regels beïnvloeden het federatiegedrag van de instantie. De volgende regels zijn ingeschakeld:", "mrf_policies": "Ingeschakelde MRF-regels", "simple": { - "simple_policies": "Instantiespecifieke regels", + "simple_policies": "Instantie-specifieke regels", "instance": "Instantie", "reason": "Reden", "not_applicable": "n.v.t.", "accept": "Accepteren", "accept_desc": "Deze instantie accepteert alleen berichten van de volgende instanties:", "reject": "Afwijzen", - "reject_desc": "Deze instantie zal geen berichten accepteren van de volgende instanties:", + "reject_desc": "Deze instantie zal géén berichten accepteren van de volgende instanties:", "quarantine": "Quarantaine", - "quarantine_desc": "Deze instantie zal alleen openbare berichten sturen naar de volgende instanties:", - "ftl_removal_desc": "Deze instantie verwijdert de volgende instanties van \"Bekende Netwerk\" tijdlijn:", + "quarantine_desc": "Deze instantie zal géén berichten sturen naar de volgende instanties:", + "ftl_removal_desc": "Deze instantie verwijdert de volgende instanties van \"Globale Netwerk\" tijdlijn:", "media_removal_desc": "Deze instantie verwijdert media van berichten van de volgende instanties:", - "media_nsfw_desc": "Deze instantie stelt media in als gevoelig in berichten van de volgende instanties:", - "ftl_removal": "Verwijderen van \"Bekende Netwerk\" Tijdlijn", - "media_removal": "Mediaverwijdering", - "media_nsfw": "Forceer media als gevoelig" + "media_nsfw_desc": "Deze instantie markeert media als gevoelig in berichten van de volgende instanties:", + "ftl_removal": "Verwijderen van \"Globale Netwerk\" Tijdlijn", + "media_removal": "Verwijderen van media", + "media_nsfw": "Media als gevoelig markeren" } }, "staff": "Personeel" @@ -691,8 +774,8 @@ "domain_mute_card": { "mute": "Negeren", "mute_progress": "Negeren…", - "unmute": "Negering opheffen", - "unmute_progress": "Negering wordt opgeheven…" + "unmute": "Negeren opheffen", + "unmute_progress": "Negeren wordt opgeheven…" }, "exporter": { "export": "Exporteren", @@ -711,21 +794,23 @@ }, "media_modal": { "previous": "Vorige", - "next": "Volgende" + "next": "Volgende", + "counter": "{current} / {total}", + "hide": "Media venster sluiten" }, "polls": { - "add_poll": "Poll toevoegen", + "add_poll": "Peiling toevoegen", "add_option": "Optie toevoegen", "option": "Optie", "votes": "stemmen", - "vote": "Stem", + "vote": "Stemmen", "single_choice": "Enkele keuze", "multiple_choices": "Meerkeuze", - "expiry": "Poll leeftijd", - "expires_in": "Poll eindigt in {0}", - "expired": "Poll is {0} geleden beëindigd", - "not_enough_options": "Te weinig opties in poll", - "type": "Poll-type", + "expiry": "Peiling tijdsduur", + "expires_in": "Peiling eindigt in {0}", + "expired": "Peiling is {0} geleden beëindigd", + "not_enough_options": "Te weinig opties in peiling", + "type": "Peiling-type", "votes_count": "{count} stem | {count} stemmen", "people_voted_count": "{count} persoon heeft gestemd | {count} personen hebben gestemd" }, @@ -742,28 +827,41 @@ }, "interactions": { "favs_repeats": "Herhalingen en favorieten", - "follows": "Nieuwe gevolgden", + "follows": "Nieuwe volgs", "moves": "Gebruikermigraties", + "emoji_reactions": "Emoji Reacties", + "reports": "Rapportages", "load_older": "Oudere interacties laden" }, "remote_user_resolver": { "searching_for": "Zoeken naar", "error": "Niet gevonden.", - "remote_user_resolver": "Externe gebruikers-zoeker" - }, + "remote_user_resolver": "Externe gebruiker zoeker" + }, + "report": { + "reporter": "Reporteerder:", + "reported_user": "Gerapporteerde gebruiker:", + "reported_statuses": "Gerapporteerde statussen:", + "notes": "Notas:", + "state": "Status:", + "state_open": "Open", + "state_closed": "Gesloten", + "state_resolved": "Opgelost" + }, + "selectable_list": { "select_all": "Alles selecteren" }, "password_reset": { - "password_reset_required_but_mailer_is_disabled": "Je dient je wachtwoord opnieuw in te stellen, maar wachtwoord reset is uitgeschakeld. Neem contact op met de beheerder van deze instantie.", + "password_reset_required_but_mailer_is_disabled": "Je dient je wachtwoord opnieuw in te stellen, maar wachtwoordherstel is uitgeschakeld. Neem contact op met de beheerder van deze instantie.", "password_reset_required": "Je dient je wachtwoord opnieuw in te stellen om in te kunnen loggen.", - "password_reset_disabled": "Wachtwoord reset is uitgeschakeld. Neem contact op met de beheerder van deze instantie.", + "password_reset_disabled": "Wachtwoordherstel is uitgeschakeld. Neem contact op met de beheerder van deze instantie.", "too_many_requests": "Je hebt het maximaal aantal pogingen bereikt, probeer het later opnieuw.", "return_home": "Terugkeren naar de home pagina", "check_email": "Controleer je email inbox voor een link om je wachtwoord opnieuw in te stellen.", "placeholder": "Je email of gebruikersnaam", "instruction": "Voer je email adres of gebruikersnaam in. We sturen je een link om je wachtwoord opnieuw in te stellen.", - "password_reset": "Wachtwoord opnieuw instellen", + "password_reset": "Wachtwoord herstellen", "forgot_password": "Wachtwoord vergeten?" }, "search": { @@ -779,26 +877,26 @@ "forward_to": "Doorsturen naar {0}", "forward_description": "Dit account hoort bij een andere server. Wil je een kopie van het rapport ook daarheen sturen?", "additional_comments": "Aanvullende opmerkingen", - "add_comment_description": "Het rapport zal naar de moderators van de instantie worden verstuurd. Je kunt hieronder uitleg bijvoegen waarom je dit account wilt aangeven:", - "title": "{0} aangeven" + "add_comment_description": "Het rapport zal naar de moderators van de instantie worden verstuurd. Je kunt hieronder uitleg bijvoegen waarom je dit account wilt rapporteren:", + "title": "{0} rapporteren" }, "status": { - "copy_link": "Link naar status kopiëren", - "status_unavailable": "Status niet beschikbaar", - "unmute_conversation": "Conversatie niet meer negeren", - "mute_conversation": "Conversatie negeren", + "copy_link": "Link naar bericht kopiëren", + "status_unavailable": "Bericht niet beschikbaar", + "unmute_conversation": "Gesprek niet meer negeren", + "mute_conversation": "Gesprek negeren", "replies_list": "Antwoorden:", "reply_to": "Antwoorden aan", - "delete_confirm": "Wil je echt deze status verwijderen?", + "delete_confirm": "Wil je echt dit bericht verwijderen?", "pin": "Aan profiel vastmaken", "pinned": "Vastgezet", "unpin": "Van profiel losmaken", - "delete": "Status verwijderen", + "delete": "Bericht verwijderen", "repeats": "Herhalingen", "favorites": "Favorieten", "thread_muted_and_words": ", heeft woorden:", - "thread_muted": "Thread genegeerd", - "expand": "Uitklappen", + "thread_muted": "Gesprek genegeerd", + "expand": "Uitvouwen", "nsfw": "Gevoelig", "status_deleted": "Dit bericht is verwijderd", "hide_content": "Inhoud verbergen", @@ -807,7 +905,33 @@ "show_full_subject": "Volledig onderwerp tonen", "external_source": "Externe bron", "unbookmark": "Bladwijzer verwijderen", - "bookmark": "Bladwijzer toevoegen" + "bookmark": "Bladwijzer toevoegen", + "show_attachment_description": "Voorbeeld beschrijving (open bijlage om de volledige beschrijving te zien)", + "remove_attachment": "Bijlage verwijderen", + "attachment_stop_flash": "Flash speler stoppen", + "move_up": "Bijlage naar links schuiven", + "move_down": "Bijlage naar rechts schuiven", + "open_gallery": "Gallerij openen", + "thread_hide": "Gesprek verbergen", + "thread_show": "Gesprek tonen", + "show_all_conversation": "Volledig gesprek tonen ({numStatus} ander bericht) | Volledig gesprek tonen ({numStatus} andere berichten)", + "show_only_conversation_under_this": "Alleen antwoorden op dit bericht tonen", + "mentions": "Vermeldingen", + "replies_list_with_others": "Antwoorden (+{numReplies} andere): | Antwoorden (+{numReplies} anderen):", + "you": "(Jij)", + "plus_more": "+{number} meer", + "many_attachments": "Bericht heeft {number} bijlage | Bericht heeft {number} bijlagen", + "collapse_attachments": "Bijlagen invouwen", + "show_all_attachments": "Alle bijlagen tonen", + "show_attachment_in_modal": "In media venster tonen", + "hide_attachment": "Bijlage verbergen", + "thread_show_full": "Alle berichten in dit gesprek tonen ({numStatus} bericht in totaal, max. diepte {depth}) | Alle berichten in dit gesprek tonen ({numStatus} berichten in totaal, max. diepte {depth})", + "thread_show_full_with_icon": "{icon} {text}", + "thread_follow": "Rest van gesprek tonen ({numStatus} bericht in totaal) | Rest van gesprek tonen ({numStatus} berichten in totaal)", + "thread_follow_with_icon": "{icon} {text}", + "ancestor_follow": "{numReplies} ander antwoord onder dit bericht tonen | {numReplies} andere antwoorden onder dit bericht tonen", + "ancestor_follow_with_icon": "{icon} {text}", + "show_all_conversation_with_icon": "{icon} {text}" }, "time": { "years_short": "{0}j", @@ -841,13 +965,29 @@ "days_short": "{0}d", "day_short": "{0}d", "days": "{0} dagen", - "day": "{0} dag" + "day": "{0} dag", + "unit": { + "months": "{0} maand | {0} maanden", + "months_short": "{0}ma", + "seconds": "{0} seconde | {0} seconden", + "seconds_short": "{0}s", + "weeks": "{0} week | {0} weken", + "weeks_short": "{0}w", + "years": "{0} jaar | {0} jaren", + "years_short": "{0}j", + "days": "{0} dag | {0} dagen", + "days_short": "{0}d", + "hours": "{0} uur | {0} uren", + "hours_short": "{0}u", + "minutes": "{0} minuut | {0} minuten", + "minutes_short": "{0}min" + } }, "shoutbox": { "title": "Shoutbox" }, "errors": { - "storage_unavailable": "Pleroma kon browseropslag niet benaderen. Je login of lokale instellingen worden niet opgeslagen en je kunt onverwachte problemen ondervinden. Probeer cookies te accepteren." + "storage_unavailable": "Pleroma kan de browseropslag niet benaderen. Je login of lokale instellingen worden niet opgeslagen en je kunt onverwachte problemen ondervinden. Probeer cookies te accepteren." }, "display_date": { "today": "Vandaag" diff --git a/src/i18n/ru.json b/src/i18n/ru.json @@ -456,6 +456,15 @@ "subject_line_mastodon": "Как в Mastodon: скопировать как есть", "subject_line_email": "Как в электронной почте: \"re: тема\"", "subject_line_behavior": "Копировать тему в ответах", + "third_column_mode": "Когда недостаточно места, показывать третью колонку содержащую", + "third_column_mode_none": "Не показывать третью колонку совсем", + "third_column_mode_notifications": "Колонку уведомлений", + "third_column_mode_postform": "Форму отправки сообщения и навигацию", + "columns": "Колонки", + "column_sizes": "Размеры колонок", + "column_sizes_sidebar": "Боковой", + "column_sizes_content": "Содержимого", + "column_sizes_notifs": "Уведомлений", "no_mutes": "Нет игнорируемых", "no_blocks": "Нет блокировок", "notification_visibility_emoji_reactions": "Реакции", diff --git a/src/i18n/uk.json b/src/i18n/uk.json @@ -24,7 +24,21 @@ }, "flash_content": "Натисніть для перегляду змісту Flash за допомогою Ruffle (експериментально, може не працювати).", "flash_security": "Ця функція може становити ризик, оскільки Flash-вміст все ще є потенційно небезпечним.", - "flash_fail": "Не вдалося завантажити Flash-вміст, докладнішу інформацію дивись у консолі." + "flash_fail": "Не вдалося завантажити Flash-вміст, докладнішу інформацію дивись у консолі.", + "generic_error_message": "Виникла помилка: {0}", + "never_show_again": "Ніколи не показувати знову", + "scope_in_timeline": { + "direct": "Приватне", + "private": "Лише читачі", + "public": "Публічне", + "unlisted": "Непублічне" + }, + "undo": "Відмінити", + "yes": "Так", + "no": "Ні", + "unpin": "Відкріпити", + "scroll_to_top": "Вгору", + "pin": "Прикріпити" }, "finder": { "error_fetching_user": "Користувача не знайдено", @@ -39,7 +53,8 @@ "scope_options": "Параметри обсягу", "media_proxy": "Посередник медіа-даних", "text_limit": "Ліміт символів", - "upload_limit": "Обмеження завантажень" + "upload_limit": "Обмеження завантажень", + "shout": "Гучномовець" }, "exporter": { "processing": "Опрацьовую, скоро ви зможете завантажити файл", @@ -52,7 +67,7 @@ "mute": "Ігнорувати" }, "shoutbox": { - "title": "Оголошення" + "title": "Гучномовець" }, "about": { "staff": "Адміністрація", @@ -70,7 +85,10 @@ "accept": "Прийняти", "reject": "Відхилити", "accept_desc": "Поточний інстанс приймає повідомлення тільки з перелічених інстансів:", - "simple_policies": "Правила поточного інстансу" + "simple_policies": "Правила поточного інстансу", + "reason": "Причина", + "not_applicable": "н/в", + "instance": "Інстанс" }, "mrf_policies_desc": "Правила MRF розповсюджуються на даний інстанс. Наступні правила активні:", "mrf_policies": "Активувати правила MRF (модуль переписування повідомлень)", @@ -141,7 +159,9 @@ "followed_you": "підписався(-лась) на вас", "favorited_you": "вподобав(-ла) ваш допис", "broken_favorite": "Невідомий допис, шукаю його…", - "error": "Помилка при оновленні сповіщень: {0}" + "error": "Помилка при оновленні сповіщень: {0}", + "poll_ended": "опитування закінчено", + "submitted_report": "подав скаргу" }, "nav": { "chats": "Чати", @@ -161,11 +181,21 @@ "mentions": "Згадування", "back": "Назад", "administration": "Адміністрування", - "home_timeline": "Домашня стрічка" + "home_timeline": "Домашня стрічка", + "lists": "Списки", + "edit_pinned": "Редагувати прикріплене", + "edit_finish": "Завершити редагування", + "mobile_sidebar": "Ввімкнути бокову панель", + "mobile_notifications": "Відкрити сповіщення (є непрочитані)", + "mobile_notifications_close": "Закрити сповіщення", + "edit_nav_mobile": "Редагувати панель навігації", + "announcements": "Анонси" }, "media_modal": { "next": "Наступна", - "previous": "Попередня" + "previous": "Попередня", + "counter": "{current} / {total}", + "hide": "Закрити медіапереглядач" }, "password_reset": { "instruction": "Введіть свою адресу електронної пошти або ім’я користувача. Ми надішлемо вам посилання для скидання пароля.", @@ -205,7 +235,9 @@ "load_older": "Завантажити давніші взаємодії", "follows": "Нові підписки", "favs_repeats": "Поширення та вподобайки", - "moves": "Міграції користувачів" + "moves": "Міграції користувачів", + "emoji_reactions": "Емоджі реакції", + "reports": "Скарги" }, "errors": { "storage_unavailable": "Pleroma не змогла отримати доступ до сховища браузеру. Ваша сесія та налаштування не будуть збережені, це може спричинити непередбачувані проблеми. Спробуйте увімкнути cookie." @@ -219,7 +251,19 @@ "emoji": "Емодзі", "load_all": "Всі {emojiAmount} эмодзі завантажуються", "load_all_hint": "Завантажені перші {saneAmount} емодзі, завантаження всіх емодзі може призвести до проблем з продуктивністю.", - "unicode": "Стандартні емодзі" + "unicode": "Стандартні емодзі", + "regional_indicator": "Регіональний індикатор {letter}", + "unicode_groups": { + "animals-and-nature": "Тварини і Рослини", + "flags": "Прапори", + "food-and-drink": "Їжа та Напої", + "objects": "Об'єкти", + "people-and-body": "Люди та Тіло", + "smileys-and-emotion": "Смайлики та Емотікони", + "activities": "Активності", + "symbols": "Символи", + "travel-and-places": "Подорожі та Місця" + } }, "post_status": { "content_type": { @@ -253,7 +297,10 @@ "preview_empty": "Пустий", "media_description_error": "Не вдалось оновити медіа, спробуйте ще раз", "media_description": "Опис медіа", - "post": "Опублікувати" + "post": "Опублікувати", + "edit_unsupported_warning": "Pleroma не підтримує редагування згадувань чи голосувань.", + "edit_status": "Редагувати допис", + "edit_remote_warning": "Інші віддалені інстанси можуть не підтримувати редагування та вони можуть не отримати актуальну версію допису." }, "settings": { "blocks_imported": "Блокування імпортовані! Їх обробка триватиме певний час.", @@ -638,7 +685,61 @@ "backup_restore": "Резервне копіювання налаштувань" }, "right_sidebar": "Показувати бокову панель справа", - "hide_shoutbox": "Приховати оголошення інстансу" + "hide_shoutbox": "Приховати гучномовець", + "setting_server_side": "Цей параметр прив’язаний до вашого профілю та впливає на всі сеанси та клієнти", + "lists_navigation": "Показувати списки в навігації", + "account_backup": "Резервне копіювання облікового запису", + "account_backup_description": "Це дозволяє завантажити архів даних вашого облікового запису та ваших дописів, але їх ще не можна імпортувати в обліковий запис Pleroma.", + "add_backup_error": "Не вдалося додати нову резервну копію: {error}", + "account_alias": "Псевдоніми облікового запису", + "new_alias_target": "Додати новий псевдонім (напр. {example})", + "move_account_notes": "Якщо ви хочете перемістити обліковий запис на інший інстанс, вам потрібно перейти до свого цільового облікового запису та додати псевдонім, що вказує цей обліковий запис.", + "added_backup": "Додано нову резервну копію.", + "expert_mode": "Показати додаткові параметри", + "post_look_feel": "Відображення дописів", + "email_language": "Мова для отримання електронних листів від сервера", + "account_backup_table_head": "Резервне копіювання", + "download_backup": "Завантажити", + "backup_not_ready": "Резервна копія ще не готова.", + "remove_backup": "Видалити", + "list_backups_error": "Помилка під час отримання списку резервних копій: {error}", + "add_backup": "Створити нову резервну копію", + "account_alias_table_head": "Псевдонім", + "list_aliases_error": "Помилка під час отримання псевдонімів: {error}", + "hide_list_aliases_error_action": "Закрити", + "remove_alias": "Видалити цей псевдонім", + "added_alias": "Псевдонім додано.", + "add_alias_error": "Помилка під час додавання псевдоніма: {error}", + "move_account": "Перемістити обліковий запис", + "move_account_target": "Цільовий обліковий запис (напр. {example})", + "moved_account": "Обліковий запис переміщено.", + "move_account_error": "Помилка під час переміщення облікового запису: {error}", + "word_filter_and_more": "Фільтр слів та більше...", + "hide_bot_indication": "Сховати позначку бот у дописах", + "navbar_column_stretch": "Розтягнути панель навігації на ширину колонок", + "hide_wordfiltered_statuses": "Ховати фільтровані статуси", + "hide_muted_threads": "Ховати приглушені треди", + "posts": "Дописи", + "account_privacy": "Безпека", + "conversation_display": "Стиль відображення розмови", + "conversation_display_tree": "Деревоподібне", + "conversation_display_tree_quick": "Вигляд дерева", + "disable_sticky_headers": "Не закріплювати заголовок колонки зверху на сторінці", + "third_column_mode_none": "Не показувати третю колонку взагалі", + "third_column_mode_notifications": "Колонка сповіщень", + "columns": "Колонки", + "auto_update": "Автоматично показувати нові дописи", + "use_websockets": "Використовувати вебсокети (Оновлення в реальному часі)", + "use_at_icon": "Показувати {'@'} символ як іконку замість тексту", + "mute_bot_posts": "Приховати дописи ботів", + "always_show_post_button": "Завжди показувати плаваючу кнопку «Новий Допис»", + "hide_favorites_description": "Не показувати список моїх вподобань (люди все одно отримують сповіщення)", + "third_column_mode": "Коли достатньо місця, показувати третю колонку, що містить", + "user_popover_avatar_action_open": "Відкрити профіль", + "wordfilter": "Фільтр слів", + "mention_links": "Посилання для згадування", + "user_profiles": "Профілі користувачів", + "notification_visibility_polls": "Закінчення опитувань, в яких ви проголосували" }, "selectable_list": { "select_all": "Вибрати все" @@ -670,7 +771,10 @@ "captcha": "CAPTCHA", "register": "Зареєструватися", "reason_placeholder": "Цей інстанс обробляє запити на реєстрацію вручну.\nРозкажіть адміністрації чому ви хочете зареєструватися.", - "reason": "Причина реєстрації" + "reason": "Причина реєстрації", + "bio_optional": "Біографія (необов'язково)", + "email_language": "Якою мовою ви бажаєте отримувати електронні листи від сервера?", + "email_optional": "Ел. пошта (необов'язково)" }, "who_to_follow": { "who_to_follow": "На кого підписатися", @@ -734,7 +838,23 @@ "day": "{0} день", "seconds_short": "{0}с", "seconds": "{0} секунди", - "in_future": "через {0}" + "in_future": "через {0}", + "unit": { + "months": "{0} місяць | {0} місяців", + "minutes": "{0} хвилина | {0} хвилин", + "hours_short": "{0}год", + "minutes_short": "{0}хв", + "months_short": "{0}міс", + "seconds": "{0} секунда | {0} секунд", + "seconds_short": "{0}с", + "weeks_short": "{0}тижд", + "years": "{0} рік | {0} років", + "years_short": "{0}р.", + "days": "{0} день | {0} днів", + "days_short": "{0}д", + "hours": "{0} година | {0} годин", + "weeks": "{0} тиждень | {0} тижнів" + } }, "search": { "no_results": "Немає результатів", @@ -803,7 +923,9 @@ "disabled": "Не виділяти" }, "bot": "Бот", - "edit_profile": "Редагувати профіль" + "edit_profile": "Редагувати профіль", + "deactivated": "Деактивований", + "follow_cancel": "Скасувати запит" }, "status": { "copy_link": "Скопіювати посилання на допис", @@ -830,7 +952,16 @@ "thread_muted": "Нитка заглушена", "unmute_conversation": "Припинити глушити розмову", "external_source": "Зовнішнє джерело", - "expand": "Розгорнути" + "expand": "Розгорнути", + "edit": "Редагувати допис", + "edited_at": "(змінено: {time})", + "thread_follow_with_icon": "{icon} {text}", + "ancestor_follow_with_icon": "{icon} {text}", + "show_all_conversation_with_icon": "{icon} {text}", + "plus_more": "+{number} більше", + "thread_show_full_with_icon": "{icon} {text}", + "show_only_conversation_under_this": "Показати всі відповіді на цей допис", + "status_history": "Історія змін" }, "timeline": { "no_more_statuses": "Більше немає дописів", @@ -860,5 +991,36 @@ "profile_loading_error": "Вибачте, під час завантаження цього профілю виникла помилка.", "profile_does_not_exist": "Вибачте, цей профіль більше не існує.", "timeline_title": "Стрічка користувача" + }, + "report": { + "notes": "Примітки:", + "state": "Статус:", + "state_open": "відкритий", + "state_closed": "закритий", + "state_resolved": "вирішений", + "reported_statuses": "Дописи, на які подано скаргу:", + "reporter": "Позивач:", + "reported_user": "Відповідач:" + }, + "announcements": { + "delete_action": "Видалити", + "page_header": "Анонси", + "title": "Анонси", + "mark_as_read_action": "Позначити як прочитане", + "post_form_header": "Розмістити оголошення", + "post_placeholder": "Введіть текст вашого оголошення тут...", + "post_action": "Пост", + "post_error": "Помилка: {error}", + "close_error": "Закрити", + "start_time_prompt": "Початок: ", + "end_time_prompt": "Кінець: ", + "all_day_prompt": "Це захід на цілий день", + "published_time_display": "Опубліковано в {time}", + "start_time_display": "Початок о {time}", + "end_time_display": "Кінець о {time}", + "edit_action": "Редагувати", + "submit_edit_action": "Надіслати", + "cancel_edit_action": "Скасувати", + "inactive_message": "Це оголошення неактивне" } } diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js @@ -17,6 +17,7 @@ const saveImmedeatelyActions = [ 'markNotificationsAsSeen', 'clearCurrentUser', 'setCurrentUser', + 'setServerSideStorage', 'setHighlight', 'setOption', 'setClientData', diff --git a/src/main.js b/src/main.js @@ -6,10 +6,12 @@ import './lib/event_target_polyfill.js' import interfaceModule from './modules/interface.js' import instanceModule from './modules/instance.js' import statusesModule from './modules/statuses.js' +import listsModule from './modules/lists.js' import usersModule from './modules/users.js' import apiModule from './modules/api.js' import configModule from './modules/config.js' import serverSideConfigModule from './modules/serverSideConfig.js' +import serverSideStorageModule from './modules/serverSideStorage.js' import shoutModule from './modules/shout.js' import oauthModule from './modules/oauth.js' import authFlowModule from './modules/auth_flow.js' @@ -18,7 +20,11 @@ import oauthTokensModule from './modules/oauth_tokens.js' import reportsModule from './modules/reports.js' import pollsModule from './modules/polls.js' import postStatusModule from './modules/postStatus.js' +import editStatusModule from './modules/editStatus.js' +import statusHistoryModule from './modules/statusHistory.js' + import chatsModule from './modules/chats.js' +import announcementsModule from './modules/announcements.js' import { createI18n } from 'vue-i18n' @@ -42,6 +48,7 @@ messages.setLanguage(i18n, currentLocale) const persistedStateOptions = { paths: [ + 'serverSideStorage.cache', 'config', 'users.lastLoginName', 'oauth' @@ -70,9 +77,11 @@ const persistedStateOptions = { // TODO refactor users/statuses modules, they depend on each other users: usersModule, statuses: statusesModule, + lists: listsModule, api: apiModule, config: configModule, serverSideConfig: serverSideConfigModule, + serverSideStorage: serverSideStorageModule, shout: shoutModule, oauth: oauthModule, authFlow: authFlowModule, @@ -81,7 +90,10 @@ const persistedStateOptions = { reports: reportsModule, polls: pollsModule, postStatus: postStatusModule, - chats: chatsModule + editStatus: editStatusModule, + statusHistory: statusHistoryModule, + chats: chatsModule, + announcements: announcementsModule }, plugins, strict: false // Socket modifies itself, let's ignore this for now. diff --git a/src/modules/announcements.js b/src/modules/announcements.js @@ -0,0 +1,135 @@ +const FETCH_ANNOUNCEMENT_INTERVAL_MS = 1000 * 60 * 5 + +export const defaultState = { + announcements: [], + supportsAnnouncements: true, + fetchAnnouncementsTimer: undefined +} + +export const mutations = { + setAnnouncements (state, announcements) { + state.announcements = announcements + }, + setAnnouncementRead (state, { id, read }) { + const index = state.announcements.findIndex(a => a.id === id) + + if (index < 0) { + return + } + + state.announcements[index].read = read + }, + setFetchAnnouncementsTimer (state, timer) { + state.fetchAnnouncementsTimer = timer + }, + setSupportsAnnouncements (state, supportsAnnouncements) { + state.supportsAnnouncements = supportsAnnouncements + } +} + +export const getters = { + unreadAnnouncementCount (state, _getters, rootState) { + if (!rootState.users.currentUser) { + return 0 + } + + const unread = state.announcements.filter(announcement => !(announcement.inactive || announcement.read)) + return unread.length + } +} + +const announcements = { + state: defaultState, + mutations, + getters, + actions: { + fetchAnnouncements (store) { + if (!store.state.supportsAnnouncements) { + return Promise.resolve() + } + + const currentUser = store.rootState.users.currentUser + const isAdmin = currentUser && currentUser.privileges.includes('announcements_manage_announcements') + + const getAnnouncements = async () => { + if (!isAdmin) { + return store.rootState.api.backendInteractor.fetchAnnouncements() + } + + const all = await store.rootState.api.backendInteractor.adminFetchAnnouncements() + const visible = await store.rootState.api.backendInteractor.fetchAnnouncements() + const visibleObject = visible.reduce((a, c) => { + a[c.id] = c + return a + }, {}) + const getWithinVisible = announcement => visibleObject[announcement.id] + + all.forEach(announcement => { + const visibleAnnouncement = getWithinVisible(announcement) + if (!visibleAnnouncement) { + announcement.inactive = true + } else { + announcement.read = visibleAnnouncement.read + } + }) + + return all + } + + return getAnnouncements() + .then(announcements => { + store.commit('setAnnouncements', announcements) + }) + .catch(error => { + // If and only if backend does not support announcements, it would return 404. + // In this case, silently ignores it. + if (error && error.statusCode === 404) { + store.commit('setSupportsAnnouncements', false) + } else { + throw error + } + }) + }, + markAnnouncementAsRead (store, id) { + return store.rootState.api.backendInteractor.dismissAnnouncement({ id }) + .then(() => { + store.commit('setAnnouncementRead', { id, read: true }) + }) + }, + startFetchingAnnouncements (store) { + if (store.state.fetchAnnouncementsTimer) { + return + } + + const interval = setInterval(() => store.dispatch('fetchAnnouncements'), FETCH_ANNOUNCEMENT_INTERVAL_MS) + store.commit('setFetchAnnouncementsTimer', interval) + + return store.dispatch('fetchAnnouncements') + }, + stopFetchingAnnouncements (store) { + const interval = store.state.fetchAnnouncementsTimer + store.commit('setFetchAnnouncementsTimer', undefined) + clearInterval(interval) + }, + postAnnouncement (store, { content, startsAt, endsAt, allDay }) { + return store.rootState.api.backendInteractor.postAnnouncement({ content, startsAt, endsAt, allDay }) + .then(() => { + return store.dispatch('fetchAnnouncements') + }) + }, + editAnnouncement (store, { id, content, startsAt, endsAt, allDay }) { + return store.rootState.api.backendInteractor.editAnnouncement({ id, content, startsAt, endsAt, allDay }) + .then(() => { + return store.dispatch('fetchAnnouncements') + }) + }, + deleteAnnouncement (store, id) { + return store.rootState.api.backendInteractor.deleteAnnouncement({ id }) + .then(() => { + return store.dispatch('fetchAnnouncements') + }) + } + } +} + +export default announcements diff --git a/src/modules/api.js b/src/modules/api.js @@ -15,6 +15,9 @@ const api = { mastoUserSocketStatus: null, followRequests: [] }, + getters: { + followRequestCount: state => state.followRequests.length + }, mutations: { setBackendInteractor (state, backendInteractor) { state.backendInteractor = backendInteractor @@ -100,6 +103,13 @@ const api = { showImmediately: timelineData.visibleStatuses.length === 0, timeline: 'friends' }) + } else if (message.event === 'status.update') { + dispatch('addNewStatuses', { + statuses: [message.status], + userId: false, + showImmediately: message.status.id in timelineData.visibleStatusesObject, + timeline: 'friends' + }) } else if (message.event === 'delete') { dispatch('deleteStatusById', message.id) } else if (message.event === 'pleroma:chat_update') { @@ -191,12 +201,13 @@ const api = { startFetchingTimeline (store, { timeline = 'friends', tag = false, - userId = false + userId = false, + listId = false }) { if (store.state.fetchers[timeline]) return const fetcher = store.state.backendInteractor.startFetchingTimeline({ - timeline, store, userId, tag + timeline, store, userId, listId, tag }) store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, @@ -205,7 +216,7 @@ const api = { if (!fetcher) return store.commit('removeFetcher', { fetcherName: timeline, fetcher }) }, - fetchTimeline (store, timeline, { ...rest }) { + fetchTimeline (store, { timeline, ...rest }) { store.state.backendInteractor.fetchTimeline({ store, timeline, @@ -248,6 +259,18 @@ const api = { store.commit('setFollowRequests', requests) }, + // Lists + startFetchingLists (store) { + if (store.state.fetchers.lists) return + const fetcher = store.state.backendInteractor.startFetchingLists({ store }) + store.commit('addFetcher', { fetcherName: 'lists', fetcher }) + }, + stopFetchingLists (store) { + const fetcher = store.state.fetchers.lists + if (!fetcher) return + store.commit('removeFetcher', { fetcherName: 'lists', fetcher }) + }, + // Pleroma websocket setWsToken (store, token) { store.commit('setWsToken', token) diff --git a/src/modules/config.js b/src/modules/config.js @@ -1,5 +1,5 @@ import Cookies from 'js-cookie' -import { setPreset, applyTheme } from '../services/style_setter/style_setter.js' +import { setPreset, applyTheme, applyConfig } from '../services/style_setter/style_setter.js' import messages from '../i18n/messages' import localeService from '../services/locale/locale.service.js' @@ -17,7 +17,8 @@ export const multiChoiceProperties = [ 'subjectLineBehavior', 'conversationDisplay', // tree | linear 'conversationOtherRepliesButton', // below | inside - 'mentionLinkDisplay' // short | full_for_remote | full + 'mentionLinkDisplay', // short | full_for_remote | full + 'userPopoverAvatarAction' // close | zoom | open ] export const defaultState = { @@ -59,6 +60,7 @@ export const defaultState = { moves: true, emojiReactions: true, followRequest: true, + reports: true, chatMention: true, polls: true }, @@ -81,8 +83,12 @@ export const defaultState = { useContainFit: true, disableStickyHeaders: false, showScrollbars: false, - userPopoverZoom: false, - userPopoverOverlay: true, + userPopoverAvatarAction: 'open', + userPopoverOverlay: false, + sidebarColumnWidth: '25rem', + contentColumnWidth: '45rem', + notifsColumnWidth: '25rem', + navbarColumnStretch: false, greentext: undefined, // instance default useAtIcon: undefined, // instance default mentionLinkDisplay: undefined, // instance default @@ -160,18 +166,24 @@ const config = { setHighlight ({ commit, dispatch }, { user, color, type }) { commit('setHighlight', { user, color, type }) }, - setOption ({ commit, dispatch }, { name, value }) { + setOption ({ commit, dispatch, state }, { name, value }) { commit('setOption', { name, value }) switch (name) { case 'theme': setPreset(value) break + case 'sidebarColumnWidth': + case 'contentColumnWidth': + case 'notifsColumnWidth': + applyConfig(state) + break case 'customTheme': case 'customThemeSource': applyTheme(value) break case 'interfaceLanguage': messages.setLanguage(this.getters.i18n, value) + dispatch('loadUnicodeEmojiData', value) Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value)) break case 'thirdColumnMode': diff --git a/src/modules/editStatus.js b/src/modules/editStatus.js @@ -0,0 +1,25 @@ +const editStatus = { + state: { + params: null, + modalActivated: false + }, + mutations: { + openEditStatusModal (state, params) { + state.params = params + state.modalActivated = true + }, + closeEditStatusModal (state) { + state.modalActivated = false + } + }, + actions: { + openEditStatusModal ({ commit }, params) { + commit('openEditStatusModal', params) + }, + closeEditStatusModal ({ commit }) { + commit('closeEditStatusModal') + } + } +} + +export default editStatus diff --git a/src/modules/instance.js b/src/modules/instance.js @@ -2,6 +2,41 @@ import { getPreset, applyTheme } from '../services/style_setter/style_setter.js' import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' import apiService from '../services/api/api.service.js' import { instanceDefaultProperties } from './config.js' +import { langCodeToCldrName, ensureFinalFallback } from '../i18n/languages.js' + +const SORTED_EMOJI_GROUP_IDS = [ + 'smileys-and-emotion', + 'people-and-body', + 'animals-and-nature', + 'food-and-drink', + 'travel-and-places', + 'activities', + 'objects', + 'symbols', + 'flags' +] + +const REGIONAL_INDICATORS = (() => { + const start = 0x1F1E6 + const end = 0x1F1FF + const A = 'A'.codePointAt(0) + const res = new Array(end - start + 1) + for (let i = start; i <= end; ++i) { + const letter = String.fromCodePoint(A + i - start) + res[i - start] = { + replacement: String.fromCodePoint(i), + imageUrl: false, + displayText: 'regional_indicator_' + letter, + displayTextI18n: { + key: 'emoji.regional_indicator', + args: { letter } + } + } + } + return res +})() + +const REMOTE_INTERACTION_URL = '/main/ostatus' const defaultState = { // Stuff from apiConfig @@ -41,6 +76,7 @@ const defaultState = { logoMargin: '.2em', logoMask: true, logoLeft: false, + disableUpdateNotification: false, minimalScopesMode: false, nsfwCensorImage: undefined, postContentType: 'text/plain', @@ -63,8 +99,9 @@ const defaultState = { // Nasty stuff customEmoji: [], customEmojiFetched: false, - emoji: [], + emoji: {}, emojiFetched: false, + unicodeEmojiAnnotations: {}, pleromaBackend: true, postFormats: [], restrictedNicknames: [], @@ -96,6 +133,31 @@ const defaultState = { } } +const loadAnnotations = (lang) => { + return import( + /* webpackChunkName: "emoji-annotations/[request]" */ + `@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json` + ) + .then(k => k.default) +} + +const injectAnnotations = (emoji, annotations) => { + const availableLangs = Object.keys(annotations) + + return { + ...emoji, + annotations: availableLangs.reduce((acc, cur) => { + acc[cur] = annotations[cur][emoji.replacement] + return acc + }, {}) + } +} + +const injectRegionalIndicators = groups => { + groups.symbols.push(...REGIONAL_INDICATORS) + return groups +} + const instance = { state: defaultState, mutations: { @@ -106,6 +168,9 @@ const instance = { }, setKnownDomains (state, domains) { state.knownDomains = domains + }, + setUnicodeEmojiAnnotations (state, { lang, annotations }) { + state.unicodeEmojiAnnotations[lang] = annotations } }, getters: { @@ -114,8 +179,68 @@ const instance = { .map(key => [key, state[key]]) .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) }, + groupedCustomEmojis (state) { + const packsOf = emoji => { + const packs = emoji.tags + .filter(k => k.startsWith('pack:')) + .map(k => { + const packName = k.slice(5) // remove 'pack:' prefix + return { + id: `custom-${packName}`, + text: packName + } + }) + + if (!packs.length) { + return [{ + id: 'unpacked' + }] + } else { + return packs + } + } + + return state.customEmoji + .reduce((res, emoji) => { + packsOf(emoji).forEach(({ id: packId, text: packName }) => { + if (!res[packId]) { + res[packId] = ({ + id: packId, + text: packName, + image: emoji.imageUrl, + emojis: [] + }) + } + res[packId].emojis.push(emoji) + }) + return res + }, {}) + }, + standardEmojiList (state) { + return SORTED_EMOJI_GROUP_IDS + .map(groupId => (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations))) + .reduce((a, b) => a.concat(b), []) + }, + standardEmojiGroupList (state) { + return SORTED_EMOJI_GROUP_IDS.map(groupId => ({ + id: groupId, + emojis: (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations)) + })) + }, instanceDomain (state) { return new URL(state.server).hostname + }, + remoteInteractionLink (state) { + const server = state.server.endsWith('/') ? state.server.slice(0, -1) : state.server + const link = server + REMOTE_INTERACTION_URL + + return ({ statusId, nickname }) => { + if (statusId) { + return `${link}?status_id=${statusId}` + } else { + return `${link}?nickname=${nickname}` + } + } } }, actions: { @@ -137,32 +262,65 @@ const instance = { }, async getStaticEmoji ({ commit }) { try { - const res = await window.fetch('/static/emoji.json') - if (res.ok) { - const values = await res.json() - const emoji = Object.keys(values).map((key) => { - return { - displayText: key, - imageUrl: false, - replacement: values[key] - } - }).sort((a, b) => a.name > b.name ? 1 : -1) - commit('setInstanceOption', { name: 'emoji', value: emoji }) - } else { - throw (res) - } + const values = (await import(/* webpackChunkName: 'emoji' */ '../../static/emoji.json')).default + + const emoji = Object.keys(values).reduce((res, groupId) => { + res[groupId] = values[groupId].map(e => ({ + displayText: e.slug, + imageUrl: false, + replacement: e.emoji + })) + return res + }, {}) + commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) }) } catch (e) { console.warn("Can't load static emoji") console.warn(e) } }, + loadUnicodeEmojiData ({ commit, state }, language) { + const langList = ensureFinalFallback(language) + + return Promise.all( + langList + .map(async lang => { + if (!state.unicodeEmojiAnnotations[lang]) { + const annotations = await loadAnnotations(lang) + commit('setUnicodeEmojiAnnotations', { lang, annotations }) + } + })) + }, + async getCustomEmoji ({ commit, state }) { try { const res = await window.fetch('/api/pleroma/emoji.json') if (res.ok) { const result = await res.json() const values = Array.isArray(result) ? Object.assign({}, ...result) : result + const caseInsensitiveStrCmp = (a, b) => { + const la = a.toLowerCase() + const lb = b.toLowerCase() + return la > lb ? 1 : (la < lb ? -1 : 0) + } + const noPackLast = (a, b) => { + const aNull = a === '' + const bNull = b === '' + if (aNull === bNull) { + return 0 + } else if (aNull && !bNull) { + return 1 + } else { + return -1 + } + } + const byPackThenByName = (a, b) => { + const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5) + const packOfA = packOf(a) + const packOfB = packOf(b) + return noPackLast(packOfA, packOfB) || caseInsensitiveStrCmp(packOfA, packOfB) || caseInsensitiveStrCmp(a.displayText, b.displayText) + } + const emoji = Object.entries(values).map(([key, value]) => { const imageUrl = value.image_url return { @@ -173,7 +331,7 @@ const instance = { } // Technically could use tags but those are kinda useless right now, // should have been "pack" field, that would be more useful - }).sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : -1) + }).sort(byPackThenByName) commit('setInstanceOption', { name: 'customEmoji', value: emoji }) } else { throw (res) diff --git a/src/modules/lists.js b/src/modules/lists.js @@ -0,0 +1,130 @@ +import { remove, find } from 'lodash' + +export const defaultState = { + allLists: [], + allListsObject: {} +} + +export const mutations = { + setLists (state, value) { + state.allLists = value + }, + setList (state, { listId, title }) { + if (!state.allListsObject[listId]) { + state.allListsObject[listId] = { accountIds: [] } + } + state.allListsObject[listId].title = title + + const entry = find(state.allLists, { id: listId }) + if (!entry) { + state.allLists.push({ id: listId, title }) + } else { + entry.title = title + } + }, + setListAccounts (state, { listId, accountIds }) { + if (!state.allListsObject[listId]) { + state.allListsObject[listId] = { accountIds: [] } + } + state.allListsObject[listId].accountIds = accountIds + }, + addListAccount (state, { listId, accountId }) { + if (!state.allListsObject[listId]) { + state.allListsObject[listId] = { accountIds: [] } + } + state.allListsObject[listId].accountIds.push(accountId) + }, + removeListAccount (state, { listId, accountId }) { + if (!state.allListsObject[listId]) { + state.allListsObject[listId] = { accountIds: [] } + } + const { accountIds } = state.allListsObject[listId] + const set = new Set(accountIds) + set.delete(accountId) + state.allListsObject[listId].accountIds = [...set] + }, + deleteList (state, { listId }) { + delete state.allListsObject[listId] + remove(state.allLists, list => list.id === listId) + } +} + +const actions = { + setLists ({ commit }, value) { + commit('setLists', value) + }, + createList ({ rootState, commit }, { title }) { + return rootState.api.backendInteractor.createList({ title }) + .then((list) => { + commit('setList', { listId: list.id, title }) + return list + }) + }, + fetchList ({ rootState, commit }, { listId }) { + return rootState.api.backendInteractor.getList({ listId }) + .then((list) => commit('setList', { listId: list.id, title: list.title })) + }, + fetchListAccounts ({ rootState, commit }, { listId }) { + return rootState.api.backendInteractor.getListAccounts({ listId }) + .then((accountIds) => commit('setListAccounts', { listId, accountIds })) + }, + setList ({ rootState, commit }, { listId, title }) { + rootState.api.backendInteractor.updateList({ listId, title }) + commit('setList', { listId, title }) + }, + setListAccounts ({ rootState, commit }, { listId, accountIds }) { + const saved = rootState.lists.allListsObject[listId].accountIds || [] + const added = accountIds.filter(id => !saved.includes(id)) + const removed = saved.filter(id => !accountIds.includes(id)) + commit('setListAccounts', { listId, accountIds }) + if (added.length > 0) { + rootState.api.backendInteractor.addAccountsToList({ listId, accountIds: added }) + } + if (removed.length > 0) { + rootState.api.backendInteractor.removeAccountsFromList({ listId, accountIds: removed }) + } + }, + addListAccount ({ rootState, commit }, { listId, accountId }) { + return rootState + .api + .backendInteractor + .addAccountsToList({ listId, accountIds: [accountId] }) + .then((result) => { + commit('addListAccount', { listId, accountId }) + return result + }) + }, + removeListAccount ({ rootState, commit }, { listId, accountId }) { + return rootState + .api + .backendInteractor + .removeAccountsFromList({ listId, accountIds: [accountId] }) + .then((result) => { + commit('removeListAccount', { listId, accountId }) + return result + }) + }, + deleteList ({ rootState, commit }, { listId }) { + rootState.api.backendInteractor.deleteList({ listId }) + commit('deleteList', { listId }) + } +} + +export const getters = { + findListTitle: state => id => { + if (!state.allListsObject[id]) return + return state.allListsObject[id].title + }, + findListAccounts: state => id => { + return [...state.allListsObject[id].accountIds] + } +} + +const lists = { + state: defaultState, + mutations, + actions, + getters +} + +export default lists diff --git a/src/modules/reports.js b/src/modules/reports.js @@ -2,20 +2,29 @@ import filter from 'lodash/filter' const reports = { state: { - userId: null, - statuses: [], - preTickedIds: [], - modalActivated: false + reportModal: { + userId: null, + statuses: [], + preTickedIds: [], + activated: false + }, + reports: {} }, mutations: { openUserReportingModal (state, { userId, statuses, preTickedIds }) { - state.userId = userId - state.statuses = statuses - state.preTickedIds = preTickedIds - state.modalActivated = true + state.reportModal.userId = userId + state.reportModal.statuses = statuses + state.reportModal.preTickedIds = preTickedIds + state.reportModal.activated = true }, closeUserReportingModal (state) { - state.modalActivated = false + state.reportModal.activated = false + }, + setReportState (reportsState, { id, state }) { + reportsState.reports[id].state = state + }, + addReport (state, report) { + state.reports[report.id] = report } }, actions: { @@ -31,6 +40,23 @@ const reports = { }, closeUserReportingModal ({ commit }) { commit('closeUserReportingModal') + }, + setReportState ({ commit, dispatch, rootState }, { id, state }) { + const oldState = rootState.reports.reports[id].state + commit('setReportState', { id, state }) + rootState.api.backendInteractor.setReportState({ id, state }).catch(e => { + console.error('Failed to set report state', e) + dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'general.generic_error_message', + messageArgs: [e.message], + timeout: 5000 + }) + commit('setReportState', { id, state: oldState }) + }) + }, + addReport ({ commit }, report) { + commit('addReport', report) } } } diff --git a/src/modules/serverSideStorage.js b/src/modules/serverSideStorage.js @@ -0,0 +1,436 @@ +import { toRaw } from 'vue' +import { isEqual, cloneDeep, set, get, clamp, flatten, groupBy, findLastIndex, takeRight, uniqWith } from 'lodash' +import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js' + +export const VERSION = 1 +export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically + +export const COMMAND_TRIM_FLAGS = 1000 +export const COMMAND_TRIM_FLAGS_AND_RESET = 1001 + +export const defaultState = { + // do we need to update data on server? + dirty: false, + // storage of flags - stuff that can only be set and incremented + flagStorage: { + updateCounter: 0, // Counter for most recent update notification seen + reset: 0 // special flag that can be used to force-reset all flags, debug purposes only + // special reset codes: + // 1000: trim keys to those known by currently running FE + // 1001: same as above + reset everything to 0 + }, + prefsStorage: { + _journal: [], + simple: { + dontShowUpdateNotifs: false, + collapseNav: false + }, + collections: { + pinnedNavItems: ['home', 'dms', 'chats'] + } + }, + // raw data + raw: null, + // local cache + cache: null +} + +export const newUserFlags = { + ...defaultState.flagStorage, + updateCounter: CURRENT_UPDATE_COUNTER // new users don't need to see update notification +} + +export const _moveItemInArray = (array, value, movement) => { + const oldIndex = array.indexOf(value) + const newIndex = oldIndex + movement + const newArray = [...array] + // remove old + newArray.splice(oldIndex, 1) + // add new + newArray.splice(clamp(newIndex, 0, newArray.length + 1), 0, value) + return newArray +} + +const _wrapData = (data, userName) => ({ + ...data, + _user: userName, + _timestamp: Date.now(), + _version: VERSION +}) + +const _checkValidity = (data) => data._timestamp > 0 && data._version > 0 + +const _verifyPrefs = (state) => { + state.prefsStorage = state.prefsStorage || { + simple: {}, + collections: {} + } + Object.entries(defaultState.prefsStorage.simple).forEach(([k, v]) => { + if (typeof v === 'number' || typeof v === 'boolean') return + console.warn(`Preference simple.${k} as invalid type, reinitializing`) + set(state.prefsStorage.simple, k, defaultState.prefsStorage.simple[k]) + }) + Object.entries(defaultState.prefsStorage.collections).forEach(([k, v]) => { + if (Array.isArray(v)) return + console.warn(`Preference collections.${k} as invalid type, reinitializing`) + set(state.prefsStorage.collections, k, defaultState.prefsStorage.collections[k]) + }) +} + +export const _getRecentData = (cache, live) => { + const result = { recent: null, stale: null, needUpload: false } + const cacheValid = _checkValidity(cache || {}) + const liveValid = _checkValidity(live || {}) + if (!liveValid && cacheValid) { + result.needUpload = true + console.debug('Nothing valid stored on server, assuming cache to be source of truth') + result.recent = cache + result.stale = live + } else if (!cacheValid && liveValid) { + console.debug('Valid storage on server found, no local cache found, using live as source of truth') + result.recent = live + result.stale = cache + } else if (cacheValid && liveValid) { + console.debug('Both sources have valid data, figuring things out...') + if (live._timestamp === cache._timestamp && live._version === cache._version) { + console.debug('Same version/timestamp on both source, source of truth irrelevant') + result.recent = cache + result.stale = live + } else { + console.debug('Different timestamp, figuring out which one is more recent') + if (live._timestamp < cache._timestamp) { + result.recent = cache + result.stale = live + } else { + result.recent = live + result.stale = cache + } + } + } else { + console.debug('Both sources are invalid, start from scratch') + result.needUpload = true + } + return result +} + +export const _getAllFlags = (recent, stale) => { + return Array.from(new Set([ + ...Object.keys(toRaw((recent || {}).flagStorage || {})), + ...Object.keys(toRaw((stale || {}).flagStorage || {})) + ])) +} + +export const _mergeFlags = (recent, stale, allFlagKeys) => { + if (!stale.flagStorage) return recent.flagStorage + if (!recent.flagStorage) return stale.flagStorage + return Object.fromEntries(allFlagKeys.map(flag => { + const recentFlag = recent.flagStorage[flag] + const staleFlag = stale.flagStorage[flag] + // use flag that is of higher value + return [flag, Number((recentFlag > staleFlag ? recentFlag : staleFlag) || 0)] + })) +} + +const _mergeJournal = (...journals) => { + // Ignore invalid journal entries + const allJournals = flatten( + journals.map(j => Array.isArray(j) ? j : []) + ).filter(entry => + Object.prototype.hasOwnProperty.call(entry, 'path') && + Object.prototype.hasOwnProperty.call(entry, 'operation') && + Object.prototype.hasOwnProperty.call(entry, 'args') && + Object.prototype.hasOwnProperty.call(entry, 'timestamp') + ) + const grouped = groupBy(allJournals, 'path') + const trimmedGrouped = Object.entries(grouped).map(([path, journal]) => { + // side effect + journal.sort((a, b) => a.timestamp > b.timestamp ? 1 : -1) + + if (path.startsWith('collections')) { + const lastRemoveIndex = findLastIndex(journal, ({ operation }) => operation === 'removeFromCollection') + // everything before last remove is unimportant + let remainder + if (lastRemoveIndex > 0) { + remainder = journal.slice(lastRemoveIndex) + } else { + // everything else doesn't need trimming + remainder = journal + } + return uniqWith(remainder, (a, b) => { + if (a.path !== b.path) { return false } + if (a.operation !== b.operation) { return false } + if (a.operation === 'addToCollection') { + return a.args[0] === b.args[0] + } + return false + }) + } else if (path.startsWith('simple')) { + // Only the last record is important + return takeRight(journal) + } else { + return journal + } + }) + return flatten(trimmedGrouped) + .sort((a, b) => a.timestamp > b.timestamp ? 1 : -1) +} + +export const _mergePrefs = (recent, stale, allFlagKeys) => { + if (!stale) return recent + if (!recent) return stale + const { _journal: recentJournal, ...recentData } = recent + const { _journal: staleJournal } = stale + /** Journal entry format: + * path: path to entry in prefsStorage + * timestamp: timestamp of the change + * operation: operation type + * arguments: array of arguments, depends on operation type + * + * currently only supported operation type is "set" which just sets the value + * to requested one. Intended only to be used with simple preferences (boolean, number) + * shouldn't be used with collections! + */ + const resultOutput = { ...recentData } + const totalJournal = _mergeJournal(staleJournal, recentJournal) + totalJournal.forEach(({ path, timestamp, operation, command, args }) => { + if (path.startsWith('_')) { + console.error(`journal contains entry to edit internal (starts with _) field '${path}', something is incorrect here, ignoring.`) + return + } + switch (operation) { + case 'set': + set(resultOutput, path, args[0]) + break + case 'addToCollection': + set(resultOutput, path, Array.from(new Set(get(resultOutput, path)).add(args[0]))) + break + case 'removeFromCollection': { + const newSet = new Set(get(resultOutput, path)) + newSet.delete(args[0]) + set(resultOutput, path, Array.from(newSet)) + break + } + case 'reorderCollection': { + const [value, movement] = args + set(resultOutput, path, _moveItemInArray(get(resultOutput, path), value, movement)) + break + } + default: + console.error(`Unknown journal operation: '${operation}', did we forget to run reverse migrations beforehand?`) + } + }) + return { ...resultOutput, _journal: totalJournal } +} + +export const _resetFlags = (totalFlags, knownKeys = defaultState.flagStorage) => { + let result = { ...totalFlags } + const allFlagKeys = Object.keys(totalFlags) + // flag reset functionality + if (totalFlags.reset >= COMMAND_TRIM_FLAGS && totalFlags.reset <= COMMAND_TRIM_FLAGS_AND_RESET) { + console.debug('Received command to trim the flags') + const knownKeysSet = new Set(Object.keys(knownKeys)) + + // Trim + result = {} + allFlagKeys.forEach(flag => { + if (knownKeysSet.has(flag)) { + result[flag] = totalFlags[flag] + } + }) + + // Reset + if (totalFlags.reset === COMMAND_TRIM_FLAGS_AND_RESET) { + // 1001 - and reset everything to 0 + console.debug('Received command to reset the flags') + Object.keys(knownKeys).forEach(flag => { result[flag] = 0 }) + } + } else if (totalFlags.reset > 0 && totalFlags.reset < 9000) { + console.debug('Received command to reset the flags') + allFlagKeys.forEach(flag => { result[flag] = 0 }) + } + result.reset = 0 + return result +} + +export const _doMigrations = (cache) => { + if (!cache) return cache + + if (cache._version < VERSION) { + console.debug('Local cached data has older version, seeing if there any migrations that can be applied') + + // no migrations right now since we only have one version + console.debug('No migrations found') + } + + if (cache._version > VERSION) { + console.debug('Local cached data has newer version, seeing if there any reverse migrations that can be applied') + + // no reverse migrations right now but we leave a possibility of loading a hotpatch if need be + if (window._PLEROMA_HOTPATCH) { + if (window._PLEROMA_HOTPATCH.reverseMigrations) { + console.debug('Found hotpatch migration, applying') + return window._PLEROMA_HOTPATCH.reverseMigrations.call({}, 'serverSideStorage', { from: cache._version, to: VERSION }, cache) + } + } + } + + return cache +} + +export const mutations = { + clearServerSideStorage (state, userData) { + state = { ...cloneDeep(defaultState) } + }, + setServerSideStorage (state, userData) { + const live = userData.storage + state.raw = live + let cache = state.cache + if (cache && cache._user !== userData.fqn) { + console.warn('cache belongs to another user! reinitializing local cache!') + cache = null + } + + cache = _doMigrations(cache) + + let { recent, stale, needsUpload } = _getRecentData(cache, live) + + const userNew = userData.created_at > NEW_USER_DATE + const flagsTemplate = userNew ? newUserFlags : defaultState.flagStorage + let dirty = false + + if (recent === null) { + console.debug(`Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`) + recent = _wrapData({ + flagStorage: { ...flagsTemplate }, + prefsStorage: { ...defaultState.prefsStorage } + }) + } + + if (!needsUpload && recent && stale) { + console.debug('Checking if data needs merging...') + // discarding timestamps and versions + const { _timestamp: _0, _version: _1, ...recentData } = recent + const { _timestamp: _2, _version: _3, ...staleData } = stale + dirty = !isEqual(recentData, staleData) + console.debug(`Data ${dirty ? 'needs' : 'doesn\'t need'} merging`) + } + + const allFlagKeys = _getAllFlags(recent, stale) + let totalFlags + let totalPrefs + if (dirty) { + // Merge the flags + console.debug('Merging the data...') + totalFlags = _mergeFlags(recent, stale, allFlagKeys) + _verifyPrefs(recent) + _verifyPrefs(stale) + totalPrefs = _mergePrefs(recent.prefsStorage, stale.prefsStorage) + } else { + totalFlags = recent.flagStorage + totalPrefs = recent.prefsStorage + } + + totalFlags = _resetFlags(totalFlags) + + recent.flagStorage = { ...flagsTemplate, ...totalFlags } + recent.prefsStorage = { ...defaultState.prefsStorage, ...totalPrefs } + + state.dirty = dirty || needsUpload + state.cache = recent + // set local timestamp to smaller one if we don't have any changes + if (stale && recent && !state.dirty) { + state.cache._timestamp = Math.min(stale._timestamp, recent._timestamp) + } + state.flagStorage = state.cache.flagStorage + state.prefsStorage = state.cache.prefsStorage + }, + setFlag (state, { flag, value }) { + state.flagStorage[flag] = value + state.dirty = true + }, + setPreference (state, { path, value }) { + if (path.startsWith('_')) { + console.error(`tried to edit internal (starts with _) field '${path}', ignoring.`) + return + } + set(state.prefsStorage, path, value) + state.prefsStorage._journal = [ + ...state.prefsStorage._journal, + { operation: 'set', path, args: [value], timestamp: Date.now() } + ] + state.dirty = true + }, + addCollectionPreference (state, { path, value }) { + if (path.startsWith('_')) { + console.error(`tried to edit internal (starts with _) field '${path}', ignoring.`) + return + } + const collection = new Set(get(state.prefsStorage, path)) + collection.add(value) + set(state.prefsStorage, path, [...collection]) + state.prefsStorage._journal = [ + ...state.prefsStorage._journal, + { operation: 'addToCollection', path, args: [value], timestamp: Date.now() } + ] + state.dirty = true + }, + removeCollectionPreference (state, { path, value }) { + if (path.startsWith('_')) { + console.error(`tried to edit internal (starts with _) field '${path}', ignoring.`) + return + } + const collection = new Set(get(state.prefsStorage, path)) + collection.delete(value) + set(state.prefsStorage, path, [...collection]) + state.prefsStorage._journal = [ + ...state.prefsStorage._journal, + { operation: 'removeFromCollection', path, args: [value], timestamp: Date.now() } + ] + state.dirty = true + }, + reorderCollectionPreference (state, { path, value, movement }) { + if (path.startsWith('_')) { + console.error(`tried to edit internal (starts with _) field '${path}', ignoring.`) + return + } + const collection = get(state.prefsStorage, path) + const newCollection = _moveItemInArray(collection, value, movement) + set(state.prefsStorage, path, newCollection) + state.prefsStorage._journal = [ + ...state.prefsStorage._journal, + { operation: 'arrangeCollection', path, args: [value], timestamp: Date.now() } + ] + state.dirty = true + }, + updateCache (state, { username }) { + state.prefsStorage._journal = _mergeJournal(state.prefsStorage._journal) + state.cache = _wrapData({ + flagStorage: toRaw(state.flagStorage), + prefsStorage: toRaw(state.prefsStorage) + }, username) + } +} + +const serverSideStorage = { + state: { + ...cloneDeep(defaultState) + }, + mutations, + actions: { + pushServerSideStorage ({ state, rootState, commit }, { force = false } = {}) { + const needPush = state.dirty || force + console.log(needPush) + if (!needPush) return + commit('updateCache', { username: rootState.users.currentUser.fqn }) + const params = { pleroma_settings_store: { 'pleroma-fe': state.cache } } + rootState.api.backendInteractor + .updateProfile({ params }) + .then((user) => { + commit('setServerSideStorage', user) + state.dirty = false + }) + } + } +} + +export default serverSideStorage diff --git a/src/modules/statusHistory.js b/src/modules/statusHistory.js @@ -0,0 +1,25 @@ +const statusHistory = { + state: { + params: {}, + modalActivated: false + }, + mutations: { + openStatusHistoryModal (state, params) { + state.params = params + state.modalActivated = true + }, + closeStatusHistoryModal (state) { + state.modalActivated = false + } + }, + actions: { + openStatusHistoryModal ({ commit }, params) { + commit('openStatusHistoryModal', params) + }, + closeStatusHistoryModal ({ commit }) { + commit('closeStatusHistoryModal') + } + } +} + +export default statusHistory diff --git a/src/modules/statuses.js b/src/modules/statuses.js @@ -62,7 +62,8 @@ export const defaultState = () => ({ friends: emptyTl(), tag: emptyTl(), dms: emptyTl(), - bookmarks: emptyTl() + bookmarks: emptyTl(), + list: emptyTl() } }) @@ -248,6 +249,9 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us status: (status) => { addStatus(status, showImmediately) }, + edit: (status) => { + addStatus(status, showImmediately) + }, retweet: (status) => { // RetweetedStatuses are never shown immediately const retweetedStatus = addStatus(status.retweeted_status, false, false) @@ -336,6 +340,10 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item } + if (notification.type === 'pleroma:report') { + dispatch('addReport', notification.report) + } + if (notification.type === 'pleroma:emoji_reaction') { dispatch('fetchEmojiReactionsBy', notification.status.id) } @@ -601,6 +609,12 @@ const statuses = { return rootState.api.backendInteractor.fetchStatus({ id }) .then((status) => dispatch('addNewStatuses', { statuses: [status] })) }, + fetchStatusSource ({ rootState, dispatch }, status) { + return apiService.fetchStatusSource({ id: status.id, credentials: rootState.users.currentUser.credentials }) + }, + fetchStatusHistory ({ rootState, dispatch }, status) { + return apiService.fetchStatusHistory({ status }) + }, deleteStatus ({ rootState, commit }, status) { commit('setDeleted', { status }) apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials }) @@ -747,10 +761,11 @@ const statuses = { rootState.api.backendInteractor.fetchRebloggedByUsers({ id }) .then(rebloggedByUsers => commit('addRepeats', { id, rebloggedByUsers, currentUser: rootState.users.currentUser })) }, - search (store, { q, resolve, limit, offset, following }) { - return store.rootState.api.backendInteractor.search2({ q, resolve, limit, offset, following }) + search (store, { q, resolve, limit, offset, following, type }) { + return store.rootState.api.backendInteractor.search2({ q, resolve, limit, offset, following, type }) .then((data) => { store.commit('addNewUsers', data.accounts) + store.commit('addNewUsers', data.statuses.map(s => s.user).filter(u => u)) store.commit('addNewStatuses', { statuses: data.statuses }) return data }) diff --git a/src/modules/users.js b/src/modules/users.js @@ -16,9 +16,6 @@ export const mergeOrAdd = (arr, obj, item) => { // This is a new item, prepare it arr.push(item) obj[item.id] = item - if (item.screen_name && !item.screen_name.includes('@')) { - obj[item.screen_name.toLowerCase()] = item - } return { item, new: true } } } @@ -54,6 +51,16 @@ const unblockUser = (store, id) => { .then((relationship) => store.commit('updateUserRelationship', [relationship])) } +const removeUserFromFollowers = (store, id) => { + return store.rootState.api.backendInteractor.removeUserFromFollowers({ id }) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + +const editUserNote = (store, { id, comment }) => { + return store.rootState.api.backendInteractor.editUserNote({ id, comment }) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + const muteUser = (store, id) => { const predictedRelationship = store.state.relationships[id] || { id } predictedRelationship.muting = true @@ -162,7 +169,11 @@ export const mutations = { if (user.relationship) { state.relationships[user.relationship.id] = user.relationship } - mergeOrAdd(state.users, state.usersObject, user) + const res = mergeOrAdd(state.users, state.usersObject, user) + const item = res.item + if (res.new && item.screen_name && !item.screen_name.includes('@')) { + state.usersByNameObject[item.screen_name.toLowerCase()] = item + } }) }, updateUserRelationship (state, relationships) { @@ -170,6 +181,9 @@ export const mutations = { state.relationships[relationship.id] = relationship }) }, + updateUserInLists (state, { id, inLists }) { + state.usersObject[id].inLists = inLists + }, saveBlockIds (state, blockIds) { state.currentUser.blockIds = blockIds }, @@ -239,12 +253,10 @@ export const mutations = { export const getters = { findUser: state => query => { - const result = state.usersObject[query] - // In case it's a screen_name, we can try searching case-insensitive - if (!result && typeof query === 'string') { - return state.usersObject[query.toLowerCase()] - } - return result + return state.usersObject[query] + }, + findUserByName: state => query => { + return state.usersByNameObject[query.toLowerCase()] }, findUserByUrl: state => query => { return state.users @@ -263,6 +275,7 @@ export const defaultState = { currentUser: false, users: [], usersObject: {}, + usersByNameObject: {}, signUpPending: false, signUpErrors: [], relationships: {} @@ -285,12 +298,25 @@ const users = { return user }) }, + fetchUserByName (store, name) { + return store.rootState.api.backendInteractor.fetchUserByName({ name }) + .then((user) => { + store.commit('addNewUsers', [user]) + return user + }) + }, fetchUserRelationship (store, id) { if (store.state.currentUser) { store.rootState.api.backendInteractor.fetchUserRelationship({ id }) .then((relationships) => store.commit('updateUserRelationship', relationships)) } }, + fetchUserInLists (store, id) { + if (store.state.currentUser) { + store.rootState.api.backendInteractor.fetchUserInLists({ id }) + .then((inLists) => store.commit('updateUserInLists', { id, inLists })) + } + }, fetchBlocks (store) { return store.rootState.api.backendInteractor.fetchBlocks() .then((blocks) => { @@ -305,12 +331,18 @@ const users = { unblockUser (store, id) { return unblockUser(store, id) }, + removeUserFromFollowers (store, id) { + return removeUserFromFollowers(store, id) + }, blockUsers (store, ids = []) { return Promise.all(ids.map(id => blockUser(store, id))) }, unblockUsers (store, ids = []) { return Promise.all(ids.map(id => unblockUser(store, id))) }, + editUserNote (store, args) { + return editUserNote(store, args) + }, fetchMutes (store) { return store.rootState.api.backendInteractor.fetchMutes() .then((mutes) => { @@ -502,6 +534,7 @@ const users = { store.dispatch('stopFetchingTimeline', 'friends') store.commit('setBackendInteractor', backendInteractorService(store.getters.getToken())) store.dispatch('stopFetchingNotifications') + store.dispatch('stopFetchingLists') store.dispatch('stopFetchingFollowRequests') store.commit('clearNotifications') store.commit('resetStatuses') @@ -509,6 +542,7 @@ const users = { store.dispatch('setLastTimeline', 'public-timeline') store.dispatch('setLayoutWidth', windowWidth()) store.dispatch('setLayoutHeight', windowHeight()) + store.commit('clearServerSideStorage') }) }, loginUser (store, accessToken) { @@ -525,6 +559,7 @@ const users = { user.muteIds = [] user.domainMutes = [] commit('setCurrentUser', user) + commit('setServerSideStorage', user) commit('addNewUsers', [user]) store.dispatch('fetchEmoji') @@ -534,6 +569,7 @@ const users = { // Set our new backend interactor commit('setBackendInteractor', backendInteractorService(accessToken)) + store.dispatch('pushServerSideStorage') if (user.token) { store.dispatch('setWsToken', user.token) @@ -553,8 +589,14 @@ const users = { store.dispatch('startFetchingChats') } + store.dispatch('startFetchingLists') + + if (user.locked) { + store.dispatch('startFetchingFollowRequests') + } + if (store.getters.mergedConfig.useStreamingApi) { - store.dispatch('fetchTimeline', 'friends', { since: null }) + store.dispatch('fetchTimeline', { timeline: 'friends', since: null }) store.dispatch('fetchNotifications', { since: null }) store.dispatch('enableMastoSockets', true).catch((error) => { console.error('Failed initializing MastoAPI Streaming socket', error) diff --git a/src/panel.scss b/src/panel.scss @@ -1,3 +1,4 @@ +/* stylelint-disable no-descending-specificity */ .panel { position: relative; display: flex; @@ -12,14 +13,14 @@ } &::after { - content: ''; + content: ""; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 5; - box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6); + box-shadow: 1px 1px 4px rgb(0 0 0 / 60%); box-shadow: var(--panelShadow); pointer-events: none; } @@ -45,8 +46,9 @@ .panel-heading, .panel-footer { --panel-heading-height-padding: 0.6em; + --__panel-heading-gap: 0.5em; --__panel-heading-height: 3.2em; - --__panel-heading-height-inner: calc(var(--__panel-heading-height) - 2 * var(--panel-heading-height-padding)); + --__panel-heading-height-inner: calc(var(--__panel-heading-height) - 2 * var(--panel-heading-height-padding, 0)); position: relative; box-sizing: border-box; @@ -54,10 +56,10 @@ grid-auto-flow: column; grid-template-columns: minmax(50%, 1fr); grid-auto-columns: auto; - grid-column-gap: 0.5em; + grid-column-gap: var(--__panel-heading-gap); flex: none; background-size: cover; - padding: 0.6em; + padding: var(--panel-heading-height-padding); height: var(--__panel-heading-height); line-height: var(--__panel-heading-height-inner); z-index: 4; @@ -86,7 +88,7 @@ &::after, &::before { - content: ''; + content: ""; position: absolute; top: 0; bottom: 0; @@ -125,7 +127,7 @@ .panel-heading { border-radius: $fallback--panelRadius $fallback--panelRadius 0 0; border-radius: var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius) 0 0; - border-width: 0 0 1px 0; + border-width: 0 0 1px; align-items: start; // panel theme color: var(--panelText); @@ -147,6 +149,15 @@ color: var(--panelLink, $fallback--link); } + .button-unstyled:hover, + a:hover { + i[class*="icon-"], + .svg-inline--fa, + .iconLetter { + color: var(--panelText); + } + } + .faint { background-color: transparent; color: $fallback--faint; @@ -163,7 +174,7 @@ flex-shrink: 0; &, - i[class*=icon-] { + i[class*="icon-"] { color: $fallback--text; color: var(--btnPanelText, $fallback--text); } @@ -186,13 +197,46 @@ } } } + + .rightside-button { + align-self: stretch; + text-align: center; + width: var(--__panel-heading-height); + height: var(--__panel-heading-height); + margin: calc(-1 * var(--panel-heading-height-padding)) 0; + margin-right: calc(-1 * var(--__panel-heading-gap)); + + > button { + box-sizing: border-box; + padding: calc(1 * var(--panel-heading-height-padding)) 0; + height: 100%; + width: 100%; + text-align: center; + + svg { + font-size: 1.2em; + } + } + } + + .rightside-icon { + align-self: stretch; + text-align: center; + width: var(--__panel-heading-height); + margin-right: calc(-1 * var(--__panel-heading-gap)); + + svg { + font-size: 1.2em; + } + } } .panel-footer { border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius; border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius); align-items: center; - border-width: 1px 0 0 0; + border-width: 1px 0 0; border-style: solid; border-color: var(--border, $fallback--border); } +/* stylelint-enable no-descending-specificity */ diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js @@ -1,5 +1,5 @@ import { each, map, concat, last, get } from 'lodash' -import { parseStatus, parseUser, parseNotification, parseAttachment, parseChat, parseLinkHeaderPagination } from '../entity_normalizer/entity_normalizer.service.js' +import { parseStatus, parseSource, parseUser, parseNotification, parseAttachment, parseChat, parseLinkHeaderPagination } from '../entity_normalizer/entity_normalizer.service.js' import { RegistrationError, StatusCodeError } from '../errors/errors' /* eslint-env browser */ @@ -49,9 +49,16 @@ const MASTODON_PUBLIC_TIMELINE = '/api/v1/timelines/public' const MASTODON_USER_HOME_TIMELINE_URL = '/api/v1/timelines/home' const MASTODON_STATUS_URL = id => `/api/v1/statuses/${id}` const MASTODON_STATUS_CONTEXT_URL = id => `/api/v1/statuses/${id}/context` +const MASTODON_STATUS_SOURCE_URL = id => `/api/v1/statuses/${id}/source` +const MASTODON_STATUS_HISTORY_URL = id => `/api/v1/statuses/${id}/history` const MASTODON_USER_URL = '/api/v1/accounts' +const MASTODON_USER_LOOKUP_URL = '/api/v1/accounts/lookup' const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships' const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses` +const MASTODON_USER_IN_LISTS = id => `/api/v1/accounts/${id}/lists` +const MASTODON_LIST_URL = id => `/api/v1/lists/${id}` +const MASTODON_LIST_TIMELINE_URL = id => `/api/v1/timelines/list/${id}` +const MASTODON_LIST_ACCOUNTS_URL = id => `/api/v1/lists/${id}/accounts` const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}` const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks' const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/' @@ -60,8 +67,10 @@ const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block` const MASTODON_UNBLOCK_USER_URL = id => `/api/v1/accounts/${id}/unblock` const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute` const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute` +const MASTODON_REMOVE_USER_FROM_FOLLOWERS = id => `/api/v1/accounts/${id}/remove_from_followers` const MASTODON_SUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/subscribe` const MASTODON_UNSUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/unsubscribe` +const MASTODON_USER_NOTE_URL = id => `/api/v1/accounts/${id}/note` const MASTODON_BOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/bookmark` const MASTODON_UNBOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/unbookmark` const MASTODON_POST_STATUS_URL = '/api/v1/statuses' @@ -79,8 +88,11 @@ const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute` const MASTODON_SEARCH_2 = '/api/v2/search' const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks' +const MASTODON_LISTS_URL = '/api/v1/lists' const MASTODON_STREAMING = '/api/v1/streaming' const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers' +const MASTODON_ANNOUNCEMENTS_URL = '/api/v1/announcements' +const MASTODON_ANNOUNCEMENTS_DISMISS_URL = id => `/api/v1/announcements/${id}/dismiss` const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions` const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}` const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}` @@ -89,7 +101,12 @@ const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}` const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages` const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read` const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}` +const PLEROMA_ADMIN_REPORTS = '/api/pleroma/admin/reports' const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups' +const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements' +const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' +const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` +const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const oldfetch = window.fetch @@ -147,7 +164,7 @@ const updateNotificationSettings = ({ credentials, settings }) => { form.append(key, value) }) - return fetch(NOTIFICATION_SETTINGS_URL, { + return fetch(`${NOTIFICATION_SETTINGS_URL}?${new URLSearchParams(settings)}`, { headers: authHeaders(credentials), method: 'PUT', body: form @@ -257,6 +274,13 @@ const unfollowUser = ({ id, credentials }) => { }).then((data) => data.json()) } +const fetchUserInLists = ({ id, credentials }) => { + const url = MASTODON_USER_IN_LISTS(id) + return fetch(url, { + headers: authHeaders(credentials) + }).then((data) => data.json()) +} + const pinOwnStatus = ({ id, credentials }) => { return promisedRequest({ url: MASTODON_PIN_OWN_STATUS(id), credentials, method: 'POST' }) .then((data) => parseStatus(data)) @@ -291,6 +315,24 @@ const unblockUser = ({ id, credentials }) => { }).then((data) => data.json()) } +const removeUserFromFollowers = ({ id, credentials }) => { + return fetch(MASTODON_REMOVE_USER_FROM_FOLLOWERS(id), { + headers: authHeaders(credentials), + method: 'POST' + }).then((data) => data.json()) +} + +const editUserNote = ({ id, credentials, comment }) => { + return promisedRequest({ + url: MASTODON_USER_NOTE_URL(id), + credentials, + payload: { + comment + }, + method: 'POST' + }) +} + const approveUser = ({ id, credentials }) => { const url = MASTODON_APPROVE_USER_URL(id) return fetch(url, { @@ -313,6 +355,25 @@ const fetchUser = ({ id, credentials }) => { .then((data) => parseUser(data)) } +const fetchUserByName = ({ name, credentials }) => { + return promisedRequest({ + url: MASTODON_USER_LOOKUP_URL, + credentials, + params: { acct: name } + }) + .then(data => data.id) + .catch(error => { + if (error && error.statusCode === 404) { + // Either the backend does not support lookup endpoint, + // or there is no user with such name. Fallback and treat name as id. + return name + } else { + throw error + } + }) + .then(id => fetchUser({ id, credentials })) +} + const fetchUserRelationship = ({ id, credentials }) => { const url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}` return fetch(url, { headers: authHeaders(credentials) }) @@ -385,6 +446,81 @@ const fetchFollowRequests = ({ credentials }) => { .then((data) => data.map(parseUser)) } +const fetchLists = ({ credentials }) => { + const url = MASTODON_LISTS_URL + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) +} + +const createList = ({ title, credentials }) => { + const url = MASTODON_LISTS_URL + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'POST', + body: JSON.stringify({ title }) + }).then((data) => data.json()) +} + +const getList = ({ listId, credentials }) => { + const url = MASTODON_LIST_URL(listId) + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) +} + +const updateList = ({ listId, title, credentials }) => { + const url = MASTODON_LIST_URL(listId) + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'PUT', + body: JSON.stringify({ title }) + }) +} + +const getListAccounts = ({ listId, credentials }) => { + const url = MASTODON_LIST_ACCOUNTS_URL(listId) + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) + .then((data) => data.map(({ id }) => id)) +} + +const addAccountsToList = ({ listId, accountIds, credentials }) => { + const url = MASTODON_LIST_ACCOUNTS_URL(listId) + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'POST', + body: JSON.stringify({ account_ids: accountIds }) + }) +} + +const removeAccountsFromList = ({ listId, accountIds, credentials }) => { + const url = MASTODON_LIST_ACCOUNTS_URL(listId) + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'DELETE', + body: JSON.stringify({ account_ids: accountIds }) + }) +} + +const deleteList = ({ listId, credentials }) => { + const url = MASTODON_LIST_URL(listId) + return fetch(url, { + method: 'DELETE', + headers: authHeaders(credentials) + }) +} + const fetchConversation = ({ id, credentials }) => { const urlContext = MASTODON_STATUS_CONTEXT_URL(id) return fetch(urlContext, { headers: authHeaders(credentials) }) @@ -414,6 +550,31 @@ const fetchStatus = ({ id, credentials }) => { .then((data) => parseStatus(data)) } +const fetchStatusSource = ({ id, credentials }) => { + const url = MASTODON_STATUS_SOURCE_URL(id) + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => { + if (data.ok) { + return data + } + throw new Error('Error fetching source', data) + }) + .then((data) => data.json()) + .then((data) => parseSource(data)) +} + +const fetchStatusHistory = ({ status, credentials }) => { + const url = MASTODON_STATUS_HISTORY_URL(status.id) + return promisedRequest({ url, credentials }) + .then((data) => { + data.reverse() + return data.map((item) => { + item.originalStatus = status + return parseStatus(item) + }) + }) +} + const tagUser = ({ tag, credentials, user }) => { const screenName = user.screen_name const form = { @@ -506,9 +667,11 @@ const fetchTimeline = ({ since = false, until = false, userId = false, + listId = false, tag = false, withMuted = false, - replyVisibility = 'all' + replyVisibility = 'all', + includeTypes = [] }) => { const timelineUrls = { public: MASTODON_PUBLIC_TIMELINE, @@ -518,6 +681,7 @@ const fetchTimeline = ({ publicAndExternal: MASTODON_PUBLIC_TIMELINE, user: MASTODON_USER_TIMELINE_URL, media: MASTODON_USER_TIMELINE_URL, + list: MASTODON_LIST_TIMELINE_URL, favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, tag: MASTODON_TAG_TIMELINE_URL, bookmarks: MASTODON_BOOKMARK_TIMELINE_URL @@ -531,6 +695,10 @@ const fetchTimeline = ({ url = url(userId) } + if (timeline === 'list') { + url = url(listId) + } + if (since) { params.push(['since_id', since]) } @@ -555,32 +723,33 @@ const fetchTimeline = ({ if (replyVisibility !== 'all') { params.push(['reply_visibility', replyVisibility]) } + if (includeTypes.length > 0) { + includeTypes.forEach(type => { + params.push(['include_types[]', type]) + }) + } params.push(['limit', 20]) const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') url += `?${queryString}` - let status = '' - let statusText = '' - - let pagination = {} return fetch(url, { headers: authHeaders(credentials) }) - .then((data) => { - status = data.status - statusText = data.statusText - pagination = parseLinkHeaderPagination(data.headers.get('Link'), { - flakeId: timeline !== 'bookmarks' && timeline !== 'notifications' - }) - return data - }) - .then((data) => data.json()) - .then((data) => { - if (!data.errors) { + .then(async (response) => { + const success = response.ok + + const data = await response.json() + + if (success && !data.errors) { + const pagination = parseLinkHeaderPagination(response.headers.get('Link'), { + flakeId: timeline !== 'bookmarks' && timeline !== 'notifications' + }) + return { data: data.map(isNotifications ? parseNotification : parseStatus), pagination } } else { - data.status = status - data.statusText = statusText + data.errors ||= [] + data.status = response.status + data.statusText = response.statusText return data } }) @@ -705,6 +874,54 @@ const postStatus = ({ .then((data) => data.error ? data : parseStatus(data)) } +const editStatus = ({ + id, + credentials, + status, + spoilerText, + sensitive, + poll, + mediaIds = [], + contentType +}) => { + const form = new FormData() + const pollOptions = poll.options || [] + + form.append('status', status) + if (spoilerText) form.append('spoiler_text', spoilerText) + if (sensitive) form.append('sensitive', sensitive) + if (contentType) form.append('content_type', contentType) + mediaIds.forEach(val => { + form.append('media_ids[]', val) + }) + + if (pollOptions.some(option => option !== '')) { + const normalizedPoll = { + expires_in: poll.expiresIn, + multiple: poll.multiple + } + Object.keys(normalizedPoll).forEach(key => { + form.append(`poll[${key}]`, normalizedPoll[key]) + }) + + pollOptions.forEach(option => { + form.append('poll[options][]', option) + }) + } + + const putHeaders = authHeaders(credentials) + + return fetch(MASTODON_STATUS_URL(id), { + body: form, + method: 'PUT', + headers: putHeaders + }) + .then((response) => { + return response.json() + }) + .then((data) => data.error ? data : parseStatus(data)) +} + const deleteStatus = ({ id, credentials }) => { return fetch(MASTODON_DELETE_URL(id), { headers: authHeaders(credentials), @@ -1075,7 +1292,7 @@ const searchUsers = ({ credentials, query }) => { .then((data) => data.map(parseUser)) } -const search2 = ({ credentials, q, resolve, limit, offset, following }) => { +const search2 = ({ credentials, q, resolve, limit, offset, following, type }) => { let url = MASTODON_SEARCH_2 const params = [] @@ -1099,6 +1316,10 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => { params.push(['following', true]) } + if (type) { + params.push(['following', type]) + } + params.push(['with_relationships', true]) const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') @@ -1154,6 +1375,66 @@ const dismissNotification = ({ credentials, id }) => { }) } +const adminFetchAnnouncements = ({ credentials }) => { + return promisedRequest({ url: PLEROMA_ANNOUNCEMENTS_URL, credentials }) +} + +const fetchAnnouncements = ({ credentials }) => { + return promisedRequest({ url: MASTODON_ANNOUNCEMENTS_URL, credentials }) +} + +const dismissAnnouncement = ({ id, credentials }) => { + return promisedRequest({ + url: MASTODON_ANNOUNCEMENTS_DISMISS_URL(id), + credentials, + method: 'POST' + }) +} + +const announcementToPayload = ({ content, startsAt, endsAt, allDay }) => { + const payload = { content } + + if (typeof startsAt !== 'undefined') { + payload.starts_at = startsAt ? new Date(startsAt).toISOString() : null + } + + if (typeof endsAt !== 'undefined') { + payload.ends_at = endsAt ? new Date(endsAt).toISOString() : null + } + + if (typeof allDay !== 'undefined') { + payload.all_day = allDay + } + + return payload +} + +const postAnnouncement = ({ credentials, content, startsAt, endsAt, allDay }) => { + return promisedRequest({ + url: PLEROMA_POST_ANNOUNCEMENT_URL, + credentials, + method: 'POST', + payload: announcementToPayload({ content, startsAt, endsAt, allDay }) + }) +} + +const editAnnouncement = ({ id, credentials, content, startsAt, endsAt, allDay }) => { + return promisedRequest({ + url: PLEROMA_EDIT_ANNOUNCEMENT_URL(id), + credentials, + method: 'PATCH', + payload: announcementToPayload({ content, startsAt, endsAt, allDay }) + }) +} + +const deleteAnnouncement = ({ id, credentials }) => { + return promisedRequest({ + url: PLEROMA_DELETE_ANNOUNCEMENT_URL(id), + credentials, + method: 'DELETE' + }) +} + export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => { return Object.entries({ ...(credentials @@ -1171,7 +1452,8 @@ const MASTODON_STREAMING_EVENTS = new Set([ 'update', 'notification', 'delete', - 'filters_changed' + 'filters_changed', + 'status.update' ]) const PLEROMA_STREAMING_EVENTS = new Set([ @@ -1243,6 +1525,8 @@ export const handleMastoWS = (wsEvent) => { const data = payload ? JSON.parse(payload) : null if (event === 'update') { return { event, status: parseStatus(data) } + } else if (event === 'status.update') { + return { event, status: parseStatus(data) } } else if (event === 'notification') { return { event, notification: parseNotification(data) } } else if (event === 'pleroma:chat_update') { @@ -1339,12 +1623,46 @@ const deleteChatMessage = ({ chatId, messageId, credentials }) => { }) } +const setReportState = ({ id, state, credentials }) => { + // TODO: Can't use promisedRequest because on OK this does not return json + // See https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1322 + return fetch(PLEROMA_ADMIN_REPORTS, { + headers: { + ...authHeaders(credentials), + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + method: 'PATCH', + body: JSON.stringify({ + reports: [{ + id, + state + }] + }) + }) + .then(data => { + if (data.status >= 500) { + throw Error(data.statusText) + } else if (data.status >= 400) { + return data.json() + } + return data + }) + .then(data => { + if (data.errors) { + throw Error(data.errors[0].message) + } + }) +} + const apiService = { verifyCredentials, fetchTimeline, fetchPinnedStatuses, fetchConversation, fetchStatus, + fetchStatusSource, + fetchStatusHistory, fetchFriends, exportFriends, fetchFollowers, @@ -1356,7 +1674,10 @@ const apiService = { unmuteConversation, blockUser, unblockUser, + removeUserFromFollowers, + editUserNote, fetchUser, + fetchUserByName, fetchUserRelationship, favorite, unfavorite, @@ -1365,6 +1686,7 @@ const apiService = { bookmarkStatus, unbookmarkStatus, postStatus, + editStatus, deleteStatus, uploadMedia, setMediaDescription, @@ -1405,6 +1727,14 @@ const apiService = { addBackup, listBackups, fetchFollowRequests, + fetchLists, + createList, + getList, + updateList, + getListAccounts, + addAccountsToList, + removeAccountsFromList, + deleteList, approveUser, denyUser, suggestions, @@ -1430,7 +1760,15 @@ const apiService = { chatMessages, sendChatMessage, readChat, - deleteChatMessage + deleteChatMessage, + setReportState, + fetchUserInLists, + fetchAnnouncements, + dismissAnnouncement, + postAnnouncement, + editAnnouncement, + deleteAnnouncement, + adminFetchAnnouncements } export default apiService diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js @@ -2,10 +2,11 @@ import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.servic import timelineFetcher from '../timeline_fetcher/timeline_fetcher.service.js' import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js' import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service' +import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js' const backendInteractorService = credentials => ({ - startFetchingTimeline ({ timeline, store, userId = false, tag }) { - return timelineFetcher.startFetching({ timeline, store, credentials, userId, tag }) + startFetchingTimeline ({ timeline, store, userId = false, listId = false, tag }) { + return timelineFetcher.startFetching({ timeline, store, credentials, userId, listId, tag }) }, fetchTimeline (args) { @@ -24,6 +25,10 @@ const backendInteractorService = credentials => ({ return followRequestFetcher.startFetching({ store, credentials }) }, + startFetchingLists ({ store }) { + return listsFetcher.startFetching({ store, credentials }) + }, + startUserSocket ({ store }) { const serv = store.rootState.instance.server.replace('http', 'ws') const url = serv + getMastodonSocketURI({ credentials, stream: 'user' }) diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js @@ -43,11 +43,13 @@ export const parseUser = (data) => { // case for users in "mentions" property for statuses in MastoAPI const mastoShort = masto && !Object.prototype.hasOwnProperty.call(data, 'avatar') + output.inLists = null output.id = String(data.id) output._original = data // used for server-side settings if (masto) { output.screen_name = data.acct + output.fqn = data.fqn output.statusnet_profile_url = data.url // There's nothing else to get @@ -90,6 +92,9 @@ export const parseUser = (data) => { output.bot = data.bot if (data.pleroma) { + if (data.pleroma.settings_store) { + output.storage = data.pleroma.settings_store['pleroma-fe'] + } const relationship = data.pleroma.relationship output.background_image = data.pleroma.background_image @@ -121,6 +126,34 @@ export const parseUser = (data) => { } output.birthday = data.pleroma.birthday + + if (data.pleroma.privileges) { + output.privileges = data.pleroma.privileges + } else if (data.pleroma.is_admin) { + output.privileges = [ + 'users_read', + 'users_manage_invites', + 'users_manage_activation_state', + 'users_manage_tags', + 'users_manage_credentials', + 'users_delete', + 'messages_read', + 'messages_delete', + 'instances_delete', + 'reports_manage_reports', + 'moderation_log_read', + 'announcements_manage_announcements', + 'emoji_manage_emoji', + 'statistics_read' + ] + } else if (data.pleroma.is_moderator) { + output.privileges = [ + 'messages_delete', + 'reports_manage_reports' + ] + } else { + output.privileges = [] + } } if (data.source) { @@ -214,12 +247,14 @@ export const parseUser = (data) => { output.screen_name_ui = output.screen_name if (output.screen_name && output.screen_name.includes('@')) { const parts = output.screen_name.split('@') - let unicodeDomain = punycode.toUnicode(parts[1]) + const unicodeDomain = punycode.toUnicode(parts[1]) if (unicodeDomain !== parts[1]) { // Add some identifier so users can potentially spot spoofing attempts: // lain.com and xn--lin-6cd.com would appear identical otherwise. - unicodeDomain = '🌏' + unicodeDomain + output.screen_name_ui_contains_non_ascii = true output.screen_name_ui = [parts[0], unicodeDomain].join('@') + } else { + output.screen_name_ui_contains_non_ascii = false } } @@ -247,6 +282,16 @@ export const parseAttachment = (data) => { return output } +export const parseSource = (data) => { + const output = {} + + output.text = data.text + output.spoiler_text = data.spoiler_text + output.content_type = data.content_type + + return output +} + export const parseStatus = (data) => { const output = {} const masto = Object.prototype.hasOwnProperty.call(data, 'account') @@ -268,6 +313,8 @@ export const parseStatus = (data) => { output.tags = data.tags + output.edited_at = data.edited_at + if (data.pleroma) { const { pleroma } = data output.text = pleroma.content ? data.pleroma.content['text/plain'] : data.content @@ -369,6 +416,10 @@ export const parseStatus = (data) => { output.favoritedBy = [] output.rebloggedBy = [] + if (Object.prototype.hasOwnProperty.call(data, 'originalStatus')) { + Object.assign(output, data.originalStatus) + } + return output } @@ -390,6 +441,13 @@ export const parseNotification = (data) => { : parseUser(data.target) output.from_profile = parseUser(data.account) output.emoji = data.emoji + if (data.report) { + output.report = data.report + output.report.content = data.report.content + output.report.acct = parseUser(data.report.account) + output.report.actor = parseUser(data.report.actor) + output.report.statuses = data.report.statuses.map(parseStatus) + } } else { const parsedNotice = parseStatus(data.notice) output.type = data.ntype diff --git a/src/services/html_converter/utility.service.js b/src/services/html_converter/utility.service.js @@ -16,7 +16,7 @@ export const getTagName = (tag) => { * @return {Object} - map of attributes key = attribute name, value = attribute value * attributes without values represented as boolean true */ -export const getAttrs = tag => { +export const getAttrs = (tag, filter) => { const innertag = tag .substring(1, tag.length - 1) .replace(new RegExp('^' + getTagName(tag)), '') @@ -28,7 +28,15 @@ export const getAttrs = tag => { if (!v) return [k, true] return [k, v.substring(1, v.length - 1)] }) - return Object.fromEntries(attrs) + const defaultFilter = ([k, v]) => { + const attrKey = k.toLowerCase() + if (attrKey === 'style') return false + if (attrKey === 'class') { + return v === 'greentext' || v === 'cyantext' + } + return true + } + return Object.fromEntries(attrs.filter(filter || defaultFilter)) } /** diff --git a/src/services/lists_fetcher/lists_fetcher.service.js b/src/services/lists_fetcher/lists_fetcher.service.js @@ -0,0 +1,22 @@ +import apiService from '../api/api.service.js' +import { promiseInterval } from '../promise_interval/promise_interval.js' + +const fetchAndUpdate = ({ store, credentials }) => { + return apiService.fetchLists({ credentials }) + .then(lists => { + store.commit('setLists', lists) + }, () => {}) + .catch(() => {}) +} + +const startFetching = ({ credentials, store }) => { + const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store }) + boundFetchAndUpdate() + return promiseInterval(boundFetchAndUpdate, 240000) +} + +const listsFetcher = { + startFetching +} + +export default listsFetcher diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js @@ -15,6 +15,7 @@ export const visibleTypes = store => { rootState.config.notificationVisibility.followRequest && 'follow_request', rootState.config.notificationVisibility.moves && 'move', rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction', + rootState.config.notificationVisibility.reports && 'pleroma:report', rootState.config.notificationVisibility.polls && 'poll' ].filter(_ => _)) } @@ -99,6 +100,9 @@ export const prepareNotificationObject = (notification, i18n) => { case 'follow_request': i18nString = 'follow_request' break + case 'pleroma:report': + i18nString = 'submitted_report' + break case 'poll': i18nString = 'poll_ended' break diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -1,6 +1,18 @@ import apiService from '../api/api.service.js' import { promiseInterval } from '../promise_interval/promise_interval.js' +// For using include_types when fetching notifications. +// Note: chat_mention excluded as pleroma-fe polls them separately +const mastoApiNotificationTypes = [ + 'mention', + 'favourite', + 'reblog', + 'follow', + 'move', + 'pleroma:emoji_reaction', + 'pleroma:report' +] + const update = ({ store, notifications, older }) => { store.dispatch('addNewNotifications', { notifications, older }) } @@ -12,6 +24,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => { const timelineData = rootState.statuses.notifications const hideMutedPosts = getters.mergedConfig.hideMutedPosts + args.includeTypes = mastoApiNotificationTypes args.withMuted = !hideMutedPosts args.timeline = 'notifications' @@ -63,6 +76,7 @@ const fetchNotifications = ({ store, args, older }) => { messageArgs: [error.message], timeout: 5000 }) + console.error(error) }) } diff --git a/src/services/push/push.js b/src/services/push/push.js @@ -1,4 +1,4 @@ -import runtime from 'serviceworker-webpack-plugin/lib/runtime' +import runtime from 'serviceworker-webpack5-plugin/lib/runtime' function urlBase64ToUint8Array (base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4) diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js @@ -47,6 +47,47 @@ const postStatus = ({ }) } +const editStatus = ({ + store, + statusId, + status, + spoilerText, + sensitive, + poll, + media = [], + contentType = 'text/plain' +}) => { + const mediaIds = map(media, 'id') + + return apiService.editStatus({ + id: statusId, + credentials: store.state.users.currentUser.credentials, + status, + spoilerText, + sensitive, + poll, + mediaIds, + contentType + }) + .then((data) => { + if (!data.error) { + store.dispatch('addNewStatuses', { + statuses: [data], + timeline: 'friends', + showImmediately: true, + noIdUpdate: true // To prevent missing notices on next pull. + }) + } + return data + }) + .catch((err) => { + console.error('Error editing status', err) + return { + error: err.message + } + }) +} + const uploadMedia = ({ store, formData }) => { const credentials = store.state.users.currentUser.credentials return apiService.uploadMedia({ credentials, formData }) @@ -59,6 +100,7 @@ const setMediaDescription = ({ store, id, description }) => { const statusPosterService = { postStatus, + editStatus, uploadMedia, setMediaDescription } diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js @@ -1,6 +1,7 @@ import { convert } from 'chromatism' import { rgb2hex, hex2rgb, rgba2css, getCssColor, relativeLuminance } from '../color_convert/color_convert.js' import { getColors, computeDynamicColor, getOpacitySlot } from '../theme_data/theme_data.service.js' +import { defaultState } from '../../modules/config.js' export const applyTheme = (input) => { const { rules } = generatePreset(input) @@ -20,6 +21,36 @@ export const applyTheme = (input) => { body.classList.remove('hidden') } +const configColumns = ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth }) => + ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth }) + +const defaultConfigColumns = configColumns(defaultState) + +export const applyConfig = (config) => { + const columns = configColumns(config) + + if (columns === defaultConfigColumns) { + return + } + + const head = document.head + const body = document.body + body.classList.add('hidden') + + const rules = Object + .entries(columns) + .filter(([k, v]) => v) + .map(([k, v]) => `--${k}: ${v}`).join(';') + + const styleEl = document.createElement('style') + head.appendChild(styleEl) + const styleSheet = styleEl.sheet + + styleSheet.toString() + styleSheet.insertRule(`:root { ${rules} }`, 'index-max') + body.classList.remove('hidden') +} + export const getCssShadow = (input, usesDropShadow) => { if (input.length === 0) { return 'none' diff --git a/src/services/theme_data/pleromafe.js b/src/services/theme_data/pleromafe.js @@ -709,6 +709,14 @@ export const SLOT_INHERITANCE = { textColor: 'bw' }, + badgeNeutral: '--cGreen', + badgeNeutralText: { + depends: ['text', 'badgeNeutral'], + layer: 'badge', + variant: 'badgeNeutral', + textColor: 'bw' + }, + chatBg: { depends: ['bg'] }, diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -3,12 +3,13 @@ import { camelCase } from 'lodash' import apiService from '../api/api.service.js' import { promiseInterval } from '../promise_interval/promise_interval.js' -const update = ({ store, statuses, timeline, showImmediately, userId, pagination }) => { +const update = ({ store, statuses, timeline, showImmediately, userId, listId, pagination }) => { const ccTimeline = camelCase(timeline) store.dispatch('addNewStatuses', { timeline: ccTimeline, userId, + listId, statuses, showImmediately, pagination @@ -22,6 +23,7 @@ const fetchAndUpdate = ({ older = false, showImmediately = false, userId = false, + listId = false, tag = false, until, since @@ -44,6 +46,7 @@ const fetchAndUpdate = ({ } args.userId = userId + args.listId = listId args.tag = tag args.withMuted = !hideMutedPosts if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) { @@ -62,7 +65,7 @@ const fetchAndUpdate = ({ if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) { store.dispatch('queueFlush', { timeline, id: timelineData.maxId }) } - update({ store, statuses, timeline, showImmediately, userId, pagination }) + update({ store, statuses, timeline, showImmediately, userId, listId, pagination }) return { statuses, pagination } }) .catch((error) => { @@ -75,14 +78,15 @@ const fetchAndUpdate = ({ }) } -const startFetching = ({ timeline = 'friends', credentials, store, userId = false, tag = false }) => { +const startFetching = ({ timeline = 'friends', credentials, store, userId = false, listId = false, tag = false }) => { const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] const showImmediately = timelineData.visibleStatuses.length === 0 timelineData.userId = userId - fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, tag }) + timelineData.listId = listId + fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, listId, tag }) const boundFetchAndUpdate = () => - fetchAndUpdate({ timeline, credentials, store, userId, tag }) + fetchAndUpdate({ timeline, credentials, store, userId, listId, tag }) return promiseInterval(boundFetchAndUpdate, 10000) } const timelineFetcher = { diff --git a/static/config.json b/static/config.json @@ -14,6 +14,7 @@ "logoMask": true, "logoLeft": false, "minimalScopesMode": false, + "disableUpdateNotification": false, "nsfwCensorImage": "", "postContentType": "text/plain", "redirectRootLogin": "/main/friends", diff --git a/static/emoji.json b/static/emoji.json @@ -1,1431 +0,0 @@ -{ - "100": "💯", - "1234": "🔢", - "1st_place_medal": "🥇", - "2nd_place_medal": "🥈", - "3rd_place_medal": "🥉", - "8ball": "🎱", - "a_button_blood_type": "🅰", - "ab": "🆎", - "abacus": "🧮", - "abc": "🔤", - "abcd": "🔡", - "accept": "🉑", - "adhesive_bandage": "🩹", - "admission_tickets": "🎟", - "adult": "🧑", - "aerial_tramway": "🚡", - "airplane": "✈", - "airplane_arriving": "🛬", - "airplane_departure": "🛫", - "alarm_clock": "⏰", - "alembic": "⚗️", - "alien": "👽", - "ambulance": "🚑", - "amphora": "🏺", - "anchor": "⚓", - "angel": "👼", - "anger": "💢", - "anger_right": "🗯", - "angry": "😠", - "anguished": "😧", - "ant": "🐜", - "apple": "🍎", - "aquarius": "♒", - "aries": "♈", - "arrow_backward": "◀️", - "arrow_double_down": "⏬", - "arrow_double_up": "⏫", - "arrow_down": "⬇️", - "arrow_down_small": "🔽", - "arrow_forward": "▶️", - "arrow_heading_down": "⤵️", - "arrow_heading_up": "⤴️", - "arrow_left": "⬅️", - "arrow_lower_left": "↙️", - "arrow_lower_right": "↘️", - "arrow_right": "➡", - "arrow_right_hook": "↪️", - "arrow_up": "⬆️", - "arrow_up_down": "↕", - "arrow_up_small": "🔼", - "arrow_upper_left": "↖", - "arrow_upper_right": "↗️", - "arrows_clockwise": "🔃", - "arrows_counterclockwise": "🔄", - "art": "🎨", - "articulated_lorry": "🚛", - "artist_palette": "🎨", - "asterisk": "*⃣", - "astonished": "😲", - "athletic_shoe": "👟", - "atm": "🏧", - "atom": "⚛", - "atom_symbol": "⚛️", - "auto_rickshaw": "🛺", - "automobile": "🚗", - "avocado": "🥑", - "axe": "🪓", - "b_button_blood_type": "🅱", - "baby": "👶", - "baby_bottle": "🍼", - "baby_chick": "🐤", - "baby_symbol": "🚼", - "back": "🔙", - "bacon": "🥓", - "badger": "🦡", - "badminton": "🏸", - "bagel": "🥯", - "baggage_claim": "🛄", - "baguette_bread": "🥖", - "balance_scale": "⚖️", - "bald": "🦲", - "ballet_shoes": "🩰", - "balloon": "🎈", - "ballot_box": "🗳", - "ballot_box_with_check": "☑️", - "bamboo": "🎍", - "banana": "🍌", - "bangbang": "‼️", - "banjo": "🪕", - "bank": "🏦", - "bar_chart": "📊", - "barber": "💈", - "baseball": "⚾", - "basket": "🧺", - "basketball": "🏀", - "basketballer": "⛹", - "bat": "🦇", - "bath": "🛀", - "bathtub": "🛁", - "battery": "🔋", - "beach_umbrella": "⛱", - "beach_with_umbrella": "🏖", - "bear": "🐻", - "beard": "🧔", - "bearded_person": "🧔", - "bed": "🛏", - "bee": "🐝", - "beer": "🍺", - "beers": "🍻", - "beetle": "🐞", - "beginner": "🔰", - "bell": "🔔", - "bellhop_bell": "🛎", - "bento": "🍱", - "beverage_box": "🧃", - "bicyclist": "🚴", - "bike": "🚲", - "bikini": "👙", - "billed_cap": "🧢", - "biohazard": "☣️", - "bird": "🐦", - "birthday": "🎂", - "black_circle": "⚫", - "black_heart": "🖤", - "black_joker": "🃏", - "black_large_square": "⬛", - "black_medium_small_square": "◾", - "black_medium_square": "◼", - "black_nib": "✒️", - "black_small_square": "▪", - "black_square_button": "🔲", - "blond_haired_person": "👱", - "blossom": "🌼", - "blowfish": "🐡", - "blue_book": "📘", - "blue_car": "🚙", - "blue_circle": "🔵", - "blue_heart": "💙", - "blue_square": "🟦", - "blush": "😊", - "boar": "🐗", - "bomb": "💣", - "bone": "🦴", - "book": "📖", - "bookmark": "🔖", - "bookmark_tabs": "📑", - "books": "📚", - "boom": "💥", - "boot": "👢", - "bouquet": "💐", - "bow": "🙇", - "bow_and_arrow": "🏹", - "bowl_with_spoon": "🥣", - "bowling": "🎳", - "boxing_glove": "🥊", - "boy": "👦", - "brain": "🧠", - "bread": "🍞", - "breast_feeding": "🤱", - "breastfeeding": "🤱", - "brick": "🧱", - "bride_with_veil": "👰", - "bridge_at_night": "🌉", - "briefcase": "💼", - "briefs": "🩲", - "broccoli": "🥦", - "broken_heart": "💔", - "broom": "🧹", - "brown_circle": "🟤", - "brown_heart": "🤎", - "bug": "🐛", - "building_construction": "🏗", - "bulb": "💡", - "bullettrain_front": "🚅", - "bullettrain_side": "🚄", - "burrito": "🌯", - "bus": "🚌", - "busstop": "🚏", - "bust_in_silhouette": "👤", - "busts_in_silhouette": "👥", - "butter": "🧈", - "butterfly": "🦋", - "cactus": "🌵", - "cake": "🍰", - "calendar": "📆", - "call_me": "🤙", - "call_me_hand": "🤙", - "calling": "📲", - "camel": "🐫", - "camera": "📷", - "camera_with_flash": "📸", - "camping": "🏕", - "cancer": "♋", - "candle": "🕯", - "candy": "🍬", - "canned_food": "🥫", - "canoe": "🛶", - "capital_abcd": "🔠", - "capricorn": "♑", - "card_file_box": "🗃", - "card_index": "📇", - "card_index_dividers": "🗂", - "carousel_horse": "🎠", - "carrot": "🥕", - "cat": "🐱", - "cat2": "🐈", - "cd": "💿", - "chains": "⛓️", - "chair": "🪑", - "champagne": "🍾", - "champagne_glass": "🥂", - "chart": "💹", - "chart_with_downwards_trend": "📉", - "chart_with_upwards_trend": "📈", - "check_box_with_check": "☑", - "check_mark": "✔", - "checkered_flag": "🏁", - "cheese": "🧀", - "cheese_wedge": "🧀", - "cherries": "🍒", - "cherry_blossom": "🌸", - "chess_pawn": "♟", - "chestnut": "🌰", - "chicken": "🐔", - "child": "🧒", - "children_crossing": "🚸", - "chipmunk": "🐿", - "chocolate_bar": "🍫", - "chopsticks": "🥢", - "christmas_tree": "🎄", - "church": "⛪", - "cinema": "🎦", - "circled_m": "Ⓜ", - "circus_tent": "🎪", - "city_dusk": "🌆", - "city_sunset": "🌇", - "cityscape": "🏙", - "cityscape_at_dusk": "🌆", - "cl": "🆑", - "clap": "👏", - "clapper": "🎬", - "classical_building": "🏛", - "clinking_glasses": "🥂", - "clipboard": "📋", - "clock1": "🕐", - "clock10": "🕙", - "clock1030": "🕥", - "clock11": "🕚", - "clock1130": "🕦", - "clock12": "🕛", - "clock1230": "🕧", - "clock130": "🕜", - "clock2": "🕑", - "clock230": "🕝", - "clock3": "🕒", - "clock330": "🕞", - "clock4": "🕓", - "clock430": "🕟", - "clock5": "🕔", - "clock530": "🕠", - "clock6": "🕕", - "clock630": "🕡", - "clock7": "🕖", - "clock730": "🕢", - "clock8": "🕗", - "clock830": "🕣", - "clock9": "🕘", - "clock930": "🕤", - "closed_book": "📕", - "closed_lock_with_key": "🔐", - "closed_umbrella": "🌂", - "cloud": "☁️", - "cloud_with_lightning": "🌩", - "cloud_with_lightning_and_rain": "⛈️", - "cloud_with_rain": "🌧", - "cloud_with_snow": "🌨", - "clown": "🤡", - "clown_face": "🤡", - "club_suit": "♣️", - "clubs": "♣", - "coat": "🧥", - "cocktail": "🍸", - "coconut": "🥥", - "coffee": "☕", - "coffin": "⚰️", - "cold_face": "🥶", - "cold_sweat": "😰", - "comet": "☄️", - "compass": "🧭", - "compression": "🗜", - "computer": "💻", - "computer_mouse": "🖱", - "confetti_ball": "🎊", - "confounded": "😖", - "confused": "😕", - "congratulations": "㊗", - "construction": "🚧", - "construction_worker": "👷", - "control_knobs": "🎛", - "convenience_store": "🏪", - "cookie": "🍪", - "cooking": "🍳", - "cool": "🆒", - "cop": "👮", - "copyright": "©", - "corn": "🌽", - "couch_and_lamp": "🛋", - "couple": "👫", - "couple_with_heart": "💑", - "couplekiss": "💏", - "cow": "🐮", - "cow2": "🐄", - "cowboy": "🤠", - "cowboy_hat_face": "🤠", - "crab": "🦀", - "crayon": "🖍", - "crazy_face": "🤪", - "credit_card": "💳", - "crescent_moon": "🌙", - "cricket": "🦗", - "cricket_game": "🏏", - "crocodile": "🐊", - "croissant": "🥐", - "cross": "✝️", - "crossed_fingers": "🤞", - "crossed_flags": "🎌", - "crossed_swords": "⚔️", - "crown": "👑", - "cry": "😢", - "crying_cat_face": "😿", - "crystal_ball": "🔮", - "cucumber": "🥒", - "cup_with_straw": "🥤", - "cupcake": "🧁", - "cupid": "💘", - "curling_stone": "🥌", - "curly_hair": "🦱", - "curly_loop": "➰", - "currency_exchange": "💱", - "curry": "🍛", - "custard": "🍮", - "customs": "🛃", - "cut_of_meat": "🥩", - "cyclone": "🌀", - "dagger": "🗡", - "dancer": "💃", - "dancers": "👯", - "dango": "🍡", - "dark_skin_tone": "🏿", - "dark_sunglasses": "🕶", - "dart": "🎯", - "dash": "💨", - "date": "📅", - "deaf_person": "🧏", - "deciduous_tree": "🌳", - "deer": "🦌", - "department_store": "🏬", - "derelict_house": "🏚", - "desert": "🏜", - "desert_island": "🏝", - "desktop_computer": "🖥", - "detective": "🕵", - "diamond_shape_with_a_dot_inside": "💠", - "diamond_suit": "♦️", - "diamonds": "♦", - "disappointed": "😞", - "disappointed_relieved": "😥", - "diving_mask": "🤿", - "diya_lamp": "🪔", - "dizzy": "💫", - "dizzy_face": "😵", - "dna": "🧬", - "do_not_litter": "🚯", - "dog": "🐶", - "dog2": "🐕", - "dollar": "💵", - "dolls": "🎎", - "dolphin": "🐬", - "door": "🚪", - "double_exclamation_mark": "‼", - "doughnut": "🍩", - "dove": "🕊", - "down_arrow": "⬇", - "downleft_arrow": "↙", - "downright_arrow": "↘", - "dragon": "🐉", - "dragon_face": "🐲", - "dress": "👗", - "dromedary_camel": "🐪", - "drooling_face": "🤤", - "drop_of_blood": "🩸", - "droplet": "💧", - "drum": "🥁", - "duck": "🦆", - "dumpling": "🥟", - "dvd": "📀", - "e-mail": "📧", - "eagle": "🦅", - "ear": "👂", - "ear_of_rice": "🌾", - "ear_with_hearing_aid": "🦻", - "earth_africa": "🌍", - "earth_americas": "🌎", - "earth_asia": "🌏", - "egg": "🥚", - "eggplant": "🍆", - "eight": "8⃣", - "eight_pointed_black_star": "✴️", - "eight_spoked_asterisk": "✳️", - "eightpointed_star": "✴", - "eightspoked_asterisk": "✳", - "eject_button": "⏏", - "electric_plug": "🔌", - "elephant": "🐘", - "elf": "🧝", - "end": "🔚", - "envelope": "✉", - "envelope_with_arrow": "📩", - "euro": "💶", - "european_castle": "🏰", - "european_post_office": "🏤", - "evergreen_tree": "🌲", - "exclamation": "❗", - "exclamation_question_mark": "⁉", - "exploding_head": "🤯", - "expressionless": "😑", - "eye": "👁", - "eyeglasses": "👓", - "eyes": "👀", - "face_vomiting": "🤮", - "face_with_hand_over_mouth": "🤭", - "face_with_headbandage": "🤕", - "face_with_monocle": "🧐", - "face_with_raised_eyebrow": "🤨", - "face_with_symbols_on_mouth": "🤬", - "face_with_symbols_over_mouth": "🤬", - "face_with_thermometer": "🤒", - "factory": "🏭", - "fairy": "🧚", - "falafel": "🧆", - "fallen_leaf": "🍂", - "family": "👪", - "fast_forward": "⏩", - "fax": "📠", - "fearful": "😨", - "feet": "🐾", - "female_sign": "♀", - "ferris_wheel": "🎡", - "ferry": "⛴️", - "field_hockey": "🏑", - "file_cabinet": "🗄", - "file_folder": "📁", - "film_frames": "🎞", - "film_projector": "📽", - "fingers_crossed": "🤞", - "fire": "🔥", - "fire_engine": "🚒", - "fire_extinguisher": "🧯", - "firecracker": "🧨", - "fireworks": "🎆", - "first_place": "🥇", - "first_quarter_moon": "🌓", - "first_quarter_moon_with_face": "🌛", - "fish": "🐟", - "fish_cake": "🍥", - "fishing_pole_and_fish": "🎣", - "fist": "✊", - "five": "5⃣", - "flag_black": "🏴", - "flag_white": "🏳", - "flags": "🎏", - "flamingo": "🦩", - "flashlight": "🔦", - "flat_shoe": "🥿", - "fleur-de-lis": "⚜", - "fleurde-lis": "⚜️", - "floppy_disk": "💾", - "flower_playing_cards": "🎴", - "flushed": "😳", - "flying_disc": "🥏", - "flying_saucer": "🛸", - "fog": "🌫", - "foggy": "🌁", - "foot": "🦶", - "football": "🏈", - "footprints": "👣", - "fork_and_knife": "🍴", - "fork_and_knife_with_plate": "🍽", - "fortune_cookie": "🥠", - "fountain": "⛲", - "fountain_pen": "🖋", - "four": "4⃣", - "four_leaf_clover": "🍀", - "fox": "🦊", - "framed_picture": "🖼", - "free": "🆓", - "french_bread": "🥖", - "fried_shrimp": "🍤", - "fries": "🍟", - "frog": "🐸", - "frowning": "😦", - "frowning_face": "☹️", - "fuelpump": "⛽", - "full_moon": "🌕", - "full_moon_with_face": "🌝", - "funeral_urn": "⚱️", - "game_die": "🎲", - "garlic": "🧄", - "gear": "⚙️", - "gem": "💎", - "gemini": "♊", - "genie": "🧞", - "ghost": "👻", - "gift": "🎁", - "gift_heart": "💝", - "giraffe": "🦒", - "girl": "👧", - "glass_of_milk": "🥛", - "globe_with_meridians": "🌐", - "gloves": "🧤", - "goal": "🥅", - "goal_net": "🥅", - "goat": "🐐", - "goggles": "🥽", - "golf": "⛳", - "golfer": "🏌", - "gorilla": "🦍", - "grapes": "🍇", - "green_apple": "🍏", - "green_book": "📗", - "green_circle": "🟢", - "green_heart": "💚", - "green_salad": "🥗", - "green_square": "🟩", - "grey_exclamation": "❕", - "grey_question": "❔", - "grimacing": "😬", - "grin": "😁", - "grinning": "😀", - "guard": "💂", - "guardsman": "💂", - "guide_dog": "🦮", - "guitar": "🎸", - "gun": "🔫", - "haircut": "💇", - "hamburger": "🍔", - "hammer": "🔨", - "hammer_and_pick": "⚒️", - "hammer_and_wrench": "🛠", - "hamster": "🐹", - "hand_with_fingers_splayed": "🖐", - "handbag": "👜", - "handshake": "🤝", - "hash": "#⃣", - "hatched_chick": "🐥", - "hatching_chick": "🐣", - "head_bandage": "🤕", - "headphones": "🎧", - "hear_no_evil": "🙉", - "heart": "❤️", - "heart_decoration": "💟", - "heart_exclamation": "❣", - "heart_eyes": "😍", - "heart_eyes_cat": "😻", - "heart_suit": "♥️", - "heartbeat": "💓", - "heartpulse": "💗", - "hearts": "♥", - "heavy_check_mark": "✔️", - "heavy_division_sign": "➗", - "heavy_dollar_sign": "💲", - "heavy_minus_sign": "➖", - "heavy_multiplication_x": "✖️", - "heavy_plus_sign": "➕", - "hedgehog": "🦔", - "helicopter": "🚁", - "herb": "🌿", - "hibiscus": "🌺", - "high_brightness": "🔆", - "high_heel": "👠", - "hiking_boot": "🥾", - "hindu_temple": "🛕", - "hippopotamus": "🦛", - "hockey": "🏒", - "hole": "🕳", - "honey_pot": "🍯", - "horse": "🐴", - "horse_racing": "🏇", - "hospital": "🏥", - "hot_face": "🥵", - "hot_pepper": "🌶", - "hot_springs": "♨", - "hotdog": "🌭", - "hotel": "🏨", - "hotsprings": "♨️", - "hourglass": "⌛", - "hourglass_flowing_sand": "⏳", - "house": "🏠", - "house_with_garden": "🏡", - "houses": "🏘", - "hugging": "🤗", - "hundred_points": "💯", - "hushed": "😯", - "ice": "🧊", - "ice_cream": "🍨", - "ice_hockey": "🏒", - "ice_skate": "⛸️", - "icecream": "🍦", - "id": "🆔", - "ideograph_advantage": "🉐", - "imp": "👿", - "inbox_tray": "📥", - "incoming_envelope": "📨", - "index_pointing_up": "☝", - "infinity": "♾", - "information": "ℹ️", - "information_desk_person": "💁", - "information_source": "ℹ", - "innocent": "😇", - "input_numbers": "🔢", - "interrobang": "⁉️", - "iphone": "📱", - "izakaya_lantern": "🏮", - "jack_o_lantern": "🎃", - "japan": "🗾", - "japanese_castle": "🏯", - "japanese_congratulations_button": "㊗️", - "japanese_free_of_charge_button": "🈚", - "japanese_goblin": "👺", - "japanese_ogre": "👹", - "japanese_reserved_button": "🈯", - "japanese_secret_button": "㊙️", - "japanese_service_charge_button": "🈂", - "jeans": "👖", - "joy": "😂", - "joy_cat": "😹", - "joystick": "🕹", - "kaaba": "🕋", - "kangaroo": "🦘", - "key": "🔑", - "keyboard": "⌨️", - "keycap_ten": "🔟", - "kick_scooter": "🛴", - "kimono": "👘", - "kiss": "💋", - "kissing": "😗", - "kissing_cat": "😽", - "kissing_closed_eyes": "😚", - "kissing_heart": "😘", - "kissing_smiling_eyes": "😙", - "kitchen_knife": "🔪", - "kite": "🪁", - "kiwi": "🥝", - "kiwi_fruit": "🥝", - "knife": "🔪", - "koala": "🐨", - "koko": "🈁", - "lab_coat": "🥼", - "label": "🏷", - "lacrosse": "🥍", - "large_blue_diamond": "🔷", - "large_orange_diamond": "🔶", - "last_quarter_moon": "🌗", - "last_quarter_moon_with_face": "🌜", - "last_track_button": "⏮️", - "latin_cross": "✝", - "laughing": "😆", - "leafy_green": "🥬", - "leaves": "🍃", - "ledger": "📒", - "left_arrow": "⬅", - "left_arrow_curving_right": "↪", - "left_facing_fist": "🤛", - "left_luggage": "🛅", - "left_right_arrow": "↔", - "leftfacing_fist": "🤛", - "leftright_arrow": "↔️", - "leftwards_arrow_with_hook": "↩️", - "leg": "🦵", - "lemon": "🍋", - "leo": "♌", - "leopard": "🐆", - "level_slider": "🎚", - "libra": "♎", - "light_rail": "🚈", - "light_skin_tone": "🏻", - "link": "🔗", - "linked_paperclips": "🖇", - "lion_face": "🦁", - "lips": "👄", - "lipstick": "💄", - "lizard": "🦎", - "llama": "🦙", - "lobster": "🦞", - "lock": "🔒", - "lock_with_ink_pen": "🔏", - "lollipop": "🍭", - "loop": "➿", - "lotion_bottle": "🧴", - "loud_sound": "🔊", - "loudspeaker": "📢", - "love_hotel": "🏩", - "love_letter": "💌", - "love_you_gesture": "🤟", - "loveyou_gesture": "🤟", - "low_brightness": "🔅", - "luggage": "🧳", - "lying_face": "🤥", - "m": "Ⓜ️", - "mag": "🔍", - "mag_right": "🔎", - "mage": "🧙", - "magnet": "🧲", - "mahjong": "🀄", - "mailbox": "📫", - "mailbox_closed": "📪", - "mailbox_with_mail": "📬", - "mailbox_with_no_mail": "📭", - "male_sign": "♂", - "man": "👨", - "man_dancing": "🕺", - "man_in_suit": "🕴", - "man_in_tuxedo": "🤵", - "man_with_chinese_cap": "👲", - "man_with_gua_pi_mao": "👲", - "man_with_turban": "👳", - "mango": "🥭", - "mans_shoe": "👞", - "mantelpiece_clock": "🕰", - "manual_wheelchair": "🦽", - "maple_leaf": "🍁", - "martial_arts_uniform": "🥋", - "mask": "😷", - "massage": "💆", - "mate": "🧉", - "meat_on_bone": "🍖", - "mechanical_arm": "🦾", - "mechanical_leg": "🦿", - "medal": "🏅", - "medical_symbol": "⚕", - "medium_skin_tone": "🏽", - "mediumdark_skin_tone": "🏾", - "mediumlight_skin_tone": "🏼", - "mega": "📣", - "melon": "🍈", - "memo": "📝", - "menorah": "🕎", - "mens": "🚹", - "merperson": "🧜", - "metal": "🤘", - "metro": "🚇", - "microbe": "🦠", - "microphone": "🎤", - "microscope": "🔬", - "middle_finger": "🖕", - "military_medal": "🎖", - "milk": "🥛", - "milky_way": "🌌", - "minibus": "🚐", - "minidisc": "💽", - "mobile_phone_off": "📴", - "money_mouth": "🤑", - "money_with_wings": "💸", - "moneybag": "💰", - "moneymouth_face": "🤑", - "monkey": "🐒", - "monkey_face": "🐵", - "monorail": "🚝", - "moon_cake": "🥮", - "mortar_board": "🎓", - "mosque": "🕌", - "mosquito": "🦟", - "motor_boat": "🛥", - "motor_scooter": "🛵", - "motorcycle": "🏍", - "motorized_wheelchair": "🦼", - "motorway": "🛣", - "mount_fuji": "🗻", - "mountain": "⛰️", - "mountain_bicyclist": "🚵", - "mountain_cableway": "🚠", - "mountain_railway": "🚞", - "mouse": "🐭", - "mouse2": "🐁", - "movie_camera": "🎥", - "moyai": "🗿", - "mrs_claus": "🤶", - "multiplication_sign": "✖", - "muscle": "💪", - "mushroom": "🍄", - "musical_keyboard": "🎹", - "musical_note": "🎵", - "musical_score": "🎼", - "mute": "🔇", - "nail_care": "💅", - "name_badge": "📛", - "national_park": "🏞", - "nauseated_face": "🤢", - "nazar_amulet": "🧿", - "necktie": "👔", - "negative_squared_cross_mark": "❎", - "nerd": "🤓", - "neutral_face": "😐", - "new": "🆕", - "new_moon": "🌑", - "new_moon_with_face": "🌚", - "newspaper": "📰", - "next_track_button": "⏭️", - "ng": "🆖", - "night_with_stars": "🌃", - "nine": "9⃣", - "no_bell": "🔕", - "no_bicycles": "🚳", - "no_entry": "⛔", - "no_entry_sign": "🚫", - "no_good": "🙅", - "no_mobile_phones": "📵", - "no_mouth": "😶", - "no_pedestrians": "🚷", - "no_smoking": "🚭", - "non-potable_water": "🚱", - "nose": "👃", - "notebook": "📓", - "notebook_with_decorative_cover": "📔", - "notes": "🎶", - "nut_and_bolt": "🔩", - "o": "⭕", - "o_button_blood_type": "🅾", - "ocean": "🌊", - "octagonal_sign": "🛑", - "octopus": "🐙", - "oden": "🍢", - "office": "🏢", - "oil_drum": "🛢", - "ok": "🆗", - "ok_hand": "👌", - "ok_woman": "🙆", - "old_key": "🗝", - "older_adult": "🧓", - "older_man": "👴", - "older_person": "🧓", - "older_woman": "👵", - "om_symbol": "🕉", - "on": "🔛", - "oncoming_automobile": "🚘", - "oncoming_bus": "🚍", - "oncoming_fist": "👊", - "oncoming_police_car": "🚔", - "oncoming_taxi": "🚖", - "one": "1⃣", - "onepiece_swimsuit": "🩱", - "onion": "🧅", - "open_file_folder": "📂", - "open_hands": "👐", - "open_mouth": "😮", - "ophiuchus": "⛎", - "orange_book": "📙", - "orange_circle": "🟠", - "orange_heart": "🧡", - "orange_square": "🟧", - "orangutan": "🦧", - "orthodox_cross": "☦️", - "otter": "🦦", - "outbox_tray": "📤", - "owl": "🦉", - "ox": "🐂", - "oyster": "🦪", - "p_button": "🅿", - "package": "📦", - "page_facing_up": "📄", - "page_with_curl": "📃", - "pager": "📟", - "paintbrush": "🖌", - "palm_tree": "🌴", - "palms_up_together": "🤲", - "pancakes": "🥞", - "panda_face": "🐼", - "paperclip": "📎", - "parachute": "🪂", - "parrot": "🦜", - "part_alternation_mark": "〽", - "partly_sunny": "⛅", - "partying_face": "🥳", - "passenger_ship": "🛳", - "passport_control": "🛂", - "pause_button": "⏸️", - "peace": "☮", - "peace_symbol": "☮️", - "peach": "🍑", - "peacock": "🦚", - "peanuts": "🥜", - "pear": "🍐", - "pen": "🖊", - "pencil": "📝", - "pencil2": "✏", - "penguin": "🐧", - "pensive": "😔", - "people_with_bunny_ears_partying": "👯", - "people_wrestling": "🤼", - "performing_arts": "🎭", - "persevere": "😣", - "person": "🧑", - "person_biking": "🚴", - "person_bouncing_ball": "⛹️", - "person_bowing": "🙇", - "person_cartwheeling": "🤸", - "person_climbing": "🧗", - "person_doing_cartwheel": "🤸", - "person_facepalming": "🤦", - "person_fencing": "🤺", - "person_frowning": "🙍", - "person_gesturing_no": "🙅", - "person_gesturing_ok": "🙆", - "person_getting_haircut": "💇", - "person_getting_massage": "💆", - "person_in_lotus_position": "🧘", - "person_in_steamy_room": "🧖", - "person_juggling": "🤹", - "person_kneeling": "🧎", - "person_mountain_biking": "🚵", - "person_playing_handball": "🤾", - "person_playing_water_polo": "🤽", - "person_pouting": "🙎", - "person_raising_hand": "🙋", - "person_rowing_boat": "🚣", - "person_running": "🏃", - "person_shrugging": "🤷", - "person_standing": "🧍", - "person_surfing": "🏄", - "person_swimming": "🏊", - "person_tipping_hand": "💁", - "person_walking": "🚶", - "person_wearing_turban": "👳", - "person_with_blond_hair": "👱", - "person_with_pouting_face": "🙎", - "petri_dish": "🧫", - "pick": "⛏️", - "pie": "🥧", - "pig": "🐷", - "pig2": "🐖", - "pig_nose": "🐽", - "pill": "💊", - "pinching_hand": "🤏", - "pineapple": "🍍", - "ping_pong": "🏓", - "pisces": "♓", - "pizza": "🍕", - "place_of_worship": "🛐", - "play_button": "▶", - "play_or_pause_button": "⏯️", - "play_pause": "⏯", - "pleading_face": "🥺", - "point_down": "👇", - "point_left": "👈", - "point_right": "👉", - "point_up": "☝️", - "point_up_2": "👆", - "police_car": "🚓", - "police_officer": "👮", - "poodle": "🐩", - "poop": "💩", - "popcorn": "🍿", - "post_office": "🏣", - "postal_horn": "📯", - "postbox": "📮", - "potable_water": "🚰", - "potato": "🥔", - "pouch": "👝", - "poultry_leg": "🍗", - "pound": "💷", - "pouting_cat": "😾", - "pray": "🙏", - "prayer_beads": "📿", - "pregnant_woman": "🤰", - "pretzel": "🥨", - "prince": "🤴", - "princess": "👸", - "printer": "🖨", - "probing_cane": "🦯", - "punch": "👊", - "purple_circle": "🟣", - "purple_heart": "💜", - "purse": "👛", - "pushpin": "📌", - "put_litter_in_its_place": "🚮", - "puzzle_piece": "🧩", - "question": "❓", - "rabbit": "🐰", - "rabbit2": "🐇", - "raccoon": "🦝", - "racehorse": "🐎", - "racing_car": "🏎", - "radio": "📻", - "radio_button": "🔘", - "radioactive": "☢️", - "rage": "😡", - "railway_car": "🚃", - "railway_track": "🛤", - "rainbow": "🌈", - "raised_back_of_hand": "🤚", - "raised_hand": "✋", - "raised_hands": "🙌", - "raising_hand": "🙋", - "ram": "🐏", - "ramen": "🍜", - "rat": "🐀", - "razor": "🪒", - "receipt": "🧾", - "record_button": "⏺️", - "recycle": "♻", - "recycling_symbol": "♻️", - "red_car": "🚗", - "red_circle": "🔴", - "red_envelope": "🧧", - "red_hair": "🦰", - "red_heart": "❤", - "red_square": "🟥", - "regional_indicator_a": "🇦", - "regional_indicator_b": "🇧", - "regional_indicator_c": "🇨", - "regional_indicator_d": "🇩", - "regional_indicator_e": "🇪", - "regional_indicator_f": "🇫", - "regional_indicator_g": "🇬", - "regional_indicator_h": "🇭", - "regional_indicator_i": "🇮", - "regional_indicator_j": "🇯", - "regional_indicator_k": "🇰", - "regional_indicator_l": "🇱", - "regional_indicator_m": "🇲", - "regional_indicator_n": "🇳", - "regional_indicator_o": "🇴", - "regional_indicator_p": "🇵", - "regional_indicator_q": "🇶", - "regional_indicator_r": "🇷", - "regional_indicator_s": "🇸", - "regional_indicator_t": "🇹", - "regional_indicator_u": "🇺", - "regional_indicator_v": "🇻", - "regional_indicator_w": "🇼", - "regional_indicator_x": "🇽", - "regional_indicator_y": "🇾", - "regional_indicator_z": "🇿", - "registered": "®", - "relieved": "😌", - "reminder_ribbon": "🎗", - "repeat": "🔁", - "repeat_one": "🔂", - "rescue_worker’s_helmet": "⛑️", - "restroom": "🚻", - "reverse_button": "◀", - "revolving_hearts": "💞", - "rewind": "⏪", - "rhino": "🦏", - "rhinoceros": "🦏", - "ribbon": "🎀", - "rice": "🍚", - "rice_ball": "🍙", - "rice_cracker": "🍘", - "rice_scene": "🎑", - "right_arrow": "➡️", - "right_arrow_curving_down": "⤵", - "right_arrow_curving_left": "↩", - "right_arrow_curving_up": "⤴", - "right_facing_fist": "🤜", - "rightfacing_fist": "🤜", - "ring": "💍", - "ringed_planet": "🪐", - "robot": "🤖", - "rocket": "🚀", - "rofl": "🤣", - "roll_of_paper": "🧻", - "rolledup_newspaper": "🗞", - "roller_coaster": "🎢", - "rolling_eyes": "🙄", - "rolling_on_the_floor_laughing": "🤣", - "rooster": "🐓", - "rose": "🌹", - "rosette": "🏵", - "rotating_light": "🚨", - "round_pushpin": "📍", - "rowboat": "🚣", - "rugby_football": "🏉", - "runner": "🏃", - "running_shirt_with_sash": "🎽", - "safety_pin": "🧷", - "safety_vest": "🦺", - "sagittarius": "♐", - "sailboat": "⛵", - "sake": "🍶", - "salad": "🥗", - "salt": "🧂", - "sandal": "👡", - "sandwich": "🥪", - "santa": "🎅", - "sari": "🥻", - "satellite": "📡", - "sauropod": "🦕", - "saxophone": "🎷", - "scales": "⚖", - "scarf": "🧣", - "school": "🏫", - "school_satchel": "🎒", - "scissors": "✂", - "scooter": "🛴", - "scorpion": "🦂", - "scorpius": "♏", - "scream": "😱", - "scream_cat": "🙀", - "scroll": "📜", - "seat": "💺", - "second_place": "🥈", - "secret": "㊙", - "see_no_evil": "🙈", - "seedling": "🌱", - "selfie": "🤳", - "seven": "7⃣", - "shallow_pan_of_food": "🥘", - "shamrock": "☘️", - "shark": "🦈", - "shaved_ice": "🍧", - "sheep": "🐑", - "shell": "🐚", - "shield": "🛡", - "shinto_shrine": "⛩️", - "ship": "🚢", - "shirt": "👕", - "shopping_bags": "🛍", - "shopping_cart": "🛒", - "shorts": "🩳", - "shower": "🚿", - "shrimp": "🦐", - "shushing_face": "🤫", - "sign_of_the_horns": "🤘", - "signal_strength": "📶", - "six": "6⃣", - "six_pointed_star": "🔯", - "skateboard": "🛹", - "ski": "🎿", - "skier": "⛷️", - "skull": "💀", - "skull_and_crossbones": "☠️", - "skull_crossbones": "☠", - "skunk": "🦨", - "sled": "🛷", - "sleeping": "😴", - "sleeping_accommodation": "🛌", - "sleepy": "😪", - "slight_frown": "🙁", - "slight_smile": "🙂", - "slightly_frowning_face": "🙁", - "slot_machine": "🎰", - "sloth": "🦥", - "small_airplane": "🛩", - "small_blue_diamond": "🔹", - "small_orange_diamond": "🔸", - "small_red_triangle": "🔺", - "small_red_triangle_down": "🔻", - "smile": "😄", - "smile_cat": "😸", - "smiley": "😃", - "smiley_cat": "😺", - "smiling": "☺️", - "smiling_face": "☺", - "smiling_face_with_hearts": "🥰", - "smiling_imp": "😈", - "smirk": "😏", - "smirk_cat": "😼", - "smoking": "🚬", - "snail": "🐌", - "snake": "🐍", - "sneezing_face": "🤧", - "snowboarder": "🏂", - "snowcapped_mountain": "🏔", - "snowflake": "❄", - "snowman": "⛄", - "soap": "🧼", - "sob": "😭", - "soccer": "⚽", - "socks": "🧦", - "softball": "🥎", - "soon": "🔜", - "sos": "🆘", - "sound": "🔉", - "space_invader": "👾", - "spade_suit": "♠️", - "spades": "♠", - "spaghetti": "🍝", - "sparkle": "❇", - "sparkler": "🎇", - "sparkles": "✨", - "sparkling_heart": "💖", - "speak_no_evil": "🙊", - "speaker": "🔈", - "speaking_head": "🗣", - "speech_balloon": "💬", - "speech_left": "🗨", - "speedboat": "🚤", - "spider": "🕷", - "spider_web": "🕸", - "spiral_calendar": "🗓", - "spiral_notepad": "🗒", - "sponge": "🧽", - "spoon": "🥄", - "squid": "🦑", - "stadium": "🏟", - "star": "⭐", - "star2": "🌟", - "star_and_crescent": "☪️", - "star_of_david": "✡", - "star_struck": "🤩", - "stars": "🌠", - "starstruck": "🤩", - "station": "🚉", - "statue_of_liberty": "🗽", - "steam_locomotive": "🚂", - "stethoscope": "🩺", - "stew": "🍲", - "stop_button": "⏹️", - "stopwatch": "⏱️", - "straight_ruler": "📏", - "strawberry": "🍓", - "stuck_out_tongue": "😛", - "stuck_out_tongue_closed_eyes": "😝", - "stuck_out_tongue_winking_eye": "😜", - "studio_microphone": "🎙", - "stuffed_flatbread": "🥙", - "sun": "☀", - "sun_behind_large_cloud": "🌥", - "sun_behind_rain_cloud": "🌦", - "sun_behind_small_cloud": "🌤", - "sun_with_face": "🌞", - "sunflower": "🌻", - "sunglasses": "😎", - "sunny": "☀️", - "sunrise": "🌅", - "sunrise_over_mountains": "🌄", - "superhero": "🦸", - "supervillain": "🦹", - "surfer": "🏄", - "sushi": "🍣", - "suspension_railway": "🚟", - "swan": "🦢", - "sweat": "😓", - "sweat_drops": "💦", - "sweat_smile": "😅", - "sweet_potato": "🍠", - "swimmer": "🏊", - "symbols": "🔣", - "synagogue": "🕍", - "syringe": "💉", - "t_rex": "🦖", - "taco": "🌮", - "tada": "🎉", - "takeout_box": "🥡", - "tanabata_tree": "🎋", - "tangerine": "🍊", - "taurus": "♉", - "taxi": "🚕", - "tea": "🍵", - "teddy_bear": "🧸", - "telephone": "☎", - "telephone_receiver": "📞", - "telescope": "🔭", - "tennis": "🎾", - "tent": "⛺", - "test_tube": "🧪", - "thermometer": "🌡", - "thermometer_face": "🤒", - "thinking": "🤔", - "third_place": "🥉", - "thought_balloon": "💭", - "thread": "🧵", - "three": "3⃣", - "thumbsdown": "👎", - "thumbsup": "👍", - "ticket": "🎫", - "tiger": "🐯", - "tiger2": "🐅", - "timer_clock": "⏲️", - "tired_face": "😫", - "tm": "™", - "toilet": "🚽", - "tokyo_tower": "🗼", - "tomato": "🍅", - "tone1": "🏻", - "tone2": "🏼", - "tone3": "🏽", - "tone4": "🏾", - "tone5": "🏿", - "tongue": "👅", - "toolbox": "🧰", - "tooth": "🦷", - "top": "🔝", - "tophat": "🎩", - "tornado": "🌪", - "track_next": "⏭", - "track_previous": "⏮", - "trackball": "🖲", - "tractor": "🚜", - "trade_mark": "™️", - "traffic_light": "🚥", - "train": "🚋", - "train2": "🚆", - "tram": "🚊", - "trex": "🦖", - "triangular_flag_on_post": "🚩", - "triangular_ruler": "📐", - "trident": "🔱", - "triumph": "😤", - "trolleybus": "🚎", - "trophy": "🏆", - "tropical_drink": "🍹", - "tropical_fish": "🐠", - "truck": "🚚", - "trumpet": "🎺", - "tulip": "🌷", - "tumbler_glass": "🥃", - "turkey": "🦃", - "turtle": "🐢", - "tv": "📺", - "twisted_rightwards_arrows": "🔀", - "two": "2⃣", - "two_hearts": "💕", - "two_men_holding_hands": "👬", - "two_women_holding_hands": "👭", - "u5272": "🈹", - "u5408": "🈴", - "u55b6": "🈺", - "u6307": "🈯", - "u6708": "🈷", - "u6709": "🈶", - "u6e80": "🈵", - "u7121": "🈚", - "u7533": "🈸", - "u7981": "🈲", - "u7a7a": "🈳", - "umbrella": "☔", - "umbrella_on_ground": "⛱️", - "unamused": "😒", - "underage": "🔞", - "unicorn": "🦄", - "unlock": "🔓", - "up": "🆙", - "up_arrow": "⬆", - "updown_arrow": "↕️", - "upleft_arrow": "↖️", - "upright_arrow": "↗", - "upside_down": "🙃", - "v": "✌️", - "vampire": "🧛", - "vertical_traffic_light": "🚦", - "vhs": "📼", - "vibration_mode": "📳", - "victory_hand": "✌", - "video_camera": "📹", - "video_game": "🎮", - "violin": "🎻", - "virgo": "♍", - "volcano": "🌋", - "volleyball": "🏐", - "vs": "🆚", - "vulcan": "🖖", - "vulcan_salute": "🖖", - "waffle": "🧇", - "walking": "🚶", - "waning_crescent_moon": "🌘", - "waning_gibbous_moon": "🌖", - "warning": "⚠", - "wastebasket": "🗑", - "watch": "⌚", - "water_buffalo": "🐃", - "watermelon": "🍉", - "wave": "👋", - "wavy_dash": "〰️", - "waxing_crescent_moon": "🌒", - "waxing_gibbous_moon": "🌔", - "wc": "🚾", - "weary": "😩", - "wedding": "💒", - "weightlifter": "🏋", - "whale": "🐳", - "whale2": "🐋", - "wheel_of_dharma": "☸️", - "wheelchair": "♿", - "white_check_mark": "✅", - "white_circle": "⚪", - "white_flower": "💮", - "white_hair": "🦳", - "white_heart": "🤍", - "white_large_square": "⬜", - "white_medium_small_square": "◽", - "white_medium_square": "◻️", - "white_small_square": "▫️", - "white_square_button": "🔳", - "wilted_flower": "🥀", - "wilted_rose": "🥀", - "wind_blowing_face": "🌬", - "wind_chime": "🎐", - "wine_glass": "🍷", - "wink": "😉", - "wolf": "🐺", - "woman": "👩", - "woman_with_headscarf": "🧕", - "womans_clothes": "👚", - "womans_hat": "👒", - "womens": "🚺", - "woozy_face": "🥴", - "world_map": "🗺", - "worried": "😟", - "wrench": "🔧", - "writing_hand": "✍️", - "x": "❌", - "yarn": "🧶", - "yawning_face": "🥱", - "yellow_circle": "🟡", - "yellow_heart": "💛", - "yellow_square": "🟨", - "yen": "💴", - "yin_yang": "☯️", - "yoyo": "🪀", - "yum": "😋", - "zany_face": "🤪", - "zap": "⚡", - "zebra": "🦓", - "zero": "0⃣", - "zipper_mouth": "🤐", - "zombie": "🧟", - "zzz": "💤" -} -\ No newline at end of file diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js @@ -16,12 +16,7 @@ const webpackConfig = merge(baseConfig, { module: { rules: utils.styleLoaders() }, - devtool: '#inline-source-map', - // vue: { - // loaders: { - // js: 'isparta' - // } - // }, + devtool: 'inline-source-map', plugins: [ new webpack.DefinePlugin({ 'process.env': require('../../config/test.env') @@ -37,22 +32,6 @@ const webpackConfig = merge(baseConfig, { // no need for app entry during tests delete webpackConfig.entry -// make sure isparta loader is applied before eslint -// webpackConfig.module.preLoaders = webpackConfig.module.preLoaders || [] -// webpackConfig.module.preLoaders.unshift({ -// test: /\.js$/, -// loader: 'isparta', -// include: path.resolve(projectRoot, 'src') -// }) - -// // only apply babel for test files when using isparta -// webpackConfig.module.loaders.some(function (loader, i) { -// if (loader.loader === 'babel') { -// loader.include = path.resolve(projectRoot, 'test/unit') -// return true -// } -// }) - module.exports = function (config) { config.set({ // to run in additional browsers: diff --git a/test/unit/specs/boot/routes.spec.js b/test/unit/specs/boot/routes.spec.js @@ -40,4 +40,28 @@ describe('routes', () => { // eslint-disable-next-line no-prototype-builtins expect(matchedComponents[0].components.default.components.hasOwnProperty('UserCard')).to.eql(true) }) + + it('list view', async () => { + await router.push('/lists') + + const matchedComponents = router.currentRoute.value.matched + + expect(Object.prototype.hasOwnProperty.call(matchedComponents[0].components.default.components, 'ListsCard')).to.eql(true) + }) + + it('list timeline', async () => { + await router.push('/lists/1') + + const matchedComponents = router.currentRoute.value.matched + + expect(Object.prototype.hasOwnProperty.call(matchedComponents[0].components.default.components, 'Timeline')).to.eql(true) + }) + + it('list edit', async () => { + await router.push('/lists/1/edit') + + const matchedComponents = router.currentRoute.value.matched + + expect(Object.prototype.hasOwnProperty.call(matchedComponents[0].components.default.components, 'BasicUserCard')).to.eql(true) + }) }) diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js @@ -19,9 +19,11 @@ const global = { } } -const makeMention = (who) => { +const makeMention = (who, noClass) => { attentions.push({ statusnet_profile_url: `https://fake.tld/@${who}` }) - return `<span class="h-card"><a class="u-url mention" href="https://fake.tld/@${who}">@<span>${who}</span></a></span>` + return noClass + ? `<span><a href="https://fake.tld/@${who}">@<span>${who}</span></a></span>` + : `<span class="h-card"><a class="u-url mention" href="https://fake.tld/@${who}">@<span>${who}</span></a></span>` } const p = (...data) => `<p>${data.join('')}</p>` const compwrap = (...data) => `<span class="RichContent">${data.join('')}</span>` @@ -142,6 +144,17 @@ describe('RichContent', () => { makeMention('Josh'), makeMention('Jeremy') ].join('') ].join('\n') + const strippedHtml = [ + [ + makeMention('Jack', true), + 'let\'s meet up with ', + makeMention('Janet', true) + ].join(''), + [ + makeMention('John', true), + makeMention('Josh', true), makeMention('Jeremy', true) + ].join('') + ].join('\n') const wrapper = shallowMount(RichContent, { global, @@ -154,7 +167,7 @@ describe('RichContent', () => { } }) - expect(wrapper.html()).to.eql(compwrap(html)) + expect(wrapper.html()).to.eql(compwrap(strippedHtml)) }) it('Adds greentext and cyantext to the post', () => { @@ -412,7 +425,7 @@ describe('RichContent', () => { 'Testing' ].join('') const expected = [ - '<span class="poast-style">', + '<span>', '<span class="MentionsLine">', '<span class="MentionLink mention-link">', '<a href="lol" class="original" target="_blank">', diff --git a/test/unit/specs/components/user_profile.spec.js b/test/unit/specs/components/user_profile.spec.js @@ -15,6 +15,7 @@ const actions = { const testGetters = { findUser: state => getters.findUser(state.users), + findUserByName: state => getters.findUserByName(state.users), relationship: state => getters.relationship(state.users), mergedConfig: state => ({ colors: '', @@ -95,6 +96,7 @@ const externalProfileStore = createStore({ credentials: '' }, usersObject: { 100: extUser }, + usersByNameObject: {}, users: [extUser], relationships: {} } @@ -163,7 +165,8 @@ const localProfileStore = createStore({ currentUser: { credentials: '' }, - usersObject: { 100: localUser, testuser: localUser }, + usersObject: { 100: localUser }, + usersByNameObject: { testuser: localUser }, users: [localUser], relationships: {} } diff --git a/test/unit/specs/modules/lists.spec.js b/test/unit/specs/modules/lists.spec.js @@ -0,0 +1,83 @@ +import { cloneDeep } from 'lodash' +import { defaultState, mutations, getters } from '../../../../src/modules/lists.js' + +describe('The lists module', () => { + describe('mutations', () => { + it('updates array of all lists', () => { + const state = cloneDeep(defaultState) + const list = { id: '1', title: 'testList' } + + mutations.setLists(state, [list]) + expect(state.allLists).to.have.length(1) + expect(state.allLists).to.eql([list]) + }) + + it('adds a new list with a title, updating the title for existing lists', () => { + const state = cloneDeep(defaultState) + const list = { id: '1', title: 'testList' } + const modList = { id: '1', title: 'anotherTestTitle' } + + mutations.setList(state, { listId: list.id, title: list.title }) + expect(state.allListsObject[list.id]).to.eql({ title: list.title, accountIds: [] }) + expect(state.allLists).to.have.length(1) + expect(state.allLists[0]).to.eql(list) + + mutations.setList(state, { listId: modList.id, title: modList.title }) + expect(state.allListsObject[modList.id]).to.eql({ title: modList.title, accountIds: [] }) + expect(state.allLists).to.have.length(1) + expect(state.allLists[0]).to.eql(modList) + }) + + it('adds a new list with an array of IDs, updating the IDs for existing lists', () => { + const state = cloneDeep(defaultState) + const list = { id: '1', accountIds: ['1', '2', '3'] } + const modList = { id: '1', accountIds: ['3', '4', '5'] } + + mutations.setListAccounts(state, { listId: list.id, accountIds: list.accountIds }) + expect(state.allListsObject[list.id]).to.eql({ accountIds: list.accountIds }) + + mutations.setListAccounts(state, { listId: modList.id, accountIds: modList.accountIds }) + expect(state.allListsObject[modList.id]).to.eql({ accountIds: modList.accountIds }) + }) + + it('deletes a list', () => { + const state = { + allLists: [{ id: '1', title: 'testList' }], + allListsObject: { + 1: { title: 'testList', accountIds: ['1', '2', '3'] } + } + } + const listId = '1' + + mutations.deleteList(state, { listId }) + expect(state.allLists).to.have.length(0) + expect(state.allListsObject).to.eql({}) + }) + }) + + describe('getters', () => { + it('returns list title', () => { + const state = { + allLists: [{ id: '1', title: 'testList' }], + allListsObject: { + 1: { title: 'testList', accountIds: ['1', '2', '3'] } + } + } + const id = '1' + + expect(getters.findListTitle(state)(id)).to.eql('testList') + }) + + it('returns list accounts', () => { + const state = { + allLists: [{ id: '1', title: 'testList' }], + allListsObject: { + 1: { title: 'testList', accountIds: ['1', '2', '3'] } + } + } + const id = '1' + + expect(getters.findListAccounts(state)(id)).to.eql(['1', '2', '3']) + }) + }) +}) diff --git a/test/unit/specs/modules/serverSideStorage.spec.js b/test/unit/specs/modules/serverSideStorage.spec.js @@ -0,0 +1,338 @@ +import { cloneDeep } from 'lodash' + +import { + VERSION, + COMMAND_TRIM_FLAGS, + COMMAND_TRIM_FLAGS_AND_RESET, + _moveItemInArray, + _getRecentData, + _getAllFlags, + _mergeFlags, + _mergePrefs, + _resetFlags, + mutations, + defaultState, + newUserFlags +} from 'src/modules/serverSideStorage.js' + +describe('The serverSideStorage module', () => { + describe('mutations', () => { + describe('setServerSideStorage', () => { + const { setServerSideStorage } = mutations + const user = { + created_at: new Date('1999-02-09'), + storage: {} + } + + it('should initialize storage if none present', () => { + const state = cloneDeep(defaultState) + setServerSideStorage(state, user) + expect(state.cache._version).to.eql(VERSION) + expect(state.cache._timestamp).to.be.a('number') + expect(state.cache.flagStorage).to.eql(defaultState.flagStorage) + expect(state.cache.prefsStorage).to.eql(defaultState.prefsStorage) + }) + + it('should initialize storage with proper flags for new users if none present', () => { + const state = cloneDeep(defaultState) + setServerSideStorage(state, { ...user, created_at: new Date() }) + expect(state.cache._version).to.eql(VERSION) + expect(state.cache._timestamp).to.be.a('number') + expect(state.cache.flagStorage).to.eql(newUserFlags) + expect(state.cache.prefsStorage).to.eql(defaultState.prefsStorage) + }) + + it('should merge flags even if remote timestamp is older', () => { + const state = { + ...cloneDeep(defaultState), + cache: { + _timestamp: Date.now(), + _version: VERSION, + ...cloneDeep(defaultState) + } + } + setServerSideStorage( + state, + { + ...user, + storage: { + _timestamp: 123, + _version: VERSION, + flagStorage: { + ...defaultState.flagStorage, + updateCounter: 1 + }, + prefsStorage: { + ...defaultState.prefsStorage + } + } + } + ) + expect(state.cache.flagStorage).to.eql({ + ...defaultState.flagStorage, + updateCounter: 1 + }) + }) + + it('should reset local timestamp to remote if contents are the same', () => { + const state = { + ...cloneDeep(defaultState), + cache: null + } + setServerSideStorage( + state, + { + ...user, + storage: { + _timestamp: 123, + _version: VERSION, + flagStorage: { + ...defaultState.flagStorage, + updateCounter: 999 + } + } + } + ) + expect(state.cache._timestamp).to.eql(123) + expect(state.flagStorage.updateCounter).to.eql(999) + expect(state.cache.flagStorage.updateCounter).to.eql(999) + }) + + it('should remote version if local missing', () => { + const state = cloneDeep(defaultState) + setServerSideStorage(state, user) + expect(state.cache._version).to.eql(VERSION) + expect(state.cache._timestamp).to.be.a('number') + expect(state.cache.flagStorage).to.eql(defaultState.flagStorage) + }) + }) + describe('setPreference', () => { + const { setPreference, updateCache, addCollectionPreference, removeCollectionPreference } = mutations + + it('should set preference and update journal log accordingly', () => { + const state = cloneDeep(defaultState) + setPreference(state, { path: 'simple.testing', value: 1 }) + expect(state.prefsStorage.simple.testing).to.eql(1) + expect(state.prefsStorage._journal.length).to.eql(1) + expect(state.prefsStorage._journal[0]).to.eql({ + path: 'simple.testing', + operation: 'set', + args: [1], + // should have A timestamp, we don't really care what it is + timestamp: state.prefsStorage._journal[0].timestamp + }) + }) + + it('should keep journal to a minimum', () => { + const state = cloneDeep(defaultState) + setPreference(state, { path: 'simple.testing', value: 1 }) + setPreference(state, { path: 'simple.testing', value: 2 }) + addCollectionPreference(state, { path: 'collections.testing', value: 2 }) + removeCollectionPreference(state, { path: 'collections.testing', value: 2 }) + updateCache(state, { username: 'test' }) + expect(state.prefsStorage.simple.testing).to.eql(2) + expect(state.prefsStorage.collections.testing).to.eql([]) + expect(state.prefsStorage._journal.length).to.eql(2) + expect(state.prefsStorage._journal[0]).to.eql({ + path: 'simple.testing', + operation: 'set', + args: [2], + // should have A timestamp, we don't really care what it is + timestamp: state.prefsStorage._journal[0].timestamp + }) + expect(state.prefsStorage._journal[1]).to.eql({ + path: 'collections.testing', + operation: 'removeFromCollection', + args: [2], + // should have A timestamp, we don't really care what it is + timestamp: state.prefsStorage._journal[1].timestamp + }) + }) + + it('should remove duplicate entries from journal', () => { + const state = cloneDeep(defaultState) + setPreference(state, { path: 'simple.testing', value: 1 }) + setPreference(state, { path: 'simple.testing', value: 1 }) + addCollectionPreference(state, { path: 'collections.testing', value: 2 }) + addCollectionPreference(state, { path: 'collections.testing', value: 2 }) + updateCache(state, { username: 'test' }) + expect(state.prefsStorage.simple.testing).to.eql(1) + expect(state.prefsStorage.collections.testing).to.eql([2]) + expect(state.prefsStorage._journal.length).to.eql(2) + }) + }) + }) + + describe('helper functions', () => { + describe('_moveItemInArray', () => { + it('should move item according to movement value', () => { + expect(_moveItemInArray([1, 2, 3, 4], 4, -1)).to.eql([1, 2, 4, 3]) + expect(_moveItemInArray([1, 2, 3, 4], 1, 2)).to.eql([2, 3, 1, 4]) + }) + it('should clamp movement to within array', () => { + expect(_moveItemInArray([1, 2, 3, 4], 4, -10)).to.eql([4, 1, 2, 3]) + expect(_moveItemInArray([1, 2, 3, 4], 3, 99)).to.eql([1, 2, 4, 3]) + }) + }) + describe('_getRecentData', () => { + it('should handle nulls correctly', () => { + expect(_getRecentData(null, null)).to.eql({ recent: null, stale: null, needUpload: true }) + }) + + it('doesn\'t choke on invalid data', () => { + expect(_getRecentData({ a: 1 }, { b: 2 })).to.eql({ recent: null, stale: null, needUpload: true }) + }) + + it('should prefer the valid non-null correctly, needUpload works properly', () => { + const nonNull = { _version: VERSION, _timestamp: 1 } + expect(_getRecentData(nonNull, null)).to.eql({ recent: nonNull, stale: null, needUpload: true }) + expect(_getRecentData(null, nonNull)).to.eql({ recent: nonNull, stale: null, needUpload: false }) + }) + + it('should prefer the one with higher timestamp', () => { + const a = { _version: VERSION, _timestamp: 1 } + const b = { _version: VERSION, _timestamp: 2 } + + expect(_getRecentData(a, b)).to.eql({ recent: b, stale: a, needUpload: false }) + expect(_getRecentData(b, a)).to.eql({ recent: b, stale: a, needUpload: false }) + }) + + it('case where both are same', () => { + const a = { _version: VERSION, _timestamp: 3 } + const b = { _version: VERSION, _timestamp: 3 } + + expect(_getRecentData(a, b)).to.eql({ recent: b, stale: a, needUpload: false }) + expect(_getRecentData(b, a)).to.eql({ recent: b, stale: a, needUpload: false }) + }) + }) + + describe('_getAllFlags', () => { + it('should handle nulls properly', () => { + expect(_getAllFlags(null, null)).to.eql([]) + }) + it('should output list of keys if passed single object', () => { + expect(_getAllFlags({ flagStorage: { a: 1, b: 1, c: 1 } }, null)).to.eql(['a', 'b', 'c']) + }) + it('should union keys of both objects', () => { + expect(_getAllFlags({ flagStorage: { a: 1, b: 1, c: 1 } }, { flagStorage: { c: 1, d: 1 } })).to.eql(['a', 'b', 'c', 'd']) + }) + }) + + describe('_mergeFlags', () => { + it('should handle merge two flag sets correctly picking higher numbers', () => { + expect( + _mergeFlags( + { flagStorage: { a: 0, b: 3 } }, + { flagStorage: { b: 1, c: 4, d: 9 } }, + ['a', 'b', 'c', 'd']) + ).to.eql({ a: 0, b: 3, c: 4, d: 9 }) + }) + }) + + describe('_mergePrefs', () => { + it('should prefer recent and apply journal to it', () => { + expect( + _mergePrefs( + // RECENT + { + simple: { a: 1, b: 0, c: true }, + _journal: [ + { path: 'simple.b', operation: 'set', args: [0], timestamp: 2 }, + { path: 'simple.c', operation: 'set', args: [true], timestamp: 4 } + ] + }, + // STALE + { + simple: { a: 1, b: 1, c: false }, + _journal: [ + { path: 'simple.a', operation: 'set', args: [1], timestamp: 1 }, + { path: 'simple.b', operation: 'set', args: [1], timestamp: 3 } + ] + } + ) + ).to.eql({ + simple: { a: 1, b: 1, c: true }, + _journal: [ + { path: 'simple.a', operation: 'set', args: [1], timestamp: 1 }, + { path: 'simple.b', operation: 'set', args: [1], timestamp: 3 }, + { path: 'simple.c', operation: 'set', args: [true], timestamp: 4 } + ] + }) + }) + + it('should allow setting falsy values', () => { + expect( + _mergePrefs( + // RECENT + { + simple: { a: 1, b: 0, c: false }, + _journal: [ + { path: 'simple.b', operation: 'set', args: [0], timestamp: 2 }, + { path: 'simple.c', operation: 'set', args: [false], timestamp: 4 } + ] + }, + // STALE + { + simple: { a: 0, b: 0, c: true }, + _journal: [ + { path: 'simple.a', operation: 'set', args: [0], timestamp: 1 }, + { path: 'simple.b', operation: 'set', args: [0], timestamp: 3 } + ] + } + ) + ).to.eql({ + simple: { a: 0, b: 0, c: false }, + _journal: [ + { path: 'simple.a', operation: 'set', args: [0], timestamp: 1 }, + { path: 'simple.b', operation: 'set', args: [0], timestamp: 3 }, + { path: 'simple.c', operation: 'set', args: [false], timestamp: 4 } + ] + }) + }) + + it('should work with strings', () => { + expect( + _mergePrefs( + // RECENT + { + simple: { a: 'foo' }, + _journal: [ + { path: 'simple.a', operation: 'set', args: ['foo'], timestamp: 2 } + ] + }, + // STALE + { + simple: { a: 'bar' }, + _journal: [ + { path: 'simple.a', operation: 'set', args: ['bar'], timestamp: 4 } + ] + } + ) + ).to.eql({ + simple: { a: 'bar' }, + _journal: [ + { path: 'simple.a', operation: 'set', args: ['bar'], timestamp: 4 } + ] + }) + }) + }) + + describe('_resetFlags', () => { + it('should reset all known flags to 0 when reset flag is set to > 0 and < 9000', () => { + const totalFlags = { a: 0, b: 3, reset: 1 } + + expect(_resetFlags(totalFlags)).to.eql({ a: 0, b: 0, reset: 0 }) + }) + it('should trim all flags to known when reset is set to 1000', () => { + const totalFlags = { a: 0, b: 3, c: 33, reset: COMMAND_TRIM_FLAGS } + + expect(_resetFlags(totalFlags, { a: 0, b: 0, reset: 0 })).to.eql({ a: 0, b: 3, reset: 0 }) + }) + it('should trim all flags to known and reset when reset is set to 1001', () => { + const totalFlags = { a: 0, b: 3, c: 33, reset: COMMAND_TRIM_FLAGS_AND_RESET } + + expect(_resetFlags(totalFlags, { a: 0, b: 0, reset: 0 })).to.eql({ a: 0, b: 0, reset: 0 }) + }) + }) + }) +}) diff --git a/test/unit/specs/modules/users.spec.js b/test/unit/specs/modules/users.spec.js @@ -57,24 +57,27 @@ describe('The users module', () => { }) describe('findUser', () => { - it('returns user with matching screen_name', () => { + it('does not return user with matching screen_name', () => { const user = { screen_name: 'Guy', id: '1' } const state = { usersObject: { - 1: user, + 1: user + }, + usersByNameObject: { guy: user } } const name = 'Guy' - const expected = { screen_name: 'Guy', id: '1' } - expect(getters.findUser(state)(name)).to.eql(expected) + expect(getters.findUser(state)(name)).to.eql(undefined) }) it('returns user with matching id', () => { const user = { screen_name: 'Guy', id: '1' } const state = { usersObject: { - 1: user, + 1: user + }, + usersByNameObject: { guy: user } } @@ -83,4 +86,35 @@ describe('The users module', () => { expect(getters.findUser(state)(id)).to.eql(expected) }) }) + + describe('findUserByName', () => { + it('returns user with matching screen_name', () => { + const user = { screen_name: 'Guy', id: '1' } + const state = { + usersObject: { + 1: user + }, + usersByNameObject: { + guy: user + } + } + const name = 'Guy' + const expected = { screen_name: 'Guy', id: '1' } + expect(getters.findUserByName(state)(name)).to.eql(expected) + }) + + it('does not return user with matching id', () => { + const user = { screen_name: 'Guy', id: '1' } + const state = { + usersObject: { + 1: user + }, + usersByNameObject: { + guy: user + } + } + const id = '1' + expect(getters.findUserByName(state)(id)).to.eql(undefined) + }) + }) }) diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -195,7 +195,7 @@ describe('API Entities normalizer', () => { expect(parsedPost).to.have.property('type', 'status') expect(parsedRepeat).to.have.property('type', 'retweet') expect(parsedRepeat).to.have.property('retweeted_status') - expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef') + expect(parsedRepeat).to.have.nested.property('retweeted_status.id', 'deadbeef') }) it('sets nsfw for statuses with the #nsfw tag', () => { @@ -229,7 +229,7 @@ describe('API Entities normalizer', () => { expect(parsedPost).to.have.property('type', 'status') expect(parsedRepeat).to.have.property('type', 'retweet') expect(parsedRepeat).to.have.property('retweeted_status') - expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef') + expect(parsedRepeat).to.have.nested.property('retweeted_status.id', 'deadbeef') }) }) }) @@ -269,7 +269,8 @@ describe('API Entities normalizer', () => { it('converts IDN to unicode and marks it as internatonal', () => { const user = makeMockUserMasto({ acct: 'lain@xn--lin-6cd.com' }) - expect(parseUser(user)).to.have.property('screen_name_ui').that.equal('lain@🌏lаin.com') + expect(parseUser(user)).to.have.property('screen_name_ui').that.equal('lain@lаin.com') + expect(parseUser(user)).to.have.property('screen_name_ui_contains_non_ascii').that.equal(true) }) }) @@ -284,9 +285,9 @@ describe('API Entities normalizer', () => { }) expect(parseNotification(notif)).to.have.property('id', 123) expect(parseNotification(notif)).to.have.property('seen', false) - expect(parseNotification(notif)).to.have.deep.property('status.id', '444') - expect(parseNotification(notif)).to.have.deep.property('action.id', '444') - expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo') + expect(parseNotification(notif)).to.have.nested.property('status.id', '444') + expect(parseNotification(notif)).to.have.nested.property('action.id', '444') + expect(parseNotification(notif)).to.have.nested.property('from_profile.id', 'spurdo') }) it('correctly normalizes favorite notifications', () => { @@ -303,9 +304,9 @@ describe('API Entities normalizer', () => { expect(parseNotification(notif)).to.have.property('id', 123) expect(parseNotification(notif)).to.have.property('type', 'like') expect(parseNotification(notif)).to.have.property('seen', true) - expect(parseNotification(notif)).to.have.deep.property('status.id', '4412') - expect(parseNotification(notif)).to.have.deep.property('action.id', '444') - expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo') + expect(parseNotification(notif)).to.have.nested.property('status.id', '4412') + expect(parseNotification(notif)).to.have.nested.property('action.id', '444') + expect(parseNotification(notif)).to.have.nested.property('from_profile.id', 'spurdo') }) }) diff --git a/yarn.lock b/yarn.lock @@ -30,64 +30,69 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.7": +"@babel/compat-data@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== -"@babel/compat-data@^7.18.6", "@babel/compat-data@^7.18.8": +"@babel/compat-data@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== -"@babel/core@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" - integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== +"@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733" + integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g== + +"@babel/core@7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.7.tgz#37072f951bd4d28315445f66e0ec9f6ae0c8c35f" + integrity sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.9" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-module-transforms" "^7.18.9" - "@babel/helpers" "^7.18.9" - "@babel/parser" "^7.18.9" - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/generator" "^7.20.7" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-module-transforms" "^7.20.7" + "@babel/helpers" "^7.20.7" + "@babel/parser" "^7.20.7" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.1" semver "^6.3.0" -"@babel/core@^7.17.9": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.6.tgz#54a107a3c298aee3fe5e1947a6464b9b6faca03d" - integrity sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ== +"@babel/core@^7.12.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" + integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.6" - "@babel/helper-compilation-targets" "^7.18.6" - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helpers" "^7.18.6" - "@babel/parser" "^7.18.6" - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.6" - "@babel/types" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.10" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.1" semver "^6.3.0" -"@babel/eslint-parser@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.18.9.tgz#255a63796819a97b7578751bb08ab9f2a375a031" - integrity sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ== +"@babel/eslint-parser@7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" + integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ== dependencies: - eslint-scope "^5.1.1" + "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" semver "^6.3.0" @@ -100,7 +105,16 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.18.6", "@babel/generator@^7.18.7": +"@babel/generator@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.10.tgz#794f328bfabdcbaf0ebf9bf91b5b57b61fa77a2a" + integrity sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA== + dependencies: + "@babel/types" "^7.18.10" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/generator@^7.18.7": version "7.18.7" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.7.tgz#2aa78da3c05aadfc82dbac16c99552fc802284bd" integrity sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A== @@ -118,6 +132,24 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" +"@babel/generator@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.0.tgz#0bfc5379e0efb05ca6092091261fcdf7ec36249d" + integrity sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w== + dependencies: + "@babel/types" "^7.20.0" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/generator@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" + integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== + dependencies: + "@babel/types" "^7.20.7" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -140,27 +172,7 @@ "@babel/helper-explode-assignable-expression" "^7.18.6" "@babel/types" "^7.18.6" -"@babel/helper-compilation-targets@^7.13.0": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz#18d35bfb9f83b1293c22c55b3d576c1315b6ed96" - integrity sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg== - dependencies: - "@babel/compat-data" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.20.2" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.18.9": +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== @@ -170,6 +182,17 @@ browserslist "^4.20.2" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" + integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== + dependencies: + "@babel/compat-data" "^7.20.5" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.6.tgz#6f15f8459f3b523b39e00a99982e2c040871ed72" @@ -199,15 +222,21 @@ "@babel/helper-annotate-as-pure" "^7.18.6" regexpu-core "^5.1.0" -"@babel/helper-define-polyfill-provider@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" - integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== +"@babel/helper-create-regexp-features-plugin@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" + integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" + +"@babel/helper-define-polyfill-provider@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" + integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== + dependencies: + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" @@ -262,6 +291,14 @@ "@babel/template" "^7.18.6" "@babel/types" "^7.18.9" +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -290,12 +327,12 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== +"@babel/helper-member-expression-to-functions@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz#a6f26e919582275a93c3aa6594756d71b0bb7f05" + integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.20.7" "@babel/helper-module-imports@^7.0.0": version "7.7.4" @@ -310,13 +347,6 @@ dependencies: "@babel/types" "^7.0.0" -"@babel/helper-module-imports@^7.12.13": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - "@babel/helper-module-imports@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" @@ -352,6 +382,34 @@ "@babel/traverse" "^7.18.9" "@babel/types" "^7.18.9" +"@babel/helper-module-transforms@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz#6c52cc3ac63b70952d33ee987cbee1c9368b533f" + integrity sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.19.4" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.6" + "@babel/types" "^7.19.4" + +"@babel/helper-module-transforms@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz#7a6c9a1155bef55e914af574153069c9d9470c43" + integrity sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" + "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" @@ -364,7 +422,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== -"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== @@ -379,6 +437,16 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== +"@babel/helper-plugin-utils@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" + integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== + +"@babel/helper-plugin-utils@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/helper-remap-async-to-generator@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.6.tgz#fa1f81acd19daee9d73de297c0308783cd3cfc23" @@ -389,6 +457,16 @@ "@babel/helper-wrap-function" "^7.18.6" "@babel/types" "^7.18.6" +"@babel/helper-remap-async-to-generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + "@babel/helper-replace-supers@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.6.tgz#efedf51cfccea7b7b8c0f00002ab317e7abfe420" @@ -400,16 +478,17 @@ "@babel/traverse" "^7.18.6" "@babel/types" "^7.18.6" -"@babel/helper-replace-supers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" - integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== +"@babel/helper-replace-supers@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" + integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== dependencies: "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.20.7" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" "@babel/helper-simple-access@^7.18.6": version "7.18.6" @@ -418,6 +497,20 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-simple-access@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz#be553f4951ac6352df2567f7daa19a0ee15668e7" + integrity sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg== + dependencies: + "@babel/types" "^7.19.4" + +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" @@ -439,6 +532,16 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" @@ -449,10 +552,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== "@babel/helper-validator-option@^7.18.6": version "7.18.6" @@ -469,14 +572,15 @@ "@babel/traverse" "^7.18.6" "@babel/types" "^7.18.6" -"@babel/helpers@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.6.tgz#4c966140eaa1fcaa3d5a8c09d7db61077d4debfd" - integrity sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ== +"@babel/helper-wrap-function@^7.18.9": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.10.tgz#a7fcd3ab9b1be4c9b52cf7d7fdc1e88c2ce93396" + integrity sha512-95NLBP59VWdfK2lyLKe6eTMq9xg+yWKzxzxbJ1wcYNi1Auz200+83fMDADjRxBvc2QQor5zja2yTQzXGhk2GtQ== dependencies: - "@babel/template" "^7.18.6" - "@babel/traverse" "^7.18.6" - "@babel/types" "^7.18.6" + "@babel/helper-function-name" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" "@babel/helpers@^7.18.9": version "7.18.9" @@ -487,6 +591,15 @@ "@babel/traverse" "^7.18.9" "@babel/types" "^7.18.9" +"@babel/helpers@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce" + integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA== + dependencies: + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" + "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" @@ -513,6 +626,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.14.7": + version "7.18.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" + integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== + "@babel/parser@^7.16.4": version "7.17.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240" @@ -523,6 +641,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.7.tgz#fc19b645a5456c8d6fdb6cecd3c66c0173902800" integrity sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA== +"@babel/parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.10.tgz#94b5f8522356e69e8277276adf67ed280c90ecc1" + integrity sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg== + "@babel/parser@^7.18.6", "@babel/parser@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.8.tgz#822146080ac9c62dac0823bb3489622e0bc1cbdf" @@ -533,6 +656,16 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== +"@babel/parser@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.0.tgz#b26133c888da4d79b0d3edcf42677bcadc783046" + integrity sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg== + +"@babel/parser@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" + integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" @@ -549,14 +682,14 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-proposal-optional-chaining" "^7.18.9" -"@babel/plugin-proposal-async-generator-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17" - integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w== +"@babel/plugin-proposal-async-generator-functions@^7.20.1": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326" + integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== dependencies: - "@babel/helper-environment-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@^7.18.6": @@ -624,16 +757,16 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" - integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== +"@babel/plugin-proposal-object-rest-spread@^7.20.2": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.20.7" "@babel/plugin-proposal-optional-catch-binding@^7.18.6": version "7.18.6" @@ -721,12 +854,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" - integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" + integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" @@ -821,24 +954,25 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoping@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" - integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== +"@babel/plugin-transform-block-scoping@^7.20.2": + version "7.20.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.9.tgz#2034307073e243fd476dddb5472ec35d13802853" + integrity sha512-hwZN0kr16UkIF/kR9F9x8gd1kTkQl1vyAF2lkUmlTuCtTKOGLE5blQctuxEeKXwz0dkArQ9RYL8+HLb/75KGMA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-classes@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da" - integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g== +"@babel/plugin-transform-classes@^7.20.2": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz#f438216f094f6bb31dc266ebfab8ff05aecad073" + integrity sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-compilation-targets" "^7.20.7" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.20.7" "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" @@ -849,12 +983,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-destructuring@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" - integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== +"@babel/plugin-transform-destructuring@^7.20.2": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz#8bda578f71620c7de7c93af590154ba331415454" + integrity sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-dotall-regex@^7.18.6": version "7.18.6" @@ -917,35 +1051,32 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-modules-amd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" - integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== +"@babel/plugin-transform-modules-amd@^7.19.6": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.7.tgz#1e5cfeb4e5f9b392e86f85698896336b442f8760" + integrity sha512-+1IVLD+dHOzRZWNFFSoyPZz4ffsVmOP+OhhjeahLKpU97v/52LcCb9RabRl5eHM1/HAuH5Dl0q9Pyzrq1v2otQ== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-modules-commonjs@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" - integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== +"@babel/plugin-transform-modules-commonjs@^7.19.6": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.7.tgz#abb5f84695e74d46acf48244082f6cbf8bb23120" + integrity sha512-76jqqFiFdCD+RJwEdtBHUG2/rEKQAmpejPbAKyQECEE3/y4U5CMPc9IXvipS990vgQhzq+ZRw6WJ+q4xJ/P24w== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-simple-access" "^7.20.2" -"@babel/plugin-transform-modules-systemjs@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06" - integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A== +"@babel/plugin-transform-modules-systemjs@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" + integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== dependencies: "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-validator-identifier" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-validator-identifier" "^7.19.1" "@babel/plugin-transform-modules-umd@^7.18.6": version "7.18.6" @@ -955,13 +1086,13 @@ "@babel/helper-module-transforms" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" - integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" + integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-transform-new-target@^7.18.6": version "7.18.6" @@ -978,12 +1109,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/helper-replace-supers" "^7.18.6" -"@babel/plugin-transform-parameters@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" - integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== +"@babel/plugin-transform-parameters@^7.20.1", "@babel/plugin-transform-parameters@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz#0ee349e9d1bc96e78e3b37a7af423a4078a7083f" + integrity sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-property-literals@^7.18.6": version "7.18.6" @@ -1007,16 +1138,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-runtime@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.9.tgz#d9e4b1b25719307bfafbf43065ed7fb3a83adb8f" - integrity sha512-wS8uJwBt7/b/mzE13ktsJdmS4JP/j7PQSaADtnb4I2wL0zK51MQ0pmF8/Jy0wUIS96fr+fXT6S/ifiPXnvrlSg== +"@babel/plugin-transform-runtime@7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz#9d2a9dbf4e12644d6f46e5e75bfbf02b5d6e9194" + integrity sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw== dependencies: "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.9" - babel-plugin-polyfill-corejs2 "^0.3.1" - babel-plugin-polyfill-corejs3 "^0.5.2" - babel-plugin-polyfill-regenerator "^0.3.1" + "@babel/helper-plugin-utils" "^7.19.0" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" semver "^6.3.0" "@babel/plugin-transform-shorthand-properties@^7.18.6": @@ -1026,12 +1157,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664" - integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA== +"@babel/plugin-transform-spread@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" + integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-transform-sticky-regex@^7.18.6": @@ -1055,12 +1186,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-unicode-escapes@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27" - integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw== +"@babel/plugin-transform-unicode-escapes@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" + integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-unicode-regex@^7.18.6": version "7.18.6" @@ -1070,18 +1201,18 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/preset-env@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.9.tgz#9b3425140d724fbe590322017466580844c7eaff" - integrity sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg== +"@babel/preset-env@7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" + integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/compat-data" "^7.20.1" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-validator-option" "^7.18.6" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.18.6" + "@babel/plugin-proposal-async-generator-functions" "^7.20.1" "@babel/plugin-proposal-class-properties" "^7.18.6" "@babel/plugin-proposal-class-static-block" "^7.18.6" "@babel/plugin-proposal-dynamic-import" "^7.18.6" @@ -1090,7 +1221,7 @@ "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-object-rest-spread" "^7.20.2" "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" "@babel/plugin-proposal-optional-chaining" "^7.18.9" "@babel/plugin-proposal-private-methods" "^7.18.6" @@ -1101,7 +1232,7 @@ "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.18.6" + "@babel/plugin-syntax-import-assertions" "^7.20.0" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -1114,10 +1245,10 @@ "@babel/plugin-transform-arrow-functions" "^7.18.6" "@babel/plugin-transform-async-to-generator" "^7.18.6" "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.18.9" - "@babel/plugin-transform-classes" "^7.18.9" + "@babel/plugin-transform-block-scoping" "^7.20.2" + "@babel/plugin-transform-classes" "^7.20.2" "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.20.2" "@babel/plugin-transform-dotall-regex" "^7.18.6" "@babel/plugin-transform-duplicate-keys" "^7.18.9" "@babel/plugin-transform-exponentiation-operator" "^7.18.6" @@ -1125,30 +1256,30 @@ "@babel/plugin-transform-function-name" "^7.18.9" "@babel/plugin-transform-literals" "^7.18.9" "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.18.6" - "@babel/plugin-transform-modules-commonjs" "^7.18.6" - "@babel/plugin-transform-modules-systemjs" "^7.18.9" + "@babel/plugin-transform-modules-amd" "^7.19.6" + "@babel/plugin-transform-modules-commonjs" "^7.19.6" + "@babel/plugin-transform-modules-systemjs" "^7.19.6" "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" "@babel/plugin-transform-new-target" "^7.18.6" "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.20.1" "@babel/plugin-transform-property-literals" "^7.18.6" "@babel/plugin-transform-regenerator" "^7.18.6" "@babel/plugin-transform-reserved-words" "^7.18.6" "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.18.9" + "@babel/plugin-transform-spread" "^7.19.0" "@babel/plugin-transform-sticky-regex" "^7.18.6" "@babel/plugin-transform-template-literals" "^7.18.9" "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.6" + "@babel/plugin-transform-unicode-escapes" "^7.18.10" "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.18.9" - babel-plugin-polyfill-corejs2 "^0.3.1" - babel-plugin-polyfill-corejs3 "^0.5.2" - babel-plugin-polyfill-regenerator "^0.3.1" - core-js-compat "^3.22.1" + "@babel/types" "^7.20.2" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + core-js-compat "^3.25.1" semver "^6.3.0" "@babel/preset-modules@^0.1.5": @@ -1173,12 +1304,12 @@ pirates "^4.0.5" source-map-support "^0.5.16" -"@babel/runtime@7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" - integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== +"@babel/runtime@7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" + integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== dependencies: - regenerator-runtime "^0.13.4" + regenerator-runtime "^0.13.11" "@babel/runtime@^7.8.4": version "7.17.7" @@ -1196,6 +1327,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + "@babel/template@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" @@ -1205,7 +1345,16 @@ "@babel/parser" "^7.18.6" "@babel/types" "^7.18.6" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.13.0": +"@babel/template@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + +"@babel/traverse@^7.0.0": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== @@ -1221,6 +1370,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.10.tgz#37ad97d1cb00efa869b91dd5d1950f8a6cf0cb08" + integrity sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.18.6", "@babel/traverse@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.8.tgz#f095e62ab46abf1da35e5a2011f43aee72d8d5b0" @@ -1253,6 +1418,38 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.19.6": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.0.tgz#538c4c6ce6255f5666eba02252a7b59fc2d5ed98" + integrity sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.0" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.0" + "@babel/types" "^7.20.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.20.7": + version "7.20.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.8.tgz#e3a23eb04af24f8bbe8a8ba3eef6155b77df0b08" + integrity sha512-/RNkaYDeCy4MjyV70+QkSHhxbvj2JO/5Ft2Pa880qJOG8tWrqcT/wXUuCCv43yogfqPzHL77Xu101KQPf4clnQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e" @@ -1269,6 +1466,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" + integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== + dependencies: + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + "@babel/types@^7.18.6", "@babel/types@^7.18.7", "@babel/types@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.8.tgz#c5af199951bf41ba4a6a9a6d0d8ad722b30cd42f" @@ -1285,6 +1491,24 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" +"@babel/types@^7.19.0", "@babel/types@^7.19.4", "@babel/types@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.0.tgz#52c94cf8a7e24e89d2a194c25c35b17a64871479" + integrity sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@babel/types@^7.20.2", "@babel/types@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" + integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@babel/types@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" @@ -1304,60 +1528,70 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@csstools/selector-specificity@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" + integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== + +"@eslint/eslintrc@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e" + integrity sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.2" - globals "^13.15.0" + espree "^9.4.0" + globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@fortawesome/fontawesome-common-types@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz#c1095b1bbabf19f37f9ff0719db38d92a410bcfe" - integrity sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA== +"@fortawesome/fontawesome-common-types@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz#411e02a820744d3f7e0d8d9df9d82b471beaa073" + integrity sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ== -"@fortawesome/fontawesome-svg-core@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz#11e2e8583a7dea75d734e4d0e53d91c63fae7511" - integrity sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA== +"@fortawesome/fontawesome-svg-core@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz#e87e905e444b5e7b715af09b64d27b53d4c8f9d9" + integrity sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.2" + "@fortawesome/fontawesome-common-types" "6.2.1" -"@fortawesome/free-regular-svg-icons@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.2.tgz#9f04009098addcc11d0d185126f058ed042c3099" - integrity sha512-xR4hA+tAwsaTHGfb+25H1gVU/aJ0Rzu+xIUfnyrhaL13yNQ7TWiI2RvzniAaB+VGHDU2a+Pk96Ve+pkN3/+TTQ== +"@fortawesome/free-regular-svg-icons@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz#650e56d937755a8341f2eef258ecb6f95458820f" + integrity sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.2" + "@fortawesome/fontawesome-common-types" "6.2.1" -"@fortawesome/free-solid-svg-icons@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz#491d668b8a6603698d0ce1ac620f66fd22b74c84" - integrity sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ== +"@fortawesome/free-solid-svg-icons@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz#2290ea5adcf1537cbd0c43de6feb38af02141d27" + integrity sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.2" + "@fortawesome/fontawesome-common-types" "6.2.1" -"@fortawesome/vue-fontawesome@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.1.tgz#ced35cefc52b364f7db973f2fe9f50c3dd160715" - integrity sha512-CdXZJoCS+aEPec26ZP7hWWU3SaJlQPZSCGdgpQ2qGl2HUmtUUNrI3zC4XWdn1JUmh3t5OuDeRG1qB4eGRNSD4A== +"@fortawesome/vue-fontawesome@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.2.tgz#1b2ec546caab790c38d3dcb38407485a70703dd2" + integrity sha512-xHVtVY8ASUeEvgcA/7vULUesENhD+pi/EirRHdMBqooHlXBqK+yrV6d8tUye1m5UKQKVgYAHMhUBfOnoiwvc8Q== -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.11.8": + version "0.11.8" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" + integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" @@ -1375,29 +1609,29 @@ source-map "^0.6.1" yaml-eslint-parser "^0.3.2" -"@intlify/core-base@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.2.0.tgz#e652ef7f71597c5d6b123ae34f01e106bb8c5a1b" - integrity sha512-PkaiY9FAzZHAwPNaS+3csXR6L5k8LFBsSjn63/dy5BqE3pOJd07R4+NYtk8ezxymUemu7p5cS9YX77cmnQO6aQ== +"@intlify/core-base@9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.2.2.tgz#5353369b05cc9fe35cab95fe20afeb8a4481f939" + integrity sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA== dependencies: - "@intlify/devtools-if" "9.2.0" - "@intlify/message-compiler" "9.2.0" - "@intlify/shared" "9.2.0" - "@intlify/vue-devtools" "9.2.0" + "@intlify/devtools-if" "9.2.2" + "@intlify/message-compiler" "9.2.2" + "@intlify/shared" "9.2.2" + "@intlify/vue-devtools" "9.2.2" -"@intlify/devtools-if@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.2.0.tgz#55249fcea03b08a6c4d5f04a253f086c74090595" - integrity sha512-8yfusyhUaqInnn6Cma+NTTh5+EWyrnAkez36qADetbUnY4tCeGyAy+MmIAGh0uqmJVIeX94vd6L1AaA0p9McGg== +"@intlify/devtools-if@9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.2.2.tgz#b13d9ac4b4e2fe6d2e7daa556517a8061fe8bd39" + integrity sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg== dependencies: - "@intlify/shared" "9.2.0" + "@intlify/shared" "9.2.2" -"@intlify/message-compiler@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.2.0.tgz#0516f144bed8274b3ea4c9eede4b9a6c08fd046d" - integrity sha512-KGwwZsl+Nw2O26ZOKdytncxzKnMZ236KmM70u4GePgbizI+pu8yAh0apKxljSPzEJ7WECKTVc9R+laG12EJQYA== +"@intlify/message-compiler@9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.2.2.tgz#e42ab6939b8ae5b3d21faf6a44045667a18bba1c" + integrity sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA== dependencies: - "@intlify/shared" "9.2.0" + "@intlify/shared" "9.2.2" source-map "0.6.1" "@intlify/message-compiler@next": @@ -1408,25 +1642,25 @@ "@intlify/shared" "9.2.0-beta.34" source-map "0.6.1" -"@intlify/shared@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.0.tgz#bcd026e419a9eb2e577afe520481ceaca80b3aa9" - integrity sha512-71uObL3Sy2ZiBQBMVETbkspE4Plpy87Hvlj6FAUF3xdD+M82tuxe3MVJjaD3ucqhtHmQWBkAWEurVLdPYr8G2g== - "@intlify/shared@9.2.0-beta.34", "@intlify/shared@next": version "9.2.0-beta.34" resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.0-beta.34.tgz#e8e9a93455eadcc9785fe2e2437fe037fc267f7d" integrity sha512-hbUKcVbTOkLVpnlSeZE1OPgEI7FpvhuZF/gb84xECTjXEImIa3u0fIcJKUUffv3dlAx8fMOE5xKgDzngidm0tw== -"@intlify/vue-devtools@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.2.0.tgz#fb7f18e83378da3504d500210ce3994552e18d18" - integrity sha512-6P/tE/JdNNVo1z/sr/FnSd90OVlox2XuKMmzHR13nvpHGX7fjRn6pVv47L2jySOYG1cMezmYvJl14TAddKpw5Q== +"@intlify/shared@9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.2.tgz#5011be9ca2b4ab86f8660739286e2707f9abb4a5" + integrity sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q== + +"@intlify/vue-devtools@9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz#b95701556daf7ebb3a2d45aa3ae9e6415aed8317" + integrity sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg== dependencies: - "@intlify/core-base" "9.2.0" - "@intlify/shared" "9.2.0" + "@intlify/core-base" "9.2.2" + "@intlify/shared" "9.2.2" -"@intlify/vue-i18n-loader@^5.0.0": +"@intlify/vue-i18n-loader@5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@intlify/vue-i18n-loader/-/vue-i18n-loader-5.0.0.tgz#26f7b9d55b3feb5d50cdbbd537c7ed4b2396b3fb" integrity sha512-rlqWLHrXdchvI9jsI5XA7/3UqE+4pgBD40d+9DWdyRkKeXfMMO9lmkp21jOKC8afWcK0NW5qzYTjp+JEJ6ymZA== @@ -1437,7 +1671,31 @@ json5 "^2.2.0" loader-utils "^2.0.0" -"@jridgewell/gen-mapping@^0.3.2": +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/schemas@^29.0.0": + version "29.0.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" + integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== + dependencies: + "@sinclair/typebox" "^0.24.1" + +"@jest/types@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.2.1.tgz#ec9c683094d4eb754e41e2119d8bdaef01cf6da0" + integrity sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw== + dependencies: + "@jest/schemas" "^29.0.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== @@ -1456,6 +1714,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" @@ -1469,6 +1735,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.14": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" @@ -1484,6 +1758,35 @@ dependencies: pointer-tracker "^2.0.3" +"@kazvmoe-infra/unicode-emoji-json@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@kazvmoe-infra/unicode-emoji-json/-/unicode-emoji-json-0.4.0.tgz#555bab2f8d11db74820ef0a2fbe2805b17c22587" + integrity sha512-22OffREdHzD0U6A/W4RaFPV8NR73za6euibtAxNxO/fu5A6TwxRO2lAdbDWKJH9COv/vYs8zqfEiSalXH2nXJA== + +"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": + version "5.1.1-v1" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" + integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== + dependencies: + eslint-scope "5.1.1" + +"@nightwatch/chai@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nightwatch/chai/-/chai-5.0.2.tgz#86b20908fc090dffd5c9567c0392bc6a494cc2e6" + integrity sha512-yzILJFCcE75OPoRfBlJ80Y3Ky06ljsdrK4Ld92yhmM477vxO2GEguwnd+ldl7pdSYTcg1gSJ1bPPQrA+/Hrn+A== + dependencies: + assertion-error "1.1.0" + check-error "1.0.2" + deep-eql "4.0.1" + loupe "2.3.4" + pathval "1.1.1" + type-detect "4.0.8" + +"@nightwatch/html-reporter-template@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@nightwatch/html-reporter-template/-/html-reporter-template-0.1.4.tgz#c70db1a13bb2e7e1932e6b10ac1e022e61177c94" + integrity sha512-fVylXypRuNJbyFAwY/5H2QM1A1XVoZWis0zhiMwA5LQN0cxHzpG2aUheb+qP1EfkxhFxwSUHOcrvphFLbPA8ow== + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1492,11 +1795,24 @@ "@nodelib/fs.stat" "2.0.3" run-parallel "^1.1.9" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + "@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + "@nodelib/fs.walk@^1.2.3": version "1.2.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" @@ -1505,51 +1821,93 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" -"@ruffle-rs/ruffle@^0.1.0-nightly.2022.7.12": +"@ruffle-rs/ruffle@0.1.0-nightly.2022.7.12": version "0.1.0-nightly.2022.7.12" resolved "https://registry.yarnpkg.com/@ruffle-rs/ruffle/-/ruffle-0.1.0-nightly.2022.7.12.tgz#c2d77fce7a0e98d51a6535371550e0bff019d0ea" integrity sha512-DFsiT4kdUuSHsYXzHV97e9Ui3FkcsHEg1GyHJipt/lCpCoZ2uRtP41uEz9eNc9ug8jWd7UyXxJmdkkRvs9UHgQ== -"@socket.io/base64-arraybuffer@~1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" - integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== -"@stylelint/postcss-css-in-js@^0.37.2": - version "0.37.3" - resolved "https://registry.yarnpkg.com/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.3.tgz#d149a385e07ae365b0107314c084cb6c11adbf49" - integrity sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg== +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: - "@babel/core" "^7.17.9" + type-detect "4.0.8" -"@stylelint/postcss-markdown@^0.36.2": - version "0.36.2" - resolved "https://registry.yarnpkg.com/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz#0a540c4692f8dcdfc13c8e352c17e7bfee2bb391" - integrity sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== dependencies: - remark "^13.0.0" - unist-util-find-all-after "^3.0.2" + type-detect "4.0.8" -"@testim/chrome-version@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.2.tgz#092005c5b77bd3bb6576a4677110a11485e11864" - integrity sha512-1c4ZOETSRpI0iBfIFUqU4KqwBAB2lHUAlBjZz/YqOHqwM9dTTzjV6Km0ZkiEiSCx/tLr1BtESIKyWWMww+RUqw== +"@sinonjs/fake-timers@10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== + dependencies: + "@sinonjs/commons" "^2.0.0" -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@sinonjs/fake-timers@^7.0.4": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== + dependencies: + "@sinonjs/commons" "^1.7.0" -"@types/component-emitter@^1.2.10": - version "1.2.11" +"@sinonjs/samsam@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-7.0.1.tgz#5b5fa31c554636f78308439d220986b9523fc51f" + integrity sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw== + dependencies: + "@sinonjs/commons" "^2.0.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" + integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== + +"@socket.io/base64-arraybuffer@~1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" + integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== + +"@testim/chrome-version@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.3.tgz#fbb68696899d7b8c1b9b891eded9c04fe2cd5529" + integrity sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A== + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/component-emitter@^1.2.10": + version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== @@ -1563,10 +1921,18 @@ resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== -"@types/eslint@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78" - integrity sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng== +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": + version "8.4.5" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.5.tgz#acdfb7dd36b91cc5d812d7c093811a8f3d9b31e4" + integrity sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1576,40 +1942,52 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== -"@types/http-proxy@^1.17.3": - version "1.17.8" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" - integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-proxy@^1.17.8": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" + integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8": +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/json-schema@^7.0.5": - version "7.0.10" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.10.tgz#9b05b7896166cd00e9cbd59864853abf65d9ac23" - integrity sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A== - -"@types/json-schema@^7.0.6": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== - "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/mdast@^3.0.0": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af" - integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== - dependencies: - "@types/unist" "*" - "@types/minimist@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" @@ -1635,15 +2013,17 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== -"@types/unist@*": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== -"@types/unist@^2.0.0", "@types/unist@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" - integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== +"@types/yargs@^17.0.8": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" + integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== + dependencies: + "@types/yargs-parser" "*" "@types/yauzl@^2.9.1": version "2.9.1" @@ -1657,10 +2037,15 @@ resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.2.3.tgz#be682c681126dca2371c4e1a1721f8e8bb400905" integrity sha512-7Bz0qdvxNGV9n0f+xcMKU7wsEfK6PNzo8IdAcOiBgMNyCuU0Mk9dv0Hbd/Kgr+MFFfn4xLHFbuOt820egT5qEA== -"@vue/babel-helper-vue-jsx-merge-props@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz#31624a7a505fb14da1d58023725a4c5f270e6a81" - integrity sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA== +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@vue/babel-helper-vue-jsx-merge-props@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz#8d53a1e21347db8edbe54d339902583176de09f2" + integrity sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA== "@vue/babel-helper-vue-transform-on@^1.0.2": version "1.0.2" @@ -1682,268 +2067,249 @@ html-tags "^3.1.0" svg-tags "^1.0.0" -"@vue/compiler-core@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.37.tgz#b3c42e04c0e0f2c496ff1784e543fbefe91e215a" - integrity sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg== +"@vue/compiler-core@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.45.tgz#d9311207d96f6ebd5f4660be129fb99f01ddb41b" + integrity sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A== dependencies: "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.37" + "@vue/shared" "3.2.45" estree-walker "^2.0.2" source-map "^0.6.1" -"@vue/compiler-dom@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz#10d2427a789e7c707c872da9d678c82a0c6582b5" - integrity sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ== +"@vue/compiler-dom@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz#c43cc15e50da62ecc16a42f2622d25dc5fd97dce" + integrity sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw== dependencies: - "@vue/compiler-core" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-core" "3.2.45" + "@vue/shared" "3.2.45" -"@vue/compiler-sfc@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz#3103af3da2f40286edcd85ea495dcb35bc7f5ff4" - integrity sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg== +"@vue/compiler-sfc@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz#7f7989cc04ec9e7c55acd406827a2c4e96872c70" + integrity sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q== dependencies: "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.37" - "@vue/compiler-dom" "3.2.37" - "@vue/compiler-ssr" "3.2.37" - "@vue/reactivity-transform" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-core" "3.2.45" + "@vue/compiler-dom" "3.2.45" + "@vue/compiler-ssr" "3.2.45" + "@vue/reactivity-transform" "3.2.45" + "@vue/shared" "3.2.45" estree-walker "^2.0.2" magic-string "^0.25.7" postcss "^8.1.10" source-map "^0.6.1" -"@vue/compiler-ssr@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz#4899d19f3a5fafd61524a9d1aee8eb0505313cff" - integrity sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw== +"@vue/compiler-ssr@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz#bd20604b6e64ea15344d5b6278c4141191c983b2" + integrity sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ== dependencies: - "@vue/compiler-dom" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-dom" "3.2.45" + "@vue/shared" "3.2.45" "@vue/devtools-api@^6.0.0-beta.11": version "6.1.3" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.1.3.tgz#a44c52e8fa6d22f84db3abdcdd0be5135b7dd7cf" integrity sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg== -"@vue/devtools-api@^6.1.4", "@vue/devtools-api@^6.2.1": +"@vue/devtools-api@^6.2.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092" integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ== -"@vue/reactivity-transform@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz#0caa47c4344df4ae59f5a05dde2a8758829f8eca" - integrity sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg== +"@vue/devtools-api@^6.4.5": + version "6.4.5" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz#d54e844c1adbb1e677c81c665ecef1a2b4bb8380" + integrity sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ== + +"@vue/reactivity-transform@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz#07ac83b8138550c83dfb50db43cde1e0e5e8124d" + integrity sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ== dependencies: "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-core" "3.2.45" + "@vue/shared" "3.2.45" estree-walker "^2.0.2" magic-string "^0.25.7" -"@vue/reactivity@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.37.tgz#5bc3847ac58828e2b78526e08219e0a1089f8848" - integrity sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A== +"@vue/reactivity@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.45.tgz#412a45b574de601be5a4a5d9a8cbd4dee4662ff0" + integrity sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A== dependencies: - "@vue/shared" "3.2.37" + "@vue/shared" "3.2.45" -"@vue/runtime-core@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.37.tgz#7ba7c54bb56e5d70edfc2f05766e1ca8519966e3" - integrity sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ== +"@vue/runtime-core@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.45.tgz#7ad7ef9b2519d41062a30c6fa001ec43ac549c7f" + integrity sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A== dependencies: - "@vue/reactivity" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/reactivity" "3.2.45" + "@vue/shared" "3.2.45" -"@vue/runtime-dom@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz#002bdc8228fa63949317756fb1e92cdd3f9f4bbd" - integrity sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw== +"@vue/runtime-dom@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz#1a2ef6ee2ad876206fbbe2a884554bba2d0faf59" + integrity sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA== dependencies: - "@vue/runtime-core" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/runtime-core" "3.2.45" + "@vue/shared" "3.2.45" csstype "^2.6.8" -"@vue/server-renderer@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.37.tgz#840a29c8dcc29bddd9b5f5ffa22b95c0e72afdfc" - integrity sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA== +"@vue/server-renderer@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.45.tgz#ca9306a0c12b0530a1a250e44f4a0abac6b81f3f" + integrity sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g== dependencies: - "@vue/compiler-ssr" "3.2.37" - "@vue/shared" "3.2.37" - -"@vue/shared@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702" - integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw== - -"@vue/test-utils@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.2.tgz#0b5edd683366153d5bc5a91edc62f292118710eb" - integrity sha512-E2P4oXSaWDqTZNbmKZFVLrNN/siVN78YkEqs7pHryWerrlZR9bBFLWdJwRoguX45Ru6HxIflzKl4vQvwRMwm5g== + "@vue/compiler-ssr" "3.2.45" + "@vue/shared" "3.2.45" -"@vuelidate/core@2.0.0-alpha.43": - version "2.0.0-alpha.43" - resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.0-alpha.43.tgz#f7eac52504c8948d6b2038f1b5b16ea976d96cc7" - integrity sha512-0/IoC8+A/wgNqmTIQc2eFYYnBlwIkvfM+riVDG1HAG3amdH7iNrFxNRkiHH/XJ810ZpOYPfYVslqYLbgq6E5HQ== - dependencies: - vue-demi "^0.13.4" +"@vue/shared@3.2.45": + version "3.2.45" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.45.tgz#a3fffa7489eafff38d984e23d0236e230c818bc2" + integrity sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg== -"@vuelidate/validators@2.0.0-alpha.31": - version "2.0.0-alpha.31" - resolved "https://registry.yarnpkg.com/@vuelidate/validators/-/validators-2.0.0-alpha.31.tgz#04d63307bc0a12db9f7ad94243350b83aacee998" - integrity sha512-+MFA9nZ7Y9zCpq383/voPDk/hiAmu6KqiJJhLOYB/FmrUPVoyKnuKnI9Bwiq8ok9GZlVkI8BnIrKPKGj9QpwiQ== - dependencies: - vue-demi "^0.13.4" +"@vue/test-utils@2.2.7": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.2.7.tgz#0d93d635031a4cca2de70b825aef3fe20a41e702" + integrity sha512-BMuoruUFTEqhLoOgsMcgNVMiByYbfHCKGr2C4CPdGtz/affUtDVX5zr1RnPuq0tYSiaqq+Enw5voUpG6JY8Q7g== -"@webassemblyjs/ast@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" - integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== +"@vuelidate/core@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.0.tgz#dfe73ba3f997646e07bd4da4f327fe53c29782cb" + integrity sha512-xIFgdQlScO0aaSZ0wTGPJh8YcTMNAj5veI8yPgiAyxOT+GV7vNQFiU1vpYWCL4cklkkhYvRRSC2OEX7YOZNmPQ== dependencies: - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" + vue-demi "^0.13.11" -"@webassemblyjs/floating-point-hex-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" - integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== - -"@webassemblyjs/helper-api-error@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" - integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== - -"@webassemblyjs/helper-buffer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" - integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== - -"@webassemblyjs/helper-code-frame@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" - integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== +"@vuelidate/validators@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@vuelidate/validators/-/validators-2.0.0.tgz#1ddd86c6c81b2cfbb5720961e951cc53ec0a80be" + integrity sha512-fQQcmDWfz7pyH5/JPi0Ng2GEgNK1pUHn/Z/j5rG/Q+HwhgIXvJblTPcZwKOj1ABL7V4UVuGKECvZCDHNGOwdrg== dependencies: - "@webassemblyjs/wast-printer" "1.9.0" + vue-demi "^0.13.11" -"@webassemblyjs/helper-fsm@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" - integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== - -"@webassemblyjs/helper-module-context@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" - integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== dependencies: - "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" -"@webassemblyjs/helper-wasm-bytecode@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" - integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== -"@webassemblyjs/helper-wasm-section@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" - integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== -"@webassemblyjs/ieee754@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" - integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== - dependencies: - "@xtuc/ieee754" "^1.2.0" +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== -"@webassemblyjs/leb128@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" - integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" - integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== -"@webassemblyjs/wasm-edit@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" - integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/helper-wasm-section" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-opt" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - "@webassemblyjs/wast-printer" "1.9.0" - -"@webassemblyjs/wasm-gen@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" - integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" -"@webassemblyjs/wasm-opt@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" - integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" + "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/wasm-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" - integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - -"@webassemblyjs/wast-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" - integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/floating-point-hex-parser" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-code-frame" "1.9.0" - "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" - integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -1954,9 +2320,10 @@ version "4.2.2" resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" -abbrev@1, abbrev@1.0.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" +abab@^2.0.5, abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== accepts@~1.3.4: version "1.3.7" @@ -1973,33 +2340,39 @@ accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + acorn-jsx@^5.2.0, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn@^7.1.1, acorn@^7.4.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.7.1: +acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== -agent-base@2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" - dependencies: - extend "~3.0.0" - semver "~5.0.1" - agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2007,35 +2380,24 @@ agent-base@6: dependencies: debug "4" -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + ajv "^8.0.0" -ajv-keywords@^3.1.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" - -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" + fast-deep-equal "^3.1.3" ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" @@ -2047,17 +2409,7 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^6.10.2: - version "6.12.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" - integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.1: +ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== @@ -2067,13 +2419,17 @@ ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.2.2" -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-colors@^3.0.0: version "3.2.4" @@ -2131,18 +2487,14 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" +ansi-to-html@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.7.2.tgz#a92c149e4184b571eb29a0135ca001a8e2d710cb" + integrity sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g== dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" + entities "^2.2.0" -anymatch@~3.1.1, anymatch@~3.1.2: +anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -2150,44 +2502,11 @@ anymatch@~3.1.1, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - dependencies: - sprintf-js "~1.0.2" - argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -2208,10 +2527,6 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - array.prototype.flat@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" @@ -2226,176 +2541,59 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - dependencies: - util "0.10.3" - -assertion-error@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.0.tgz#c7f85438fdd466bc7ca16ab90c81513797a5d23b" - -assertion-error@^1.0.1: +assertion-error@1.1.0, assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - -ast-types@0.x.x: - version "0.11.7" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.7.tgz#f318bf44e339db6a320be0009ded64ec1471f46c" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - -async@1.x: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -async@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - dependencies: - lodash "^4.17.10" +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - -autoprefixer@6.7.7, autoprefixer@^6.3.1: - version "6.7.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" - integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ= +autoprefixer@10.4.13: + version "10.4.13" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" + integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg== dependencies: - browserslist "^1.7.6" - caniuse-db "^1.0.30000634" + browserslist "^4.21.4" + caniuse-lite "^1.0.30001426" + fraction.js "^4.2.0" normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.16" - postcss-value-parser "^3.2.3" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" -autoprefixer@^9.8.6: - version "9.8.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" - integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== - dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - picocolors "^0.2.1" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" +axe-core@^4.6.1: + version "4.6.2" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.2.tgz#6e566ab2a3d29e415f5115bc0fd2597a5eb3e5e3" + integrity sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg== -axios@^0.27.2: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== +axios@^1.1.3: + version "1.2.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.2.tgz#72681724c6e6a43a9fea860fc558127dbe32f9f1" + integrity sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q== dependencies: - follow-redirects "^1.14.9" + follow-redirects "^1.15.0" form-data "^4.0.0" + proxy-from-env "^1.1.0" -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.1.4, babel-core@^6.26.0: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-loader@8.2.5: - version "8.2.5" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" - integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== +babel-loader@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.0.tgz#839e9ae88aea930864ef9ec0f356dfca96ecf238" + integrity sha512-Antt61KJPinUMwHwIIz9T5zfMgevnfZkEVWYDWlG888fgdvRRGD0JTuf/fFozQnfT+uq64sk1bmdHDy/mOEWnA== dependencies: - object.assign "^4.1.0" + find-cache-dir "^3.3.2" + schema-utils "^4.0.0" babel-plugin-lodash@3.3.4: version "3.3.4" @@ -2408,94 +2606,29 @@ babel-plugin-lodash@3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" -babel-plugin-polyfill-corejs2@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" - integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== +babel-plugin-polyfill-corejs2@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" + integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.3" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" - integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.21.0" - -babel-plugin-polyfill-regenerator@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" - integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== +babel-plugin-polyfill-corejs3@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" + integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/helper-define-polyfill-provider" "^0.3.3" + core-js-compat "^3.25.1" -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" +babel-plugin-polyfill-regenerator@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" + integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - -balanced-match@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + "@babel/helper-define-polyfill-provider" "^0.3.3" balanced-match@^1.0.0: version "1.0.0" @@ -2506,57 +2639,38 @@ balanced-match@^2.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9" integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA== -base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64id@2.0.0, base64id@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" -binary-extensions@^1.0.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: bytes "3.1.2" content-type "~1.0.4" @@ -2566,7 +2680,7 @@ body-parser@1.20.0: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.10.3" + qs "6.11.0" raw-body "2.5.1" type-is "~1.6.18" unpipe "1.0.0" @@ -2592,32 +2706,38 @@ body-scroll-lock@3.1.5: resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== -boolbase@^1.0.0, boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== -brace-expansion@^1.0.0, brace-expansion@^1.1.7: +boxen@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + +brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" + balanced-match "^1.0.0" braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: version "3.0.2" @@ -2626,94 +2746,25 @@ braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - dependencies: - pako "~1.0.5" - -browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" - dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.12.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.13.0.tgz#42556cba011e1b0a2775b611cba6a8eca18e940d" - integrity sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ== - dependencies: - caniuse-lite "^1.0.30001093" - electron-to-chromium "^1.3.488" - escalade "^3.0.1" - node-releases "^1.1.58" +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.17.5, browserslist@^4.19.1: - version "4.20.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" - integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.20.3: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== dependencies: - caniuse-lite "^1.0.30001317" - electron-to-chromium "^1.4.84" - escalade "^3.1.1" - node-releases "^2.0.2" - picocolors "^1.0.0" + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" browserslist@^4.20.2: version "4.21.1" @@ -2725,15 +2776,15 @@ browserslist@^4.20.2: node-releases "^2.0.5" update-browserslist-db "^1.0.4" -browserslist@^4.21.1: - version "4.21.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" - integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== +browserslist@^4.21.3, browserslist@^4.21.4: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== dependencies: - caniuse-lite "^1.0.30001366" - electron-to-chromium "^1.4.188" + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" node-releases "^2.0.6" - update-browserslist-db "^1.0.4" + update-browserslist-db "^1.0.9" buffer-crc32@~0.2.3: version "0.2.13" @@ -2744,25 +2795,13 @@ buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - -buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + base64-js "^1.3.1" + ieee754 "^1.1.13" builtins@^5.0.1: version "5.0.1" @@ -2771,73 +2810,11 @@ builtins@^5.0.1: dependencies: semver "^7.0.0" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^12.0.2: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^15.0.5: - version "15.0.6" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" - integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== - dependencies: - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -2846,42 +2823,17 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" + pascal-case "^3.1.2" + tslib "^2.0.3" camelcase-keys@^6.2.2: version "6.2.2" @@ -2892,10 +2844,6 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - camelcase@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" @@ -2910,56 +2858,62 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== -caniuse-api@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== dependencies: - browserslist "^1.3.6" - caniuse-db "^1.0.30000529" + browserslist "^4.0.0" + caniuse-lite "^1.0.0" lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000928" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000928.tgz#2e83d2b14276442da239511615eb7c62fed0cfa7" - -caniuse-lite@^1.0.30001093: - version "1.0.30001107" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001107.tgz#809360df7a5b3458f627aa46b0f6ed6d5239da9a" - integrity sha512-86rCH+G8onCmdN4VZzJet5uPELII59cUzDphko3thQFgAQG1RNa+sVLDoALIhRYmflo5iSIzWY3vu1XTWtNMQQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370: + version "1.0.30001376" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001376.tgz#af2450833e5a06873fbb030a9556ca9461a2736d" + integrity sha512-I27WhtOQ3X3v3it9gNs/oTpoE5KpwmqKR5oKPA8M0G7uMXh9Ty81Q904HpKUrM30ei7zfcL5jE7AXefgbOfMig== -caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001359: +caniuse-lite@^1.0.30001359: version "1.0.30001366" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001366.tgz#c73352c83830a9eaf2dea0ff71fb4b9a4bbaa89c" integrity sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA== -caniuse-lite@^1.0.30001317: - version "1.0.30001317" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001317.tgz#0548fb28fd5bc259a70b8c1ffdbe598037666a1b" - integrity sha512-xIZLh8gBm4dqNX0gkzrBeyI86J2eCjWzYAs40q88smG844YIrN4tVQl/RhquHvKEKImWWFIVh1Lxe5n1G/N+GQ== - -caniuse-lite@^1.0.30001366: - version "1.0.30001367" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz#2b97fe472e8fa29c78c5970615d7cd2ee414108a" - integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== - -chai-nightwatch@~0.1.x: - version "0.1.1" - resolved "https://registry.yarnpkg.com/chai-nightwatch/-/chai-nightwatch-0.1.1.tgz#1ca56de768d3c0868fe7fc2f4d32c2fe894e6be9" - dependencies: - assertion-error "1.0.0" - deep-eql "0.1.3" - -chai@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" - integrity sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc= - dependencies: - assertion-error "^1.0.1" - deep-eql "^0.1.3" - type-detect "^1.0.0" - -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: +caniuse-lite@^1.0.30001400: + version "1.0.30001418" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz#5f459215192a024c99e3e3a53aac310fc7cf24e6" + integrity sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg== + +caniuse-lite@^1.0.30001426: + version "1.0.30001439" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz#ab7371faeb4adff4b74dad1718a6fd122e45d9cb" + integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A== + +chai-nightwatch@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/chai-nightwatch/-/chai-nightwatch-0.5.3.tgz#980ecf63dde5a04e7f3524370682c7ff01178ffb" + integrity sha512-38ixH/mqpY6IwnZkz6xPqx8aB5/KVR+j6VPugcir3EGOsphnWXrPH/mUt8Jp+ninL6ghY0AaJDQ10hSfCPGy/g== + dependencies: + assertion-error "1.1.0" + +chai@4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" + integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^4.1.2" + get-func-name "^2.0.0" + loupe "^2.3.1" + pathval "^1.1.1" + type-detect "^4.0.5" + +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -2969,7 +2923,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" dependencies: @@ -2977,7 +2931,7 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4. escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2993,30 +2947,12 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +check-error@1.0.2, check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1: +chokidar@3.5.3, "chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3031,49 +2967,6 @@ character-reference-invalid@^1.0.0: optionalDependencies: fsevents "~2.3.2" -chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chokidar@^3.4.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" - -chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - chromatism@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/chromatism/-/chromatism-3.0.0.tgz#a7249d353c1e4f3577e444ac41171c4e2e624b12" @@ -3084,51 +2977,40 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -chromedriver@103.0.0: - version "103.0.0" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-103.0.0.tgz#2ef086d62076e3ff6df6cfb84895d11d2c18d9cf" - integrity sha512-7BHf6HWt0PeOHCzWO8qlnD13sARzr5AKTtG8Csn+czsuAsajwPxdLNtry5GPh8HYFyl+i0M+yg3bT43AGfgU9w== +chromedriver@108.0.0: + version "108.0.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-108.0.0.tgz#7994013f423d8b95a513bb9553a55088de81b252" + integrity sha512-/kb0rb0dlC4RfXh2BOT7RV87K6d+It3VV5YXebLzO5a8t2knNffiTE23XPJQCH+l1xmgoW8/sOX/NB9irskvOQ== dependencies: - "@testim/chrome-version" "^1.1.2" - axios "^0.27.2" - del "^6.0.0" + "@testim/chrome-version" "^1.1.3" + axios "^1.1.3" + compare-versions "^5.0.1" extract-zip "^2.0.1" - https-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" proxy-from-env "^1.1.0" tcp-port-used "^1.0.1" -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -clap@^1.0.9: - version "1.2.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" - dependencies: - chalk "^1.1.3" +ci-info@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" +ci-info@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f" + integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw== -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" +clean-css@^5.2.2: + version "5.3.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" + integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== dependencies: source-map "~0.6.0" -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== cli-cursor@^2.1.0: version "2.1.0" @@ -3136,11 +3018,32 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + cli-spinners@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" integrity sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg== +cli-spinners@^2.5.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" + integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== + +cli-table3@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" + integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + click-outside-vue3@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/click-outside-vue3/-/click-outside-vue3-4.0.1.tgz#81a6ac01696b301764b42db6fdbdf28e7cd8ef95" @@ -3172,39 +3075,12 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-regexp@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f" - integrity sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q== - dependencies: - is-regexp "^2.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== -co@~3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/co/-/co-3.0.6.tgz#1445f226c5eb956138e68c9ac30167ea7d2e6bda" - -coa@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" - dependencies: - q "^1.1.2" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.3.0, color-convert@^1.9.0: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" dependencies: @@ -3217,7 +3093,7 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3, color-name@^1.0.0: +color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" @@ -3226,37 +3102,16 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" - dependencies: - color-name "^1.0.0" - -color@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" - dependencies: - clone "^1.0.2" - color-convert "^1.3.0" - color-string "^0.3.0" - -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" - dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" +colord@^2.9.1, colord@^2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== colors@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -3264,28 +3119,29 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@2.17.x, commander@~2.17.1: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" +compare-versions@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.3.tgz#a9b34fea217472650ef4a2651d905f42c28ebfd7" + integrity sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A== component-emitter@~1.3.0: version "1.3.0" @@ -3296,19 +3152,10 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -connect-history-api-fallback@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== +connect-history-api-fallback@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== connect@^3.7.0: version "3.7.0" @@ -3320,20 +3167,6 @@ connect@^3.7.0: parseurl "~1.3.3" utils-merge "1.0.1" -console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - dependencies: - date-now "^0.1.4" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" @@ -3345,12 +3178,6 @@ content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" -convert-source-map@^1.5.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - dependencies: - safe-buffer "~5.1.1" - convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" @@ -3372,57 +3199,24 @@ cookie@~0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" +copy-webpack-plugin@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" + integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -copy-webpack-plugin@6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz#138cd9b436dbca0a6d071720d5414848992ec47e" - integrity sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA== - dependencies: - cacache "^15.0.5" - fast-glob "^3.2.4" - find-cache-dir "^3.3.1" - glob-parent "^5.1.1" - globby "^11.0.1" - loader-utils "^2.0.0" + fast-glob "^3.2.11" + glob-parent "^6.0.1" + globby "^13.1.1" normalize-path "^3.0.0" - p-limit "^3.0.2" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - webpack-sources "^1.4.3" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" -core-js-compat@^3.21.0: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" - integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== +core-js-compat@^3.25.1: + version "3.26.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.26.0.tgz#94e2cf8ba3e63800c4956ea298a6473bc9d62b44" + integrity sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A== dependencies: - browserslist "^4.19.1" - semver "7.0.0" - -core-js-compat@^3.22.1: - version "3.23.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.23.4.tgz#56ad4a352884317a15f6b04548ff7139d23b917f" - integrity sha512-RkSRPe+JYEoflcsuxJWaiMPhnZoFS51FcIxm53k4KzhISCBTmaGlto9dTIrYuk0hnJc3G6pKufAKepHnBq6B6Q== - dependencies: - browserslist "^4.21.1" - semver "7.0.0" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" + browserslist "^4.21.4" core-util-is@~1.0.0: version "1.0.2" @@ -3436,16 +3230,6 @@ cors@~2.8.5: object-assign "^4" vary "^1" -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - cosmiconfig@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" @@ -3457,48 +3241,23 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" +cosmiconfig@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" cropperjs@1.5.12: version "1.5.12" resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50" integrity sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw== -cross-spawn@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^7.0.2: +cross-spawn@7.0.3, cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3507,131 +3266,149 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -css-color-names@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - -css-loader@0.28.11: - version "0.28.11" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7" - integrity sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg== - dependencies: - babel-code-frame "^6.26.0" - css-selector-tokenizer "^0.7.0" - cssnano "^3.10.0" - icss-utils "^2.1.0" - loader-utils "^1.0.2" - lodash.camelcase "^4.3.0" - object-assign "^4.1.1" - postcss "^5.0.6" - postcss-modules-extract-imports "^1.2.0" - postcss-modules-local-by-default "^1.2.0" - postcss-modules-scope "^1.1.0" - postcss-modules-values "^1.3.0" - postcss-value-parser "^3.3.0" - source-list-map "^2.0.0" - -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" +css-declaration-sorter@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz#72ebd995c8f4532ff0036631f7365cce9759df14" + integrity sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og== -css-selector-tokenizer@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d" +css-functions-list@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.1.0.tgz#cf5b09f835ad91a00e5959bcfc627cd498e1321b" + integrity sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w== + +css-loader@6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.3.tgz#1e8799f3ccc5874fdd55461af51137fcc5befbcd" + integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.19" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +css-minimizer-webpack-plugin@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz#79f6199eb5adf1ff7ba57f105e3752d15211eb35" + integrity sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA== + dependencies: + cssnano "^5.1.8" + jest-worker "^29.1.2" + postcss "^8.4.17" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" -css-what@2.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" -cssesc@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" - -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" +cssnano-preset-default@^5.2.12: + version "5.2.12" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" + integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== + dependencies: + css-declaration-sorter "^6.3.0" + cssnano-utils "^3.1.0" + postcss-calc "^8.2.3" + postcss-colormin "^5.3.0" + postcss-convert-values "^5.1.2" + postcss-discard-comments "^5.1.2" + postcss-discard-duplicates "^5.1.0" + postcss-discard-empty "^5.1.1" + postcss-discard-overridden "^5.1.0" + postcss-merge-longhand "^5.1.6" + postcss-merge-rules "^5.1.2" + postcss-minify-font-values "^5.1.0" + postcss-minify-gradients "^5.1.1" + postcss-minify-params "^5.1.3" + postcss-minify-selectors "^5.2.1" + postcss-normalize-charset "^5.1.0" + postcss-normalize-display-values "^5.1.0" + postcss-normalize-positions "^5.1.1" + postcss-normalize-repeat-style "^5.1.1" + postcss-normalize-string "^5.1.0" + postcss-normalize-timing-functions "^5.1.0" + postcss-normalize-unicode "^5.1.0" + postcss-normalize-url "^5.1.0" + postcss-normalize-whitespace "^5.1.1" + postcss-ordered-values "^5.1.3" + postcss-reduce-initial "^5.1.0" + postcss-reduce-transforms "^5.1.0" + postcss-svgo "^5.1.0" + postcss-unique-selectors "^5.1.1" + +cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + +cssnano@^5.1.8: + version "5.1.13" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.13.tgz#83d0926e72955332dc4802a7070296e6258efc0a" + integrity sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ== + dependencies: + cssnano-preset-default "^5.2.12" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: - clap "^1.0.9" - source-map "^0.5.3" + cssom "~0.3.6" csstype@^2.6.8: version "2.6.20" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - dependencies: - array-find-index "^1.0.1" - custom-event-polyfill@1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz#9bc993ddda937c1a30ccd335614c6c58c4f87aee" @@ -3641,53 +3418,31 @@ custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - -data-uri-to-buffer@1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" +data-urls@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" + integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== + dependencies: + abab "^2.0.6" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" date-format@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.6.tgz#f6138b8f17968df9815b3d101fc06b0523f066c5" integrity sha512-B9vvg5rHuQ8cbUXE/RMWMyX2YA5TecT3jKF5fLtGNlzPlU7zblSPmAm2OImDbWL+LDOQ6pUm+4LOFz+ywS41Zw== -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - -dateformat@^1.0.6: - version "1.0.12" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" - dependencies: - get-stdin "^4.0.1" - meow "^3.3.0" - de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= -debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" -debug@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - -debug@2.6.8: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - dependencies: - ms "2.0.0" - debug@4: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" @@ -3701,6 +3456,20 @@ debug@4.1.0: dependencies: ms "^2.1.1" +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@4.3.4, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -3714,13 +3483,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.0.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -3735,88 +3497,66 @@ decamelize-keys@^1.1.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -deep-eql@0.1.3, deep-eql@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" +decimal.js@^10.3.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + +deep-eql@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.1.tgz#2b65bc89491d193780c452edee2144a91bb0a445" + integrity sha512-D/Oxqobjr+kxaHsgiQBZq9b6iAWdEj5W/JdJm8deNduAPc9CwXQ3BJJCuEqlrPXcy45iOMkGPZ0T81Dnz7UDCA== dependencies: - type-detect "0.1.1" + type-detect "^4.0.0" -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" +deep-eql@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.2.tgz#270ceb902f87724077e6f6449aed81463f42fc1c" + integrity sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w== + dependencies: + type-detect "^4.0.0" -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - dependencies: - is-descriptor "^1.0.0" +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA== dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + clone "^1.0.2" -degenerator@~1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" - dependencies: - ast-types "0.x.x" - escodegen "1.x.x" - esprima "3.x.x" +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" + object-keys "^1.0.12" delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -3826,52 +3566,29 @@ depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" -des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" -diff@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" - -diff@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" +didyoumean@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== -diff@3.5.0, diff@^3.1.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" +diff@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== dijkstrajs@^1.0.1: version "1.0.2" @@ -3898,9 +3615,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-converter@~0.2: +dom-converter@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== dependencies: utila "~0.4" @@ -3914,111 +3632,106 @@ dom-serialize@^2.2.1: extend "^3.0.0" void-elements "^2.0.0" -dom-serializer@0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== dependencies: - domelementtype "~1.1.1" - entities "~1.1.1" + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - -domelementtype@1, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" -domelementtype@~1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== -domhandler@2.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== dependencies: - domelementtype "1" + webidl-conversions "^7.0.0" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== dependencies: - domelementtype "1" + domelementtype "^2.2.0" -domutils@1.1: - version "1.1.6" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485" +domhandler@^5.0.1, domhandler@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== dependencies: - domelementtype "1" + domelementtype "^2.3.0" -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: - dom-serializer "0" - domelementtype "1" + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== +domutils@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" + integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== dependencies: - dom-serializer "0" - domelementtype "1" + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.1" -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" + no-case "^3.0.4" + tslib "^2.0.3" + +dotenv@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -ejs@2.5.7: - version "2.5.7" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" - -electron-to-chromium@^1.2.7: - version "1.3.100" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.100.tgz#899fb088def210aee6b838a47655bbb299190e13" - -electron-to-chromium@^1.3.488: - version "1.3.509" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.509.tgz#830fcb89cd66dc2984d18d794973b99e3f00584c" - integrity sha512-cN4lkjNRuTG8rtAqTOVgwpecEC2kbKA04PG6YijcKGHK/kD0xLjiqExcAOmLUwtXZRF8cBeam2I0VZcih919Ug== +ejs@3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" + integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== + dependencies: + jake "^10.8.5" electron-to-chromium@^1.4.172: version "1.4.187" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.187.tgz#b884493df00816dc2ce928958c4f6a51a93fe1a8" integrity sha512-t3iFLHVIMhB8jGZ+8ui951nz6Bna5qKfhxezG3wzXdBJ79qFKPsE2chjjVFNqC1ewhfrPQrw9pmVeo4FFpZeQA== -electron-to-chromium@^1.4.188: - version "1.4.191" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.191.tgz#01dd4bf32502a48ce24bf3890b5553a1c5f93539" - integrity sha512-MeEaiuoSFh4G+rrN+Ilm1KJr8pTTZloeLurcZ+PRcthvdK1gWThje+E6baL7/7LoNctrzCncavAG/j/vpES9jg== +electron-to-chromium@^1.4.202: + version "1.4.219" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.219.tgz#a7a672304b6aa4f376918d3f63a47f2c3906009a" + integrity sha512-zoQJsXOUw0ZA0YxbjkmzBumAJRtr6je5JySuL/bAoFs0DuLiLJ+5FzRF7/ZayihxR2QcewlRZVm5QZdUhwjOgA== -electron-to-chromium@^1.4.84: - version "1.4.86" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.86.tgz#90fe4a9787f48d6522957213408e08a8126b2ebc" - integrity sha512-EVTZ+igi8x63pK4bPuA95PXIs2b2Cowi3WQwI9f9qManLiZJOD1Lash1J3W4TvvcUCcIR4o/rgi9o8UicXSO+w== - -elliptic@^6.0.0: - version "6.4.1" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" +electron-to-chromium@^1.4.251: + version "1.4.276" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz#17837b19dafcc43aba885c4689358b298c19b520" + integrity sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ== emoji-regex@^8.0.0: version "8.0.0" @@ -4043,7 +3756,7 @@ encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" dependencies: @@ -4072,30 +3785,40 @@ engine.io@~6.2.0: engine.io-parser "~5.0.3" ws "~8.2.3" -enhanced-resolve@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" - integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" + graceful-fs "^4.2.4" + tapable "^2.2.0" ent@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" +entities@^2.0.0, entities@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^4.2.0, entities@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== + +envinfo@7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -errno@^0.1.3, errno@~0.1.7: +errno@^0.1.3: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" dependencies: @@ -4127,24 +3850,10 @@ es-abstract@^1.19.0, es-abstract@^1.19.1: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.1" -es-abstract@^1.5.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" - -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== es-to-primitive@^1.2.1: version "1.2.1" @@ -4155,11 +3864,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escalade@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" - integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -4170,32 +3874,22 @@ escape-html@1.0.3, escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -escape-string-regexp@^4.0.0: +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.2.0" +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -escodegen@1.x.x, escodegen@^1.6.1: - version "1.11.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: - esprima "^3.1.3" - estraverse "^4.2.0" + esprima "^4.0.1" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: @@ -4260,29 +3954,29 @@ eslint-plugin-import@2.26.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-plugin-n@15.2.4: - version "15.2.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-15.2.4.tgz#d62021a0821ae650701ed459756aaf478a9b6056" - integrity sha512-tjnVMv2fiXYMnuiIFI8QMtyUFI42SckEEWvi8h68SWGWshfqO6SSCASy24dGMGAiy7NUk6DZt90DM0iNUsmQ5w== +eslint-plugin-n@15.6.1: + version "15.6.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz#f7e77f24abb92a550115cf11e29695da122c398c" + integrity sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA== dependencies: builtins "^5.0.1" eslint-plugin-es "^4.1.0" eslint-utils "^3.0.0" ignore "^5.1.1" - is-core-module "^2.9.0" + is-core-module "^2.11.0" minimatch "^3.1.2" - resolve "^1.10.1" - semver "^7.3.7" + resolve "^1.22.1" + semver "^7.3.8" -eslint-plugin-promise@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz#017652c07c9816413a41e11c30adc42c3d55ff18" - integrity sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw== +eslint-plugin-promise@6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" + integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== -eslint-plugin-vue@9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz#c3f5ce515dae387e062428725c5cf96098d9da0b" - integrity sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ== +eslint-plugin-vue@9.8.0: + version "9.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.8.0.tgz#91de2aabbee8cdbef078ccd4f650a9ecfa445f4f" + integrity sha512-E/AXwcTzunyzM83C2QqDHxepMzvI2y6x+mmeYHbVDQlKFqmKYvRrhaVixEeeG27uI44p9oKDFiyCRw4XxgtfHA== dependencies: eslint-utils "^3.0.0" natural-compare "^1.4.0" @@ -4292,14 +3986,7 @@ eslint-plugin-vue@9.3.0: vue-eslint-parser "^9.0.1" xml-name-validator "^4.0.0" -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^5.1.1: +eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -4344,25 +4031,26 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint-webpack-plugin@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-2.7.0.tgz#0525793a4f8c652c1c6d863995ce1e0f2dcbd143" - integrity sha512-bNaVVUvU4srexGhVcayn/F4pJAz19CWBkKoMx7aSQ4wtTbZQCnG5O9LHCE42mM+JSKOUp7n6vd5CIwzj7lOVGA== +eslint-webpack-plugin@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz#1978cdb9edc461e4b0195a20da950cf57988347c" + integrity sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w== dependencies: - "@types/eslint" "^7.29.0" - arrify "^2.0.1" - jest-worker "^27.5.1" + "@types/eslint" "^7.29.0 || ^8.4.1" + jest-worker "^28.0.2" micromatch "^4.0.5" normalize-path "^3.0.0" - schema-utils "^3.1.1" + schema-utils "^4.0.0" -eslint@8.20.0: - version "8.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.20.0.tgz#048ac56aa18529967da8354a478be4ec0a2bc81b" - integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA== +eslint@8.32.0: + version "8.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.32.0.tgz#d9690056bb6f1a302bd991e7090f5b68fbaea861" + integrity sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ== dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + "@eslint/eslintrc" "^1.4.1" + "@humanwhocodes/config-array" "^0.11.8" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -4372,18 +4060,21 @@ eslint@8.20.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.2" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.15.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -4395,7 +4086,6 @@ eslint@8.20.0: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" espree@^6.0.0: version "6.2.1" @@ -4406,7 +4096,7 @@ espree@^6.0.0: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" -espree@^9.3.1, espree@^9.3.2: +espree@^9.3.1: version "9.3.2" resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== @@ -4415,17 +4105,19 @@ espree@^9.3.1, espree@^9.3.2: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" -esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -esprima@3.x.x, esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" -esprima@^4.0.0: +esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0: version "1.4.0" @@ -4434,12 +4126,6 @@ esquery@^1.4.0: dependencies: estraverse "^5.1.0" -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - dependencies: - estraverse "^4.1.0" - esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" @@ -4447,11 +4133,7 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -4478,49 +4160,24 @@ eventemitter3@^4.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== eventsource-polyfill@0.9.6: version "0.9.6" resolved "https://registry.yarnpkg.com/eventsource-polyfill/-/eventsource-polyfill-0.9.6.tgz#10e0d187f111b167f28fdab918843ce7d818f13c" integrity sha1-EODRh/ERsWfyj9q5GIQ859gY8Tw= -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execall@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45" - integrity sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow== - dependencies: - clone-regexp "^2.1.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express@4.18.1: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== +express@4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.0" + body-parser "1.20.1" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.5.0" @@ -4539,7 +4196,7 @@ express@4.18.1: parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.10.3" + qs "6.11.0" range-parser "~1.2.1" safe-buffer "5.2.1" send "0.18.0" @@ -4550,37 +4207,11 @@ express@4.18.1: utils-merge "1.0.1" vary "~1.1.2" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@3, extend@3.0.2, extend@^3.0.0, extend@~3.0.0: +extend@3.0.2, extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - extract-zip@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" @@ -4592,43 +4223,26 @@ extract-zip@^2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" - merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - -fast-glob@^3.2.4: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== +fast-glob@^3.2.11, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" -fast-glob@^3.2.5, fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== +fast-glob@^3.2.12: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -4640,19 +4254,15 @@ fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fastest-levenshtein@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" - integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== - -fastparse@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" +fastest-levenshtein@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== fastq@^1.6.0: version "1.8.0" @@ -4668,10 +4278,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4679,26 +4285,12 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-loader@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" - integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== - dependencies: - loader-utils "^1.0.2" - schema-utils "^1.0.0" - -file-uri-to-path@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" +filelist@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" + minimatch "^5.0.1" fill-range@^7.0.1: version "7.0.1" @@ -4733,7 +4325,7 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: +find-cache-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" dependencies: @@ -4741,21 +4333,22 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== +find-cache-dir@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== dependencies: commondir "^1.0.1" make-dir "^3.0.2" pkg-dir "^4.1.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" +find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" + locate-path "^6.0.0" + path-exists "^4.0.0" find-up@^2.1.0: version "2.1.0" @@ -4785,6 +4378,11 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" @@ -4799,27 +4397,16 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - follow-redirects@^1.0.0: version "1.6.1" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.1.tgz#514973c44b5757368bad8bddfe52f81f015c94cb" dependencies: debug "=3.1.0" -follow-redirects@^1.14.9: - version "1.15.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" - integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== form-data@^4.0.0: version "4.0.0" @@ -4830,34 +4417,20 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -formatio@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" - dependencies: - samsam "1.x" - forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - dependencies: - map-cache "^0.2.2" +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - fs-extra@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" @@ -4867,72 +4440,28 @@ fs-extra@^10.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - dependencies: - minipass "^2.2.1" - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - dependencies: - nan "^2.12.1" - node-pre-gyp "^0.12.0" - -fsevents@~2.3.1, fsevents@~2.3.2: +fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -ftp@~0.3.10: - version "0.3.10" - resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" - dependencies: - readable-stream "1.1.x" - xregexp "2.0.0" - function-bind@1.1.1, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -4943,6 +4472,11 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -4952,15 +4486,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - -get-stdin@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" - integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== - get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -4976,78 +4501,34 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -get-uri@2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.2.tgz#5c795e71326f6ca1286f2fc82575cd2bab2af578" - dependencies: - data-uri-to-buffer "1" - debug "2" - extend "3" - file-uri-to-path "1" - ftp "~0.3.10" - readable-stream "2" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - dependencies: - is-glob "^4.0.1" - -glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.1, glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" -glob@7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" +glob@7.2.0, glob@^7.1.7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" @@ -5062,27 +4543,15 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.7: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" @@ -5106,30 +4575,14 @@ globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" -globals@^13.15.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== +globals@^13.19.0: + version "13.19.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" + integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== dependencies: type-fest "^0.20.2" -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -globby@^11.0.1: - version "11.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" - integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -globby@^11.0.3: +globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -5141,19 +4594,23 @@ globby@^11.0.3: merge2 "^1.4.1" slash "^3.0.0" +globby@^13.1.1: + version "13.1.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.2.tgz#29047105582427ab6eca4f905200667b056da515" + integrity sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + globjoin@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= -gonzales-pe@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" - integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== - dependencies: - minimist "^1.2.5" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: +graceful-fs@^4.1.2: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" @@ -5167,23 +4624,20 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== -handlebars@^4.0.1: - version "4.0.12" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" - dependencies: - async "^2.5.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== hard-rejection@^2.1.0: version "2.1.0" @@ -5201,14 +4655,6 @@ has-bigints@^1.0.1: resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -5234,50 +4680,12 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.1, has@^1.0.3: +has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" dependencies: function-bind "^1.1.1" -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - hash-sum@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" @@ -5287,37 +4695,11 @@ hash-sum@^2.0.0: resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - -he@1.2.x, he@^1.2.0: +he@1.2.0, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" @@ -5329,74 +4711,76 @@ hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" html-entities@^2.1.0: version "2.3.3" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== -html-minifier@^3.2.3: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" html-tags@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== -html-webpack-plugin@3.2.0: +html-tags@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" - integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= - dependencies: - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" - tapable "^1.0.0" - toposort "^1.0.0" - util.promisify "1.0.0" - -htmlparser2@^3.10.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" + integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg== + +html-webpack-plugin@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" + integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" -htmlparser2@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe" +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== dependencies: - domelementtype "1" - domhandler "2.1" - domutils "1.1" - readable-stream "1.0" + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" -http-errors@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" +htmlparser2@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" + integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" + domelementtype "^2.3.0" + domhandler "^5.0.2" + domutils "^3.0.1" + entities "^4.3.0" http-errors@1.8.1: version "1.8.1" @@ -5420,26 +4804,27 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-proxy-agent@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz#cc1ce38e453bf984a0f7702d2dd59c73d081284a" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: - agent-base "2" - debug "2" - extend "3" + "@tootallnate/once" "2" + agent-base "6" + debug "4" -http-proxy-middleware@0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.21.0.tgz#c6b1ca05174b5fbc57bee9485ffa0fa2f0dabeb0" - integrity sha512-4Arcl5QQ6pRMRJmtM1WVHKHkFAQn5uvw83XuNeqnMTOikDiCoTxv5/vdudhKQsF+1mtaAawrK2SEB1v2tYecdQ== +http-proxy-middleware@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== dependencies: - "@types/http-proxy" "^1.17.3" - http-proxy "^1.18.0" + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" is-glob "^4.0.1" - lodash "^4.17.15" + is-plain-obj "^3.0.0" micromatch "^4.0.2" -http-proxy@^1.18.0, http-proxy@^1.18.1: +http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== @@ -5448,18 +4833,6 @@ http-proxy@^1.18.0, http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - -https-proxy-agent@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" - dependencies: - agent-base "2" - debug "2" - extend "3" - https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -5468,11 +4841,13 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -iconv-lite@0.4.23, iconv-lite@^0.4.4: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: - safer-buffer ">= 2.1.2 < 3" + agent-base "6" + debug "4" iconv-lite@0.4.24: version "0.4.24" @@ -5480,39 +4855,32 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -icss-replace-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" - -icss-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: - postcss "^6.0.1" + safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - dependencies: - minimatch "^3.0.4" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.1.1, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -ignore@^5.1.4, ignore@^5.1.8: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.1: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== immediate@~3.0.5: version "3.0.6" @@ -5523,21 +4891,6 @@ immutable@^4.0.0: resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== -import-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= - dependencies: - import-from "^2.1.0" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - import-fresh@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" @@ -5553,13 +4906,6 @@ import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= - dependencies: - resolve-from "^3.0.0" - import-lazy@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" @@ -5569,12 +4915,6 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" @@ -5584,11 +4924,6 @@ indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -5596,30 +4931,19 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - -inherits@2.0.4: +inherits@2.0.4, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.5, ini@~1.3.0: +ini@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inject-loader@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inject-loader/-/inject-loader-2.0.1.tgz#1a7b45d60a81610459ac76079c3ce2a654d0dfc7" - integrity sha1-GntF1gqBYQRZrHYHnDziplTQ38c= - dependencies: - loader-utils "^0.2.3" - internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -5633,58 +4957,15 @@ interpret@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - dependencies: - loose-envify "^1.0.0" - ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" -ip@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.0.1.tgz#c7e356cdea225ae71b36d70f2e71a92ba4e42590" - -ip@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - dependencies: - kind-of "^6.0.0" - -is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -5696,12 +4977,6 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -5717,21 +4992,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-buffer@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" @@ -5741,6 +5001,13 @@ is-callable@^1.2.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== +is-core-module@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + is-core-module@^2.5.0, is-core-module@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" @@ -5755,93 +5022,24 @@ is-core-module@^2.8.1: dependencies: has "^1.0.3" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - dependencies: - kind-of "^6.0.0" - is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - -is-docker@^2.0.0: +is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" @@ -5855,10 +5053,10 @@ is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== is-negative-zero@^2.0.1: version "2.0.2" @@ -5872,47 +5070,45 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: +is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" -is-plain-obj@^2.0.0: +is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" dependencies: isobject "^3.0.1" -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - dependencies: - has "^1.0.1" +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-regex@^1.1.4: version "1.1.4" @@ -5922,11 +5118,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-regexp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d" - integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA== - is-shared-array-buffer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" @@ -5939,12 +5130,6 @@ is-string@^1.0.5, is-string@^1.0.7: dependencies: has-tostringtag "^1.0.0" -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" - dependencies: - html-comment-regex "^1.1.0" - is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -5958,10 +5143,6 @@ is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -5971,10 +5152,6 @@ is-url@^1.2.2: version "1.2.4" resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - is-weakref@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -5982,15 +5159,12 @@ is-weakref@^1.0.1: dependencies: call-bind "^1.0.2" -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== -is-wsl@^2.1.0: +is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -6009,7 +5183,7 @@ isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -6027,57 +5201,75 @@ iso-639-1@2.1.15: resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.15.tgz#20cf78a4f691aeb802c16f17a6bad7d99271e85d" integrity sha512-7c7mBznZu2ktfvyT582E2msM+Udc1EjOyhVRE/0ZsjD9LBtWSm23h3PtiRh2a35XoUsTQQjJXaJzuLjXsOdFDg== -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: +isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" -isparta-loader@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isparta-loader/-/isparta-loader-2.0.0.tgz#4425f496c93f765bbceb4dd938576da307566ed1" - integrity sha1-RCX0lsk/dlu8603ZOFdtowdWbtE= +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: - isparta "4.x.x" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" -isparta@4.x.x: - version "4.1.1" - resolved "https://registry.yarnpkg.com/isparta/-/isparta-4.1.1.tgz#c92e49672946914ec5407c801160f3374e0b7cb4" - dependencies: - babel-core "^6.1.4" - escodegen "^1.6.1" - esprima "^4.0.0" - istanbul "0.4.5" - mkdirp "^0.5.0" - nomnomnomnom "^2.0.0" - object-assign "^4.0.1" - source-map "^0.5.0" - which "^1.0.9" - -istanbul@0.4.5, istanbul@^0.4.0: - version "0.4.5" - resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" - dependencies: - abbrev "1.0.x" - async "1.x" - escodegen "1.8.x" - esprima "2.7.x" - glob "^5.0.15" - handlebars "^4.0.1" - js-yaml "3.x" - mkdirp "0.5.x" - nopt "3.x" - once "1.x" - resolve "1.1.x" - supports-color "^3.1.0" - which "^1.1.1" - wordwrap "^1.0.0" - -jest-worker@^27.5.1: +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jake@^10.8.5: + version "10.8.5" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" + integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.1" + minimatch "^3.0.4" + +jest-util@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.2.1.tgz#f26872ba0dc8cbefaba32c34f98935f6cf5fc747" + integrity sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g== + dependencies: + "@jest/types" "^29.2.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== @@ -6086,54 +5278,83 @@ jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -js-base64@^2.1.9: - version "2.5.0" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.0.tgz#42255ba183ab67ce59a0dee640afdc00ab5ae93e" +jest-worker@^28.0.2, jest-worker@^28.1.0: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest-worker@^29.1.2: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.2.1.tgz#8ba68255438252e1674f990f0180c54dfa26a3b1" + integrity sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg== + dependencies: + "@types/node" "*" + jest-util "^29.2.1" + merge-stream "^2.0.0" + supports-color "^8.0.0" -js-cookie@^3.0.1: +js-cookie@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414" integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw== -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +js-sdsl@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" + integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" -js-yaml@3.x: - version "3.12.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" +js-tokens@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-8.0.0.tgz#5dbe2cdfa9afc93251d3a77bf18c3ad6fa8a4de4" + integrity sha512-PC7MzqInq9OqKyTXfIvQNcjMkODJYC8A17kAaQgeW79yfhqTWSOfjHYQ2mDDcwJ96Iibtwkfh0C7R/OvqPlgVA== -js-yaml@^4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" -js-yaml@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" +jsdom@19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a" + integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A== + dependencies: + abab "^2.0.5" + acorn "^8.5.0" + acorn-globals "^6.0.0" + cssom "^0.5.0" + cssstyle "^2.3.0" + data-urls "^3.0.1" + decimal.js "^10.3.1" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + ws "^8.2.3" + xml-name-validator "^4.0.0" jsesc@^2.5.1: version "2.5.2" @@ -6149,10 +5370,15 @@ json-loader@0.5.7: resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -6166,14 +5392,6 @@ json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - -json5@^0.5.0, json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -6212,23 +5430,40 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -karma-coverage@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-1.1.2.tgz#cc09dceb589a83101aca5fe70c287645ef387689" - integrity sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw== +jszip@^3.10.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== dependencies: - dateformat "^1.0.6" - istanbul "^0.4.0" - lodash "^4.17.0" - minimatch "^3.0.0" - source-map "^0.5.1" + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" -karma-firefox-launcher@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-1.3.0.tgz#ebcbb1d1ddfada6be900eb8fae25bcf2dcdc8171" - integrity sha512-Fi7xPhwrRgr+94BnHX0F5dCl1miIW4RHnzjIGxF8GaIEp7rNqX7LSi7ok63VXs3PS/5MQaQMhGxw+bvD+pibBQ== +just-extend@^4.0.2: + version "4.2.1" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" + integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== + +karma-coverage@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.2.0.tgz#64f838b66b71327802e7f6f6c39d569b7024e40c" + integrity sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA== + dependencies: + istanbul-lib-coverage "^3.2.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.0.5" + minimatch "^3.0.4" + +karma-firefox-launcher@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz#9a38cc783c579a50f3ed2a82b7386186385cfc2d" + integrity sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA== dependencies: - is-wsl "^2.1.0" + is-wsl "^2.2.0" + which "^2.0.1" karma-mocha-reporter@2.2.5: version "2.2.5" @@ -6258,29 +5493,26 @@ karma-sourcemap-loader@0.3.8: dependencies: graceful-fs "^4.1.2" -karma-spec-reporter@0.0.34: - version "0.0.34" - resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.34.tgz#7dc79cdc76b0e37f17006921439600ae3c648669" - integrity sha512-l5H/Nh9q4g2Ysx2CDU2m+NIPyLQpCVbk9c4V02BTZHw3NM6RO1dq3eRpKXCSSdPt4RGfhHk8jDt3XYkGp+5PWg== +karma-spec-reporter@0.0.36: + version "0.0.36" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.36.tgz#c54dc155dec2ded1f92ea68dbbdd67fcedbef350" + integrity sha512-11bvOl1x6ryKZph7kmbmMpbi8vsngEGxGOoeTlIcDaH3ab3j8aPJnZ+r+K/SS0sBSGy5VGkGYO2+hLct7hw/6w== dependencies: colors "1.4.0" -karma-webpack@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-4.0.2.tgz#23219bd95bdda853e3073d3874d34447c77bced0" - integrity sha512-970/okAsdUOmiMOCY8sb17A2I8neS25Ad9uhyK3GHgmRSIFJbDcNEFE8dqqUhNe9OHiCC9k3DMrSmtd/0ymP1A== +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== dependencies: - clone-deep "^4.0.1" - loader-utils "^1.1.0" - neo-async "^2.6.1" - schema-utils "^1.0.0" - source-map "^0.7.3" - webpack-dev-middleware "^3.7.0" + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" -karma@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" - integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== +karma@6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.1.tgz#f2253716dd3a41aaa813fa9f54b6ee047e1127d9" + integrity sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA== dependencies: "@colors/colors" "1.5.0" body-parser "^1.19.0" @@ -6307,23 +5539,7 @@ karma@6.4.0: ua-parser-js "^0.7.30" yargs "^16.1.1" -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -kind-of@^6.0.0, kind-of@^6.0.2: +kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" @@ -6332,10 +5548,15 @@ kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -known-css-properties@^0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.21.0.tgz#15fbd0bbb83447f3ce09d8af247ed47c68ede80d" - integrity sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw== +klona@^2.0.4, klona@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + +known-css-properties@^0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.26.0.tgz#008295115abddc045a9f4ed7e2a84dc8b3a77649" + integrity sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg== levn@^0.4.1: version "0.4.1" @@ -6348,6 +5569,7 @@ levn@^0.4.1: levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" @@ -6358,36 +5580,29 @@ lie@3.1.1: dependencies: immediate "~3.0.5" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +lilconfig@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" + integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-utils@^0.2.16, loader-utils@^0.2.3: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0: +loader-utils@^1.0.2: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" dependencies: @@ -6395,15 +5610,6 @@ loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0: emojis-list "^2.0.0" json5 "^1.0.1" -loader-utils@^1.2.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - loader-utils@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" @@ -6441,6 +5647,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash._arraycopy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" @@ -6476,18 +5689,10 @@ lodash._baseclone@^3.0.0: lodash.isarray "^3.0.0" lodash.keys "^3.0.0" -lodash._baseclone@^4.0.0: - version "4.5.7" - resolved "https://registry.yarnpkg.com/lodash._baseclone/-/lodash._baseclone-4.5.7.tgz#ce42ade08384ef5d62fa77c30f61a46e686f8434" - lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" - lodash._baseeach@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash._baseeach/-/lodash._baseeach-3.0.4.tgz#cf8706572ca144e8d9d75227c990da982f932af3" @@ -6530,17 +5735,9 @@ lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - -lodash._stack@^4.0.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lodash._stack/-/lodash._stack-4.1.3.tgz#751aa76c1b964b047e76d14fc72a093fcb5e2dd0" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" lodash.clone@3.0.3: version "3.0.3" @@ -6550,29 +5747,20 @@ lodash.clone@3.0.3: lodash._bindcallback "^3.0.0" lodash._isiterateecall "^3.0.0" -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.defaultsdeep@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.3.2.tgz#6c1a586e6c5647b0e64e2d798141b8836158be8a" - dependencies: - lodash._baseclone "^4.0.0" - lodash._stack "^4.0.0" - lodash.isplainobject "^4.0.0" - lodash.keysin "^4.0.0" - lodash.mergewith "^4.0.0" - lodash.rest "^4.0.0" +lodash.defaultsdeep@4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + +lodash.escape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + integrity sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw== lodash.find@^3.2.1: version "3.2.1" @@ -6585,6 +5773,11 @@ lodash.find@^3.2.1: lodash.isarray "^3.0.0" lodash.keys "^3.0.0" +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -6610,10 +5803,6 @@ lodash.isplainobject@^3.0.0, lodash.isplainobject@^3.2.0: lodash.isarguments "^3.0.0" lodash.keysin "^3.0.0" -lodash.isplainobject@^4.0.0: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - lodash.istypedarray@^3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62" @@ -6633,13 +5822,15 @@ lodash.keysin@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash.keysin@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.keysin/-/lodash.keysin-4.2.0.tgz#8cc3fb35c2d94acc443a1863e02fa40799ea6f28" - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.merge@4.6.2, lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.merge@^3.3.2: version "3.3.2" @@ -6657,24 +5848,16 @@ lodash.merge@^3.3.2: lodash.keysin "^3.0.0" lodash.toplainobject "^3.0.0" -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.mergewith@^4.0.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - lodash.pairs@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash.pairs/-/lodash.pairs-3.0.1.tgz#bbe08d5786eeeaa09a15c91ebf0dcb7d2be326a9" dependencies: lodash.keys "^3.0.0" -lodash.rest@^4.0.0: - version "4.0.5" - resolved "https://registry.yarnpkg.com/lodash.rest/-/lodash.rest-4.0.5.tgz#954ef75049262038c96d1fc98b28fdaf9f0772aa" +lodash.pick@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== lodash.restparam@^3.0.0: version "3.6.1" @@ -6695,13 +5878,14 @@ lodash.truncate@^4.4.2: lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@4.17.21, lodash@^4.17.20, lodash@^4.17.21: +lodash@4.17.21, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4: +lodash@^4.17.10: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -6710,10 +5894,13 @@ lodash@^4.17.13: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -lodash@^4.17.15: - version "4.17.19" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" - integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== +log-symbols@4.1.0, log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" log-symbols@^1.0.2: version "1.0.2" @@ -6727,14 +5914,6 @@ log-symbols@^2.1.0: dependencies: chalk "^2.0.1" -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - log4js@^6.4.1: version "6.4.4" resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.4.tgz#c9bc75569f3f40bba22fe1bd0677afa7a6a13bac" @@ -6746,43 +5925,24 @@ log4js@^6.4.1: rfdc "^1.3.0" streamroller "^3.0.6" -lolex@1.6.0, lolex@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" - integrity sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY= - -longest-streak@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" - integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" +loupe@2.3.4, loupe@^2.3.1: + version "2.3.4" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" + integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + get-func-name "^2.0.0" -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" + tslib "^2.0.3" lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" @@ -6793,10 +5953,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@~2.6.5: - version "2.6.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5" - magic-string@^0.25.7: version "0.25.9" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" @@ -6811,18 +5967,14 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.2, make-dir@^3.1.0: +make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -map-obj@^1.0.0, map-obj@^1.0.1: +map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -6831,56 +5983,15 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" integrity sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g== -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - dependencies: - object-visit "^1.0.0" - -math-expression-evaluator@^1.2.14: - version "1.2.17" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" - mathml-tag-names@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3" integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg== -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdast-util-from-markdown@^0.8.0: - version "0.8.5" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" - integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-string "^2.0.0" - micromark "~2.11.0" - parse-entities "^2.0.0" - unist-util-stringify-position "^2.0.0" - -mdast-util-to-markdown@^0.6.0: - version "0.6.5" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe" - integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ== - dependencies: - "@types/unist" "^2.0.0" - longest-streak "^2.0.0" - mdast-util-to-string "^2.0.0" - parse-entities "^2.0.0" - repeat-string "^1.0.0" - zwitch "^1.0.0" - -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== media-typer@0.3.0: version "0.3.0" @@ -6893,29 +6004,6 @@ memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - meow@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364" @@ -6952,32 +6040,6 @@ methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" -micromark@~2.11.0: - version "2.11.4" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" - integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== - dependencies: - debug "^4.0.0" - parse-entities "^2.0.0" - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - micromatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" @@ -6994,13 +6056,6 @@ micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - mime-db@1.40.0: version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" @@ -7010,7 +6065,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -7028,10 +6083,6 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.0.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.3.tgz#229687331e86f68924e6cb59e1cdd937f18275fe" - mime@^2.4.4, mime@^2.5.2: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" @@ -7041,48 +6092,57 @@ mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -mini-css-extract-plugin@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.12.0.tgz#ddeb74fd6304ca9f99c1db74acc7d5b507705454" - integrity sha512-z6PQCe9rd1XUwZ8gMaEVwwRyZlrYy8Ba1gRjFP5HcV51HkXX+XlwZ+a1iAYTjSYwgNBXoNR7mhx79mDpOn5fdw== +mini-css-extract-plugin@2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz#e049d3ea7d3e4e773aad585c6cb329ce0c7b72d7" + integrity sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw== dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + schema-utils "^4.0.0" -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" +minimatch@3.1.2, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== dependencies: brace-expansion "^1.1.7" -minimatch@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: - brace-expansion "^1.0.0" + brace-expansion "^2.0.1" -minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + dependencies: + brace-expansion "^2.0.1" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -7092,165 +6152,102 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@0.0.8, minimist@~0.0.1: +minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -minimist@^1.2.3, minimist@^1.2.6: +minimist@1.2.6, minimist@^1.2.3, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== - dependencies: - yallist "^4.0.0" - -minizlib@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - dependencies: - minipass "^2.2.1" - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" +mitt@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230" + integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg== -mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" -mkdirp@^0.5.3, mkdirp@^0.5.5: +mkdirp@^0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - mkpath@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-1.0.0.tgz#ebb3a977e7af1c683ae6fda12b545a6ba6c5853d" -mocha-nightwatch@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/mocha-nightwatch/-/mocha-nightwatch-3.2.2.tgz#91bcb9b3bde057dd7677c78125e491e58d66647c" - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.2.0" - diff "1.4.0" - escape-string-regexp "1.0.5" - glob "7.0.5" - growl "1.9.2" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - -mocha@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" - integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.6.8" - diff "3.2.0" - escape-string-regexp "1.0.5" - glob "7.1.1" - growl "1.9.2" - he "1.1.1" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" +mocha@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mocha@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "4.2.1" + ms "2.1.3" + nanoid "3.3.1" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" ms@2.0.0: version "2.0.0" @@ -7270,47 +6267,25 @@ ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - -nanoid@^3.3.1: +nanoid@3.3.1, nanoid@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== -native-promise-only@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -7320,129 +6295,81 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - -neo-async@^2.6.1: +neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -netmask@~1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" - -nightwatch@0.9.21: - version "0.9.21" - resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-0.9.21.tgz#9e794a7514b4fd5f46602d368e50515232ab9e90" - integrity sha1-nnlKdRS0/V9GYC02jlBRUjKrnpA= - dependencies: - chai-nightwatch "~0.1.x" - ejs "2.5.7" +nightwatch-axe-verbose@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nightwatch-axe-verbose/-/nightwatch-axe-verbose-2.1.0.tgz#3a03f70dd9b78739a5178ee096a24e0658a8ee53" + integrity sha512-j31VB0wdv/HXoQWWAJsvNc9UenXzXf1u/QsvExCUDuFOMR4GRg3963wlPIxd2ME47egXsnkXPd1dl8Ozdk7XHA== + dependencies: + axe-core "^4.6.1" + +nightwatch@2.6.10: + version "2.6.10" + resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-2.6.10.tgz#eda82a6a0ff0002fdbeb9d160938d3c53a92dd88" + integrity sha512-nn5HVEtETLQ8qgu7APAZKg/yXTBkMflwdmzhfywP8mZUfKk0/dRQbeDqY2RawHr/sYsFmZV6eMirlJaaQoQ7Yw== + dependencies: + "@nightwatch/chai" "5.0.2" + "@nightwatch/html-reporter-template" "0.1.4" + ansi-to-html "0.7.2" + assertion-error "1.1.0" + boxen "5.1.2" + chai-nightwatch "0.5.3" + ci-info "3.3.0" + cli-table3 "^0.6.3" + didyoumean "1.2.2" + dotenv "10.0.0" + ejs "3.1.8" + envinfo "7.8.1" + fs-extra "^10.1.0" + glob "^7.2.3" + jsdom "19.0.0" lodash.clone "3.0.3" - lodash.defaultsdeep "4.3.2" - minimatch "3.0.3" + lodash.defaultsdeep "4.6.1" + lodash.escape "4.0.1" + lodash.merge "4.6.2" + lodash.pick "4.4.0" + minimatch "3.1.2" + minimist "1.2.6" mkpath "1.0.0" - mocha-nightwatch "3.2.2" - optimist "0.6.1" - proxy-agent "2.0.0" - q "1.4.1" - -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + mocha "9.2.2" + nightwatch-axe-verbose "^2.1.0" + open "8.4.0" + ora "5.4.1" + selenium-webdriver "4.6.1" + semver "7.3.5" + stacktrace-parser "0.1.10" + strip-ansi "6.0.1" + untildify "^4.0.0" + uuid "8.3.2" + +nise@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.2.tgz#a7b8909c216b3491fd4fc0b124efb69f3939b449" + integrity sha512-+gQjFi8v+tkfCuSCxfURHLhRhniE/+IaYbIphxAN2JRR9SHKhY8hgXpaXiYfHdw+gcGe4buxgbprBQFab9FkhA== dependencies: - lower-case "^1.1.1" + "@sinonjs/commons" "^2.0.0" + "@sinonjs/fake-timers" "^7.0.4" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + path-to-regexp "^1.7.0" -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -node-releases@^1.1.58: - version "1.1.60" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" - integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== - -node-releases@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" - integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" node-releases@^2.0.5, node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== -nomnomnomnom@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/nomnomnomnom/-/nomnomnomnom-2.0.1.tgz#b2239f031c8d04da67e32836e1e3199e12f7a8e2" - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -7463,12 +6390,6 @@ normalize-package-data@^3.0.0: semver "^7.3.4" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -7477,39 +6398,10 @@ normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" -normalize-selector@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" - integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM= - -normalize-url@1.9.1, normalize-url@^1.4.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -npm-bundled@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" - -npm-packlist@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== nth-check@^2.0.1: version "2.1.1" @@ -7518,57 +6410,24 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - dependencies: - boolbase "~1.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" +nwsapi@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" + integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - object-inspect@^1.11.0, object-inspect@^1.9.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" @@ -7579,19 +6438,6 @@ object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - dependencies: - isobject "^3.0.1" - object.values@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" @@ -7614,7 +6460,7 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -7626,31 +6472,40 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -opn@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" - integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" + mimic-fn "^2.1.0" -optimist@0.6.1, optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" +open@8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +opn@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" + is-wsl "^1.1.0" optionator@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: deep-is "~0.1.3" - fast-levenshtein "~2.0.4" + fast-levenshtein "~2.0.6" levn "~0.3.0" prelude-ls "~1.1.2" type-check "~0.3.2" - wordwrap "~1.0.0" + word-wrap "~1.2.3" optionator@^0.9.1: version "0.9.1" @@ -7674,24 +6529,20 @@ ora@0.4.1: cli-spinners "^1.0.0" log-symbols "^1.0.2" -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" +ora@5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" p-limit@^1.1.0: version "1.3.0" @@ -7738,12 +6589,12 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: - aggregate-error "^3.0.0" + p-limit "^3.0.2" p-try@^1.0.0: version "1.0.0" @@ -7753,47 +6604,18 @@ p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" -pac-proxy-agent@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d" - dependencies: - agent-base "2" - debug "2" - extend "3" - get-uri "2" - http-proxy-agent "1" - https-proxy-agent "1" - pac-resolver "~2.0.0" - raw-body "2" - socks-proxy-agent "2" - -pac-resolver@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-2.0.0.tgz#99b88d2f193fbdeefc1c9a529c1f3260ab5277cd" - dependencies: - co "~3.0.6" - degenerator "~1.0.2" - ip "1.0.1" - netmask "~1.0.4" - thunkify "~2.1.1" - -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - -parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - dependencies: - cyclist "~0.2.2" - inherits "^2.0.3" - readable-stream "^2.1.5" +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== dependencies: - no-case "^2.2.0" + dot-case "^3.0.4" + tslib "^2.0.3" parent-module@^1.0.0: version "1.0.1" @@ -7801,43 +6623,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0: - version "5.1.4" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse-json@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.1.tgz#7cfe35c1ccd641bce3981467e6c2ece61b3b3878" @@ -7848,36 +6633,30 @@ parse-json@^5.0.0: json-parse-better-errors "^1.0.1" lines-and-columns "^1.1.6" -parse-link-header@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-link-header/-/parse-link-header-1.0.1.tgz#bedfe0d2118aeb84be75e7b025419ec8a61140a7" - integrity sha1-vt/g0hGK64S+deewJUGeyKYRQKc= +parse-link-header@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-link-header/-/parse-link-header-2.0.0.tgz#949353e284f8aa01f2ac857a98f692b57733f6b7" + integrity sha512-xjU87V0VyHZybn2RrCX5TIFGxTVZE6zqqZWMPlIKiSKuWh/X5WZdt+w1Ki1nXB+8L/KtL+nZ4iq+sfI6MrhhMw== dependencies: xtend "~4.0.1" +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== dependencies: - pinkie-promise "^2.0.0" + no-case "^3.0.4" + tslib "^2.0.3" path-exists@^3.0.0: version "3.0.0" @@ -7888,7 +6667,7 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -7916,28 +6695,15 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" +pathval@1.1.1, pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== pend@~1.2.0: version "1.2.0" @@ -7948,11 +6714,6 @@ phoenix@1.6.2: resolved "https://registry.yarnpkg.com/phoenix/-/phoenix-1.6.2.tgz#8d1d9f06e51cb893d08059e80488cd0de328e01a" integrity sha512-VjR27NETvrLSj8rI6DlpVAfo7pCYth/9+1OCoTof4LKEbq0141ze/tdxFHHZzVQSok3gqJUo2h/tqbxR3r8eyw== -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -7968,29 +6729,15 @@ picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -picomatch@^2.3.1: +picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - pirates@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -8019,264 +6766,254 @@ pointer-tracker@^2.0.3: resolved "https://registry.yarnpkg.com/pointer-tracker/-/pointer-tracker-2.4.0.tgz#78721c2d2201486db11ec1094377f03023b621b3" integrity sha512-pWI2tpaM/XNtc9mUTv42Rmjf6mkHvE8LT5DDEq0G7baPNhxNM9E3CepubPplSoSLk9E5bwQrAMyDcPVmJyTW4g== -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" +postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" -postcss-colormin@^2.1.8: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" +postcss-colormin@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" + integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" -postcss-convert-values@^2.3.4: - version "2.6.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" +postcss-convert-values@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" + integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" + browserslist "^4.20.3" + postcss-value-parser "^4.2.0" -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" - dependencies: - postcss "^5.0.14" +postcss-discard-comments@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" + integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== -postcss-discard-duplicates@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" - dependencies: - postcss "^5.0.4" +postcss-discard-duplicates@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== -postcss-discard-empty@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" - dependencies: - postcss "^5.0.14" +postcss-discard-empty@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" - dependencies: - postcss "^5.0.16" +postcss-discard-overridden@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== -postcss-discard-unused@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" +postcss-html@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-1.5.0.tgz#57a43bc9e336f516ecc448a37d2e8c2290170a6f" + integrity sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA== dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" + htmlparser2 "^8.0.0" + js-tokens "^8.0.0" + postcss "^8.4.0" + postcss-safe-parser "^6.0.0" -postcss-filter-plugins@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz#82245fdf82337041645e477114d8e593aa18b8ec" +postcss-loader@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.0.2.tgz#b53ff44a26fba3688eee92a048c7f2d4802e23bb" + integrity sha512-fUJzV/QH7NXUAqV8dWJ9Lg4aTkDCezpTS5HgJ2DvqznexTbSTxgi/dTECvTZ15BwKTtk8G/bqI/QTu2HPd3ZCg== dependencies: - postcss "^5.0.4" + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.8" -postcss-html@^0.36.0: - version "0.36.0" - resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-0.36.0.tgz#b40913f94eaacc2453fd30a1327ad6ee1f88b204" - integrity sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw== - dependencies: - htmlparser2 "^3.10.0" +postcss-media-query-parser@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" + integrity sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ= -postcss-less@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-3.1.4.tgz#369f58642b5928ef898ffbc1a6e93c958304c5ad" - integrity sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA== +postcss-merge-longhand@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" + integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== dependencies: - postcss "^7.0.14" + postcss-value-parser "^4.2.0" + stylehacks "^5.1.0" -postcss-load-config@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" - integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== +postcss-merge-rules@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" + integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== dependencies: - cosmiconfig "^5.0.0" - import-cwd "^2.0.0" + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" -postcss-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" - integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== +postcss-minify-font-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== dependencies: - loader-utils "^1.1.0" - postcss "^7.0.0" - postcss-load-config "^2.0.0" - schema-utils "^1.0.0" - -postcss-media-query-parser@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" - integrity sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ= + postcss-value-parser "^4.2.0" -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" +postcss-minify-gradients@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" + integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" -postcss-merge-longhand@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" +postcss-minify-params@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" + integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== dependencies: - postcss "^5.0.4" + browserslist "^4.16.6" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" -postcss-merge-rules@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" +postcss-minify-selectors@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" + integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== dependencies: - browserslist "^1.5.2" - caniuse-api "^1.5.2" - postcss "^5.0.4" - postcss-selector-parser "^2.2.2" - vendors "^1.0.0" + postcss-selector-parser "^6.0.5" -postcss-message-helpers@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" + postcss-selector-parser "^6.0.4" -postcss-minify-params@^1.0.4: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" - uniqs "^2.0.0" + icss-utils "^5.0.0" -postcss-minify-selectors@^2.0.4: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" +postcss-normalize-charset@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + +postcss-normalize-display-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-modules-extract-imports@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" +postcss-normalize-positions@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== dependencies: - postcss "^6.0.1" + postcss-value-parser "^4.2.0" -postcss-modules-local-by-default@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" +postcss-normalize-repeat-style@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" + postcss-value-parser "^4.2.0" -postcss-modules-scope@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" +postcss-normalize-string@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" + postcss-value-parser "^4.2.0" -postcss-modules-values@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" +postcss-normalize-timing-functions@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== dependencies: - icss-replace-symbols "^1.1.0" - postcss "^6.0.1" + postcss-value-parser "^4.2.0" -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" +postcss-normalize-unicode@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" + integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== dependencies: - postcss "^5.0.5" + browserslist "^4.16.6" + postcss-value-parser "^4.2.0" -postcss-normalize-url@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" +postcss-normalize-url@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== dependencies: - is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" -postcss-ordered-values@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" +postcss-normalize-whitespace@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" + postcss-value-parser "^4.2.0" -postcss-reduce-idents@^2.2.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" +postcss-ordered-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" -postcss-reduce-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" +postcss-reduce-initial@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" + integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== dependencies: - postcss "^5.0.4" + browserslist "^4.16.6" + caniuse-api "^3.0.0" -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" +postcss-reduce-transforms@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" + postcss-value-parser "^4.2.0" postcss-resolve-nested-selector@0.1.1, postcss-resolve-nested-selector@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" integrity sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4= -postcss-safe-parser@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" - integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== - dependencies: - postcss "^7.0.26" - -postcss-sass@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.4.4.tgz#91f0f3447b45ce373227a98b61f8d8f0785285a3" - integrity sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg== - dependencies: - gonzales-pe "^4.3.0" - postcss "^7.0.21" +postcss-safe-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1" + integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ== -postcss-scss@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.1.1.tgz#ec3a75fa29a55e016b90bf3269026c53c1d2b383" - integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA== - dependencies: - postcss "^7.0.6" +postcss-scss@^4.0.2, postcss-scss@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.6.tgz#5d62a574b950a6ae12f2aa89b60d63d9e4432bfd" + integrity sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ== postcss-selector-parser@2.2.1: version "2.2.1" @@ -8287,15 +7024,15 @@ postcss-selector-parser@2.2.1: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.6: + version "6.0.11" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" + integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" + cssesc "^3.0.0" + util-deprecate "^1.0.2" -postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.0.10" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== @@ -8303,87 +7040,39 @@ postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-svgo@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" +postcss-svgo@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" - -postcss-syntax@^0.36.2: - version "0.36.2" - resolved "https://registry.yarnpkg.com/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c" - integrity sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w== + postcss-value-parser "^4.2.0" + svgo "^2.7.0" -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" +postcss-unique-selectors@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + postcss-selector-parser "^6.0.5" postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss-zindex@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" - dependencies: - has "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16: - version "5.2.18" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.2.3" - -postcss@^6.0.1: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - -postcss@^7.0.0: - version "7.0.17" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" - integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.6: - version "7.0.32" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" - integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^7.0.35: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== +postcss@8.4.20, postcss@^8.4.19: + version "8.4.20" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" + integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g== dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" postcss@^8.1.10: version "8.4.12" @@ -8394,6 +7083,24 @@ postcss@^8.1.10: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.0: + version "8.4.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" + integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.4.17: + version "8.4.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.18.tgz#6d50046ea7d3d66a85e0e782074e7203bc7fbca2" + integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -8402,34 +7109,20 @@ prelude-ls@^1.2.1: prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - -pretty-error@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== dependencies: - renderkid "^2.0.1" - utila "~0.4" - -private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + lodash "^4.17.20" + renderkid "^3.0.0" process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -8438,19 +7131,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-agent@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-2.0.0.tgz#57eb5347aa805d74ec681cb25649dba39c933499" - dependencies: - agent-base "2" - debug "2" - extend "3" - http-proxy-agent "1" - https-proxy-agent "1" - lru-cache "~2.6.5" - pac-proxy-agent "1" - socks-proxy-agent "2" - proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -8460,27 +7140,10 @@ prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== pump@^3.0.0: version "3.0.0" @@ -8489,14 +7152,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - punycode.js@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.1.0.tgz#f3937f7a914152c2dc17e9c280a2cf86a26b7cda" @@ -8505,25 +7160,18 @@ punycode.js@2.1.0: punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== -punycode@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" -q@1.4.1, q@^1.1.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" - qjobs@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== -qrcode@1: +qrcode@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.0.tgz#95abb8a91fdafd86f8190f2836abbfc500c72d1b" integrity sha512-9MgRpgVc+/+47dFvQeD6U2s0Z92EsKzcHogtum4QB+UNd025WOJSHvn/hjk9xmzj7Stj95CyUAs31mrjxliEsQ== @@ -8533,10 +7181,10 @@ qrcode@1: pngjs "^5.0.0" yargs "^15.3.1" -qs@6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" @@ -8545,54 +7193,38 @@ qs@6.9.7: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@^0.2.0: +querystring-es3@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== -querystring@0.2.0, querystring@^0.2.0: +querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: +randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" - dependencies: - bytes "3.0.0" - http-errors "1.6.3" - iconv-lite "0.4.23" - unpipe "1.0.0" - raw-body@2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" @@ -8613,27 +7245,6 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -raw-loader@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" - integrity sha1-DD0L6u2KAclm2Xh793goElKpeao= - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -8643,14 +7254,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" @@ -8661,7 +7264,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@^2.0.1: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -8673,25 +7276,7 @@ read-pkg@^5.2.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@1.0: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@1.1.x: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^3.1.1: +readable-stream@^3.4.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -8700,20 +7285,18 @@ readable-stream@^3.1.1: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== +readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: - picomatch "^2.2.1" + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" readdirp@~3.6.0: version "3.6.0" @@ -8728,13 +7311,6 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -8743,20 +7319,6 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -reduce-css-calc@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" - dependencies: - balanced-match "^0.4.2" - math-expression-evaluator "^1.2.14" - reduce-function-call "^1.0.1" - -reduce-function-call@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" - dependencies: - balanced-match "^0.4.2" - regenerate-unicode-properties@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" @@ -8764,18 +7326,15 @@ regenerate-unicode-properties@^10.0.1: dependencies: regenerate "^1.4.2" -regenerate@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== regenerator-runtime@^0.13.4: version "0.13.9" @@ -8787,28 +7346,13 @@ regenerator-transform@^0.15.0: resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== dependencies: - "@babel/runtime" "^7.8.4" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" + "@babel/runtime" "^7.8.4" regexpp@^3.0.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regexpu-core@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - regexpu-core@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" @@ -8833,21 +7377,11 @@ regexpu-core@^5.1.0: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - regjsgen@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - regjsparser@^0.8.2: version "0.8.4" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" @@ -8855,65 +7389,21 @@ regjsparser@^0.8.2: dependencies: jsesc "~0.5.0" -relateurl@0.2.x: +relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== -remark-parse@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" - integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== - dependencies: - mdast-util-from-markdown "^0.8.0" - -remark-stringify@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-9.0.1.tgz#576d06e910548b0a7191a71f27b33f1218862894" - integrity sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg== - dependencies: - mdast-util-to-markdown "^0.6.0" - -remark@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/remark/-/remark-13.0.0.tgz#d15d9bf71a402f40287ebe36067b66d54868e425" - integrity sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA== - dependencies: - remark-parse "^9.0.0" - remark-stringify "^9.0.0" - unified "^9.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -renderkid@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.2.tgz#12d310f255360c07ad8fde253f6c9e9de372d2aa" - dependencies: - css-select "^1.1.0" - dom-converter "~0.2" - htmlparser2 "~3.3.0" - strip-ansi "^3.0.0" - utila "^0.4.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - -repeat-string@^1.0.0, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== dependencies: - is-finite "^1.0.0" - -replace-ext@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" require-directory@^2.1.1: version "2.1.1" @@ -8937,11 +7427,6 @@ requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -8951,11 +7436,7 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - -resolve@1.1.x, resolve@^1.1.6: +resolve@^1.1.6: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -8965,15 +7446,6 @@ resolve@^1.10.0: dependencies: path-parse "^1.0.6" -resolve@^1.10.1, resolve@^1.22.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - resolve@^1.14.2, resolve@^1.20.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" @@ -8983,6 +7455,15 @@ resolve@^1.14.2, resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.0, resolve@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -8990,9 +7471,13 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" reusify@^1.0.4: version "1.0.4" @@ -9004,19 +7489,6 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.5.4, rimraf@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - dependencies: - glob "^7.1.3" - -rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -9024,98 +7496,49 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - run-parallel@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - dependencies: - aproba "^1.1.1" - safe-buffer@5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -samsam@1.x, samsam@^1.1.3: - version "1.3.0" - resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" - -sass-loader@7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.3.1.tgz#a5bf68a04bcea1c13ff842d747150f7ab7d0d23f" - integrity sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA== +sass-loader@13.2.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.2.0.tgz#80195050f58c9aac63b792fa52acb6f5e0f6bdc3" + integrity sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg== dependencies: - clone-deep "^4.0.1" - loader-utils "^1.0.1" - neo-async "^2.5.0" - pify "^4.0.1" - semver "^6.3.0" + klona "^2.0.4" + neo-async "^2.6.2" -sass@1.54.0: - version "1.54.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.0.tgz#24873673265e2a4fe3d3a997f714971db2fba1f4" - integrity sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ== +sass@1.57.1: + version "1.57.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.57.1.tgz#dfafd46eb3ab94817145e8825208ecf7281119b5" + integrity sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -sax@^1.2.4, sax@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - -schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: - "@types/json-schema" "^7.0.6" - ajv "^6.12.5" - ajv-keywords "^3.5.2" + xmlchars "^2.2.0" -schema-utils@^3.1.1: +schema-utils@^3.1.0, schema-utils@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== @@ -9124,40 +7547,59 @@ schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + selenium-server@2.53.1: version "2.53.1" resolved "https://registry.yarnpkg.com/selenium-server/-/selenium-server-2.53.1.tgz#d681528812f3c2e0531a6b7e613e23bb02cce8a6" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.6.0: +selenium-webdriver@4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.6.1.tgz#ac66867206542a40c24b5a44f4ccbae992e962dc" + integrity sha512-FT8Dw0tbzaTp8YYLuwhaCnve/nw03HKrOJrA3aUmTKmxaIFSP4kT2R5fN3K0RpV5kbR0ZnM4FGVI2vANBvekaA== + dependencies: + jszip "^3.10.0" + tmp "^0.2.1" + ws ">=8.7.0" + +"semver@2 || 3 || 4 || 5", semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" -semver@5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.3.8, semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7: +semver@^7.0.0, semver@^7.3.4, semver@^7.3.5, semver@^7.3.6: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -semver@~5.0.1: - version "5.0.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -9177,17 +7619,10 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== dependencies: randombytes "^2.1.0" @@ -9201,56 +7636,27 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" -serviceworker-webpack-plugin@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-1.0.1.tgz#481863288487e92da01d49745336c72ef8a6136b" - integrity sha512-VgDEkZ3pA0HajsRaWtl5w6bLxAXx0Y+4dm7YeTcIxVmvC9YXvstex38HOBDuYETeDS5fUlBy/47gC0QYBrG0nw== +serviceworker-webpack5-plugin@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/serviceworker-webpack5-plugin/-/serviceworker-webpack5-plugin-2.0.0.tgz#6d3516b11fcf3cfadee60f04d607e7d042e3e7fc" + integrity sha512-lMypbP8MQiWeUa2Za1BfV9M18aXQCoB71XaeL6v32qxvdTCqILv2cxDNW1Mlq/tHJ8hgKlP3INQ2eo2BLaHyZQ== dependencies: minimatch "^3.0.4" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: +setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -9287,38 +7693,42 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2: +signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon-chai@2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.14.0.tgz#da7dd4cc83cd6a260b67cca0f7a9fdae26a1205d" - integrity sha512-9stIF1utB0ywNHNT7RgiXbdmen8QDCRsrTjw+G9TgKt1Yexjiv8TOWZ6WHsTPz57Yky3DIswZvEqX8fpuHNDtQ== +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -sinon@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.4.1.tgz#021fd64b54cb77d9d2fb0d43cdedfae7629c3a36" - integrity sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw== - dependencies: - diff "^3.1.0" - formatio "1.2.0" - lolex "^1.6.0" - native-promise-only "^0.8.1" - path-to-regexp "^1.7.0" - samsam "^1.1.3" - text-encoding "0.6.4" - type-detect "^4.0.0" +sinon-chai@3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783" + integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g== -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +sinon@15.0.1: + version "15.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-15.0.1.tgz#ce062611a0b131892e2c18f03055b8eb6e8dc234" + integrity sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg== + dependencies: + "@sinonjs/commons" "^2.0.0" + "@sinonjs/fake-timers" "10.0.2" + "@sinonjs/samsam" "^7.0.1" + diff "^5.0.0" + nise "^5.1.2" + supports-color "^7.2.0" slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -9328,37 +7738,6 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -smart-buffer@^1.0.13: - version "1.1.15" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - socket.io-adapter@~2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" @@ -9385,52 +7764,11 @@ socket.io@^4.4.1: socket.io-adapter "~2.4.0" socket.io-parser "~4.0.4" -socks-proxy-agent@2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3" - dependencies: - agent-base "2" - extend "3" - socks "~1.1.5" - -socks@~1.1.5: - version "1.1.10" - resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" - dependencies: - ip "^1.1.4" - smart-buffer "^1.0.13" - -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - source-map-support@^0.5.16: version "0.5.16" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" @@ -9439,37 +7777,22 @@ source-map-support@^0.5.16: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@~0.5.12: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" -source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -source-map@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - dependencies: - amdefine ">=0.0.4" - sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" @@ -9497,83 +7820,28 @@ spdx-license-ids@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" -specificity@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019" - integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - dependencies: - figgy-pudding "^3.5.1" - -ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" +stacktrace-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" + type-fest "^0.7.1" statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"statuses@>= 1.4.0 < 2": - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - streamroller@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.6.tgz#52823415800ded79a49aa3f7712f50a422b97493" @@ -9583,26 +7851,7 @@ streamroller@^3.0.6: debug "^4.3.4" fs-extra "^10.0.1" -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^4.1.0, string-width@^4.2.2, string-width@^4.2.3: +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -9636,12 +7885,6 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string_decoder@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - dependencies: - safe-buffer "~5.1.0" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -9649,10 +7892,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -9666,7 +7905,14 @@ strip-ansi@5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: +strip-ansi@6.0.1, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" dependencies: @@ -9685,33 +7931,10 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -9719,31 +7942,58 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - style-search@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI= -stylelint-config-recommended@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz#e0e547434016c5539fe2650afd58049a2fd1d657" - integrity sha512-F6yTRuc06xr1h5Qw/ykb2LuFynJ2IxkKfCMf+1xqPffkxh0S09Zc902XCffcsw/XMFq/OzQ1w54fLIDtmRNHnQ== +stylehacks@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" + integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== + dependencies: + browserslist "^4.16.6" + postcss-selector-parser "^6.0.4" + +stylelint-config-html@>=1.0.0, stylelint-config-html@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz#999db19aea713b7ff6dde92ada76e4c1bd812b66" + integrity sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ== + +stylelint-config-recommended-scss@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-8.0.0.tgz#1c1e93e619fe2275d4c1067928d92e0614f7d64f" + integrity sha512-BxjxEzRaZoQb7Iinc3p92GS6zRdRAkIuEu2ZFLTxJK2e1AIcCb5B5MXY9KOXdGTnYFZ+KKx6R4Fv9zU6CtMYPQ== + dependencies: + postcss-scss "^4.0.2" + stylelint-config-recommended "^9.0.0" + stylelint-scss "^4.0.0" + +stylelint-config-recommended-vue@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended-vue/-/stylelint-config-recommended-vue-1.4.0.tgz#0a182da17dc9e846e4bec65a7676ccf882b35964" + integrity sha512-DVJqyX2KvMCn9U0+keL12r7xlsH26K4Vg8NrIZuq5MoF7g82DpMp326Om4E0Q+Il1o+bTHuUyejf2XAI0iD04Q== + dependencies: + semver "^7.3.5" + stylelint-config-html ">=1.0.0" + stylelint-config-recommended ">=6.0.0" + +stylelint-config-recommended@>=6.0.0, stylelint-config-recommended@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz#1c9e07536a8cd875405f8ecef7314916d94e7e40" + integrity sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ== -stylelint-config-standard@20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-20.0.0.tgz#06135090c9e064befee3d594289f50e295b5e20d" - integrity sha512-IB2iFdzOTA/zS4jSVav6z+wGtin08qfj+YyExHB3LF9lnouQht//YyB0KZq9gGz5HNPkddHOzcY8HsUey6ZUlA== +stylelint-config-standard@29.0.0: + version "29.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz#4cc0e0f05512a39bb8b8e97853247d3a95d66fa2" + integrity sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg== dependencies: - stylelint-config-recommended "^3.0.0" + stylelint-config-recommended "^9.0.0" stylelint-rscss@0.4.0: version "0.4.0" @@ -9753,94 +8003,95 @@ stylelint-rscss@0.4.0: postcss-resolve-nested-selector "0.1.1" postcss-selector-parser "2.2.1" -stylelint@13.13.1: - version "13.13.1" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.13.1.tgz#fca9c9f5de7990ab26a00f167b8978f083a18f3c" - integrity sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ== +stylelint-scss@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.3.0.tgz#638800faf823db11fff60d537c81051fe74c90fa" + integrity sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ== + dependencies: + lodash "^4.17.21" + postcss-media-query-parser "^0.2.3" + postcss-resolve-nested-selector "^0.1.1" + postcss-selector-parser "^6.0.6" + postcss-value-parser "^4.1.0" + +stylelint-webpack-plugin@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stylelint-webpack-plugin/-/stylelint-webpack-plugin-3.3.0.tgz#3ba40e2b2b2b7d1802fa53618e01fc28bc21ffb3" + integrity sha512-F53bapIZ9zI16ero8IWm6TrUE6SSibZBphJE9b5rR2FxtvmGmm1YmS+a5xjQzn63+cv71GVSCu4byX66fBLpEw== + dependencies: + globby "^11.1.0" + jest-worker "^28.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + +stylelint@14.16.1: + version "14.16.1" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.16.1.tgz#b911063530619a1bbe44c2b875fd8181ebdc742d" + integrity sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A== dependencies: - "@stylelint/postcss-css-in-js" "^0.37.2" - "@stylelint/postcss-markdown" "^0.36.2" - autoprefixer "^9.8.6" + "@csstools/selector-specificity" "^2.0.2" balanced-match "^2.0.0" - chalk "^4.1.1" - cosmiconfig "^7.0.0" - debug "^4.3.1" - execall "^2.0.0" - fast-glob "^3.2.5" - fastest-levenshtein "^1.0.12" + colord "^2.9.3" + cosmiconfig "^7.1.0" + css-functions-list "^3.1.0" + debug "^4.3.4" + fast-glob "^3.2.12" + fastest-levenshtein "^1.0.16" file-entry-cache "^6.0.1" - get-stdin "^8.0.0" global-modules "^2.0.0" - globby "^11.0.3" + globby "^11.1.0" globjoin "^0.1.4" - html-tags "^3.1.0" - ignore "^5.1.8" + html-tags "^3.2.0" + ignore "^5.2.1" import-lazy "^4.0.0" imurmurhash "^0.1.4" - known-css-properties "^0.21.0" - lodash "^4.17.21" - log-symbols "^4.1.0" + is-plain-object "^5.0.0" + known-css-properties "^0.26.0" mathml-tag-names "^2.1.3" meow "^9.0.0" - micromatch "^4.0.4" - normalize-selector "^0.2.0" - postcss "^7.0.35" - postcss-html "^0.36.0" - postcss-less "^3.1.4" + micromatch "^4.0.5" + normalize-path "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.19" postcss-media-query-parser "^0.2.3" postcss-resolve-nested-selector "^0.1.1" - postcss-safe-parser "^4.0.2" - postcss-sass "^0.4.4" - postcss-scss "^2.1.1" - postcss-selector-parser "^6.0.5" - postcss-syntax "^0.36.2" - postcss-value-parser "^4.1.0" + postcss-safe-parser "^6.0.0" + postcss-selector-parser "^6.0.11" + postcss-value-parser "^4.2.0" resolve-from "^5.0.0" - slash "^3.0.0" - specificity "^0.4.1" - string-width "^4.2.2" - strip-ansi "^6.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" style-search "^0.1.0" - sugarss "^2.0.0" + supports-hyperlinks "^2.3.0" svg-tags "^1.0.0" - table "^6.6.0" + table "^6.8.1" v8-compile-cache "^2.3.0" - write-file-atomic "^3.0.3" - -sugarss@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" - integrity sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ== - dependencies: - postcss "^7.0.2" + write-file-atomic "^4.0.2" -supports-color@3.1.2, supports-color@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: - has-flag "^1.0.0" + has-flag "^4.0.0" supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0, supports-color@^5.4.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" +supports-color@^7.0.0, supports-color@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: - has-flag "^3.0.0" + has-flag "^4.0.0" supports-color@^7.1.0: version "7.1.0" @@ -9849,12 +8100,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== +supports-hyperlinks@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== dependencies: has-flag "^4.0.0" + supports-color "^7.0.0" supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" @@ -9866,22 +8118,28 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= -svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^6.6.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" - integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== +table@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== dependencies: ajv "^8.0.1" lodash.truncate "^4.4.2" @@ -9889,33 +8147,10 @@ table@^6.6.0: string-width "^4.2.3" strip-ansi "^6.0.1" -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - -tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -tar@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== tcp-port-used@^1.0.1: version "1.0.1" @@ -9924,55 +8159,31 @@ tcp-port-used@^1.0.1: debug "4.1.0" is2 "2.0.1" -terser-webpack-plugin@^1.4.3: - version "1.4.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" - integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== +terser-webpack-plugin@^5.1.3: + version "5.3.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.4.tgz#f4d31e265883d20fda3ca9c0fc6a53f173ae62e3" + integrity sha512-SmnkUhBxLDcBfTIeaq+ZqJXLVEyXxSaNcCeSezECdKjfkMrTTnPvapBILylYwyEvHFZAn2cJ8dtiXel5XnfOfQ== dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^4.0.0" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" + "@jridgewell/trace-mapping" "^0.3.14" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.14.1" -terser@^4.1.2: - version "4.8.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" - integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== +terser@^5.10.0, terser@^5.14.1: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -text-encoding@0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + source-map-support "~0.5.20" text-table@0.2.0, text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -thunkify@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" - -timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - dependencies: - setimmediate "^1.0.4" - tmp@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" @@ -9980,31 +8191,10 @@ tmp@^0.2.1: dependencies: rimraf "^3.0.0" -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -10012,42 +8202,33 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -toposort@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" +tough-cookie@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" + integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" trim-newlines@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - tsconfig-paths@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" @@ -10058,9 +8239,10 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" +tslib@^2.0.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -10072,18 +8254,11 @@ type-check@^0.4.0, type-check@~0.4.0: type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: prelude-ls "~1.1.2" -type-detect@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" - -type-detect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" - -type-detect@^4.0.0: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -10102,6 +8277,11 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" @@ -10115,29 +8295,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - ua-parser-js@^0.7.30: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== -uglify-js@3.4.x, uglify-js@^3.1.4: - version "3.4.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" - dependencies: - commander "~2.17.1" - source-map "~0.6.1" - unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -10148,10 +8310,6 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" -underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -10175,65 +8333,14 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== -unified@^9.1.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" - integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" - dependencies: - imurmurhash "^0.1.4" - -unist-util-find-all-after@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz#fdfecd14c5b7aea5e9ef38d5e0d5f774eeb561f6" - integrity sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ== - dependencies: - unist-util-is "^4.0.0" - -unist-util-is@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.0.2.tgz#c7d1341188aa9ce5b3cff538958de9895f14a5de" - integrity sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ== - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: version "2.0.0" @@ -10244,16 +8351,10 @@ unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== update-browserslist-db@^1.0.4: version "1.0.4" @@ -10263,9 +8364,21 @@ update-browserslist-db@^1.0.4: escalade "^3.1.1" picocolors "^1.0.0" -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" uri-js@^4.2.2: version "4.2.2" @@ -10273,31 +8386,23 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - -url-loader@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" - integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== dependencies: - loader-utils "^1.1.0" - mime "^2.0.3" - schema-utils "^1.0.0" + querystringify "^2.1.1" + requires-port "^1.0.0" -url@^0.11.0: +url@0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== dependencies: punycode "1.3.2" querystring "0.2.0" -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - -utf8@^3.0.0: +utf8@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== @@ -10306,26 +8411,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - dependencies: - inherits "2.0.3" - -utila@^0.4.0, utila@~0.4: +utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -10333,11 +8419,16 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" +uuid@8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" -v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0: +v8-compile-cache@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== @@ -10353,42 +8444,14 @@ vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" -vendors@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801" - -vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - -vfile@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.1.1.tgz#282d28cebb609183ac51703001bc18b3e3f17de9" - integrity sha512-lRjkpyDGjVlBA7cDQhQ+gNcvB1BGaTHYuSOcY3S7OhDmBtnzX95FhtZZDecSTDm6aajFymyve6S5DN4ZHGezdQ== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" -vue-demi@^0.13.4: - version "0.13.5" - resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.5.tgz#d5eddbc9eaefb89ce5995269d1fa6b0486312092" - integrity sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw== +vue-demi@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99" + integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A== vue-eslint-parser@^9.0.1: version "9.0.3" @@ -10403,31 +8466,41 @@ vue-eslint-parser@^9.0.1: lodash "^4.17.21" semver "^7.3.6" -vue-i18n@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.2.0.tgz#18e746aa0d6739860fe73383daff8884b6fd3c47" - integrity sha512-vN8aW8Vn4r4eRhUgTLK1/kCIYMb3LQmuloa1YP4NsehiASCX0XCq50tgUAz1o0eBAZ8YvhdlaVPqlO7O0wCnkQ== +vue-i18n@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.2.2.tgz#aeb49d9424923c77e0d6441e3f21dafcecd0e666" + integrity sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ== dependencies: - "@intlify/core-base" "9.2.0" - "@intlify/shared" "9.2.0" - "@intlify/vue-devtools" "9.2.0" + "@intlify/core-base" "9.2.2" + "@intlify/shared" "9.2.2" + "@intlify/vue-devtools" "9.2.2" "@vue/devtools-api" "^6.2.1" -vue-loader@^16.0.0: - version "16.8.3" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.8.3.tgz#d43e675def5ba9345d6c7f05914c13d861997087" - integrity sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA== +vue-loader@17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-17.0.1.tgz#c0ee8875e0610a0c2d13ba9b4d50a9c8442e7a3a" + integrity sha512-/OOyugJnImKCkAKrAvdsWMuwoCqGxWT5USLsjohzWbMgOwpA5wQmzQiLMzZd7DjhIfunzAGIApTOgIylz/kwcg== dependencies: chalk "^4.1.0" hash-sum "^2.0.0" loader-utils "^2.0.0" -vue-router@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.1.3.tgz#f8dc7931a2253cc5aa9b740f8b98969d08ca283c" - integrity sha512-XvK81bcYglKiayT7/vYAg/f36ExPC4t90R/HIpzrZ5x+17BOWptXLCrEPufGgZeuq68ww4ekSIMBZY1qdUdfjA== +vue-observe-visibility@^2.0.0-alpha.1: + version "2.0.0-alpha.1" + resolved "https://registry.yarnpkg.com/vue-observe-visibility/-/vue-observe-visibility-2.0.0-alpha.1.tgz#1e4eda7b12562161d58984b7e0dea676d83bdb13" + integrity sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g== + +vue-resize@^2.0.0-alpha.1: + version "2.0.0-alpha.1" + resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz#43eeb79e74febe932b9b20c5c57e0ebc14e2df3a" + integrity sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg== + +vue-router@4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.1.6.tgz#b70303737e12b4814578d21d68d21618469375a1" + integrity sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ== dependencies: - "@vue/devtools-api" "^6.1.4" + "@vue/devtools-api" "^6.4.5" vue-style-loader@4.1.3: version "4.1.3" @@ -10437,51 +8510,76 @@ vue-style-loader@4.1.3: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@2.7.8: - version "2.7.8" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.8.tgz#eadd54ed8fbff55b7deb07093a976c07f451a1dc" - integrity sha512-eQqdcUpJKJpBRPDdxCNsqUoT0edNvdt1jFjtVnVS/LPPmr0BU2jWzXlrf6BVMeODtdLewB3j8j3WjNiB+V+giw== +vue-template-compiler@2.7.14: + version "2.7.14" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz#4545b7dfb88090744c1577ae5ac3f964e61634b1" + integrity sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ== dependencies: de-indent "^1.0.2" he "^1.2.0" -vue@3.2.37: - version "3.2.37" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.37.tgz#da220ccb618d78579d25b06c7c21498ca4e5452e" - integrity sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ== +vue-virtual-scroller@^2.0.0-beta.7: + version "2.0.0-beta.7" + resolved "https://registry.yarnpkg.com/vue-virtual-scroller/-/vue-virtual-scroller-2.0.0-beta.7.tgz#4ea8158638c84b2033b001a8b26c5fcb6896b271" + integrity sha512-OrouVj1i2939jaLjVfu8f5fsDlbzhAb4bOsYZYrAkpcVLylAmMoGtIL7eT3hJrdTiaKbwQpRdnv7DKf9Fn+tHg== dependencies: - "@vue/compiler-dom" "3.2.37" - "@vue/compiler-sfc" "3.2.37" - "@vue/runtime-dom" "3.2.37" - "@vue/server-renderer" "3.2.37" - "@vue/shared" "3.2.37" + mitt "^2.1.0" + vue-observe-visibility "^2.0.0-alpha.1" + vue-resize "^2.0.0-alpha.1" -vuex@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.2.tgz#f896dbd5bf2a0e963f00c67e9b610de749ccacc9" - integrity sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q== +vue@3.2.45: + version "3.2.45" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.45.tgz#94a116784447eb7dbd892167784619fef379b3c8" + integrity sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA== + dependencies: + "@vue/compiler-dom" "3.2.45" + "@vue/compiler-sfc" "3.2.45" + "@vue/runtime-dom" "3.2.45" + "@vue/server-renderer" "3.2.45" + "@vue/shared" "3.2.45" + +vuex@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.1.0.tgz#aa1b3ea5c7385812b074c86faeeec2217872e36c" + integrity sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ== dependencies: "@vue/devtools-api" "^6.0.0-beta.11" -watchpack-chokidar2@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" - integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: - chokidar "^2.1.8" + browser-process-hrtime "^1.0.0" -watchpack@^1.7.4: - version "1.7.5" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" - integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== +w3c-xmlserializer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" + integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== + dependencies: + xml-name-validator "^4.0.0" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== dependencies: + glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" - neo-async "^2.5.0" - optionalDependencies: - chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.1" -webpack-dev-middleware@3.7.3, webpack-dev-middleware@^3.7.0: +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +webpack-dev-middleware@3.7.3: version "3.7.3" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== @@ -10492,14 +8590,13 @@ webpack-dev-middleware@3.7.3, webpack-dev-middleware@^3.7.0: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-hot-middleware@2.25.1: - version "2.25.1" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.1.tgz#581f59edf0781743f4ca4c200fd32c9266c6cf7c" - integrity sha512-Koh0KyU/RPYwel/khxbsDz9ibDivmUbrRuKSSQvW42KSDdO4w23WI3SkHpSUKHE76LrFnnM/L7JCrpBwu8AXYw== +webpack-hot-middleware@2.25.3: + version "2.25.3" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz#be343ce2848022cfd854dd82820cd730998c6794" + integrity sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA== dependencies: ansi-html-community "0.0.8" html-entities "^2.1.0" - querystring "^0.2.0" strip-ansi "^6.0.0" webpack-log@^2.0.0: @@ -10520,53 +8617,75 @@ webpack-merge@0.20.0: lodash.isplainobject "^3.2.0" lodash.merge "^3.3.2" -webpack-sources@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" + lodash "^4.17.15" -webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@5.75.0: + version "5.75.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" + integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" + iconv-lite "0.6.3" -webpack@4.46.0: - version "4.46.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" - integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/wasm-edit" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - acorn "^6.4.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.5.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.3" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.7.4" - webpack-sources "^1.4.1" - -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da" + integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" which-boxed-primitive@^1.0.2: version "1.0.2" @@ -10584,43 +8703,40 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.0.9, which@^1.1.1, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - dependencies: - isexe "^2.0.0" - -which@^2.0.1: +which@2.0.2, which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" +which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== dependencies: - string-width "^1.0.2 || 2" + string-width "^4.0.0" -word-wrap@^1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@^1.0.0, wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - dependencies: - errno "~0.1.7" +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== wrap-ansi@^6.2.0: version "6.2.0" @@ -10644,15 +8760,23 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" + signal-exit "^3.0.7" + +ws@>=8.7.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== + +ws@^8.2.3: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== ws@~8.2.3: version "8.2.3" @@ -10664,11 +8788,12 @@ xml-name-validator@^4.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== -xregexp@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.0, xtend@~4.0.1: +xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -10681,13 +8806,10 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: version "4.0.0" @@ -10703,11 +8825,16 @@ yaml-eslint-parser@^0.3.2: lodash "^4.17.20" yaml "^1.10.0" -yaml@^1.10.0: +yaml@^1.10.0, yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -10721,6 +8848,29 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.3: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^15.3.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -10738,19 +8888,6 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.1.1: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" @@ -10763,8 +8900,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==