diff --git a/.env.production.sample b/.env.production.sample index 0bf01bdc361d93..0b458a1aa96dfb 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -1,5 +1,5 @@ # This is a sample configuration file. You can generate your configuration -# with the `rake mastodon:setup` interactive setup wizard, but to customize +# with the `bundle exec rails mastodon:setup` interactive setup wizard, but to customize # your setup even further, you'll need to edit it manually. This sample does # not demonstrate all available configuration options. Please look at # https://docs.joinmastodon.org/admin/config/ for the full documentation. @@ -40,14 +40,14 @@ ES_PASS=password # Secrets # ------- -# Make sure to use `rake secret` to generate secrets +# Make sure to use `bundle exec rails secret` to generate secrets # ------- SECRET_KEY_BASE= OTP_SECRET= # Web Push # -------- -# Generate with `rake mastodon:webpush:generate_vapid_key` +# Generate with `bundle exec rails mastodon:webpush:generate_vapid_key` # -------- VAPID_PRIVATE_KEY= VAPID_PUBLIC_KEY= diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index e3e2da0c787a54..2341d6e67f6241 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -1,8 +1,10 @@ name: Bundler Audit on: + merge_group: push: - branches-ignore: - - 'dependabot/**' + branches: + - 'main' + - 'stable-*' paths: - 'Gemfile*' - '.ruby-version' diff --git a/.github/workflows/check-i18n.yml b/.github/workflows/check-i18n.yml index ceb385933b29bb..5a1c0519665873 100644 --- a/.github/workflows/check-i18n.yml +++ b/.github/workflows/check-i18n.yml @@ -2,9 +2,13 @@ name: Check i18n on: push: - branches: [main] + branches: + - 'main' + - 'stable-*' pull_request: - branches: [main] + branches: + - 'main' + - 'stable-*' env: RAILS_ENV: test diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6fb93b7fef45a6..8690e9ed6d1639 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,11 +1,15 @@ name: 'CodeQL' on: + merge_group: push: - branches: ['main'] + branches: + - 'main' + - 'stable-*' pull_request: - # The branches below must be a subset of the branches above - branches: ['main'] + branches: + - 'main' + - 'stable-*' schedule: - cron: '22 6 * * 1' diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml index 705af12c025044..4c9d7b096b8e63 100644 --- a/.github/workflows/crowdin-upload.yml +++ b/.github/workflows/crowdin-upload.yml @@ -1,9 +1,11 @@ name: Crowdin / Upload translations on: + merge_group: push: branches: - - main + - 'main' + - 'stable-*' paths: - crowdin.yml - app/javascript/mastodon/locales/en.json diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml index 2d483b50229626..c10f350a02ef28 100644 --- a/.github/workflows/format-check.yml +++ b/.github/workflows/format-check.yml @@ -1,6 +1,10 @@ name: Check formatting on: + merge_group: push: + branches: + - 'main' + - 'stable-*' pull_request: jobs: diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml index d3b8035cd86521..95fcd569420fdf 100644 --- a/.github/workflows/lint-css.yml +++ b/.github/workflows/lint-css.yml @@ -1,9 +1,10 @@ name: CSS Linting on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' paths: - 'package.json' - 'yarn.lock' diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml index ca4b0c80bfdc3e..a1a9e99c902bfb 100644 --- a/.github/workflows/lint-haml.yml +++ b/.github/workflows/lint-haml.yml @@ -1,9 +1,10 @@ name: Haml Linting on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' paths: - '.github/workflows/haml-lint-problem-matcher.json' - '.github/workflows/lint-haml.yml' diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index 1c1ecc2b22049b..7d31a5e20e7804 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -1,9 +1,10 @@ name: JavaScript Linting on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' paths: - 'package.json' - 'yarn.lock' diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index b3a89c3caf1cbd..277e456146fdcf 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -1,9 +1,10 @@ name: Ruby Linting on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' paths: - 'Gemfile*' - '.rubocop*.yml' diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml index 481afdba30366d..e9e43ac9e80184 100644 --- a/.github/workflows/test-js.yml +++ b/.github/workflows/test-js.yml @@ -1,9 +1,10 @@ name: JavaScript Testing on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' paths: - 'package.json' - 'yarn.lock' diff --git a/.github/workflows/test-migrations.yml b/.github/workflows/test-migrations.yml index 3eaf2c2d7402b8..6a0e67c58ee500 100644 --- a/.github/workflows/test-migrations.yml +++ b/.github/workflows/test-migrations.yml @@ -1,29 +1,29 @@ name: Historical data migration test on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' + paths: + - 'Gemfile*' + - '.ruby-version' + - '**/*.rb' + - '.github/workflows/test-migrations.yml' + - 'lib/tasks/tests.rake' + pull_request: + paths: + - 'Gemfile*' + - '.ruby-version' + - '**/*.rb' + - '.github/workflows/test-migrations.yml' + - 'lib/tasks/tests.rake' jobs: - pre_job: - runs-on: ubuntu-latest - - outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} - - steps: - - id: skip_check - uses: fkirc/skip-duplicate-actions@v5 - with: - paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations.yml", "lib/tasks/tests.rake"]' - test: runs-on: ubuntu-latest - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' strategy: fail-fast: false diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index ef898968d0128c..fcfeed5fbad7b3 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -1,10 +1,11 @@ name: Ruby Testing on: + merge_group: push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' + branches: + - 'main' + - 'stable-*' pull_request: env: @@ -223,7 +224,7 @@ jobs: - name: Load database schema run: './bin/rails db:create db:schema:load db:seed' - - run: bin/rspec --tag paperclip_processing + - run: bin/rspec --tag attachment_processing - name: Upload coverage reports to Codecov if: matrix.ruby-version == '.ruby-version' diff --git a/.ruby-version b/.ruby-version index 619b537668489e..a0891f563f38b0 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.3 +3.3.4 diff --git a/Dockerfile b/Dockerfile index 7f7eca06dac040..52d3758dc67cf7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ ARG BUILDPLATFORM=${BUILDPLATFORM} # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"] # renovate: datasource=docker depName=docker.io/ruby -ARG RUBY_VERSION="3.3.3" +ARG RUBY_VERSION="3.3.4" # # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] # renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="20" diff --git a/Gemfile.lock b/Gemfile.lock index eb6720e4542b77..1c253719e4ebae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -346,7 +346,7 @@ GEM activesupport (>= 3.0) nokogiri (>= 1.6) io-console (0.7.2) - irb (1.13.2) + irb (1.14.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jmespath (1.6.2) @@ -793,10 +793,10 @@ GEM redis (>= 4.5.0, < 5) sidekiq-bulk (0.2.0) sidekiq - sidekiq-scheduler (5.0.3) + sidekiq-scheduler (5.0.5) rufus-scheduler (~> 3.2) sidekiq (>= 6, < 8) - tilt (>= 1.4.0) + tilt (>= 1.4.0, < 3) sidekiq-unique-jobs (7.1.33) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) diff --git a/app/controllers/api/v1/polls/votes_controller.rb b/app/controllers/api/v1/polls/votes_controller.rb index 513b937ef2de34..ad1b82cb522c69 100644 --- a/app/controllers/api/v1/polls/votes_controller.rb +++ b/app/controllers/api/v1/polls/votes_controller.rb @@ -8,7 +8,7 @@ class Api::V1::Polls::VotesController < Api::BaseController before_action :set_poll def create - VoteService.new.call(current_account, @poll, vote_params[:choices]) + VoteService.new.call(current_account, @poll, vote_params) render json: @poll, serializer: REST::PollSerializer end @@ -22,6 +22,6 @@ def set_poll end def vote_params - params.permit(choices: []) + params.require(:choices) end end diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index b07dff182a8bb4..0bcba7d57fe78b 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -279,7 +279,7 @@ export function submitComposeFail(error) { export function uploadCompose(files) { return function (dispatch, getState) { - const uploadLimit = 4; + const uploadLimit = getState().getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']); const media = getState().getIn(['compose', 'media_attachments']); const pending = getState().getIn(['compose', 'pending_media_attachments']); const progress = new Array(files.length).fill(0); @@ -299,7 +299,7 @@ export function uploadCompose(files) { dispatch(uploadComposeRequest()); for (const [i, file] of Array.from(files).entries()) { - if (media.size + i > 3) break; + if (media.size + i > (uploadLimit - 1)) break; const data = new FormData(); data.append('file', file); diff --git a/app/javascript/mastodon/components/account.jsx b/app/javascript/mastodon/components/account.jsx index 18a31cba244867..2a748e67ff139b 100644 --- a/app/javascript/mastodon/components/account.jsx +++ b/app/javascript/mastodon/components/account.jsx @@ -131,7 +131,7 @@ const Account = ({ size = 46, account, onFollow, onBlock, onMute, onMuteNotifica return (
- +
diff --git a/app/javascript/mastodon/components/hover_card_controller.tsx b/app/javascript/mastodon/components/hover_card_controller.tsx index 5ca55ebde91049..057ef1aaed4a71 100644 --- a/app/javascript/mastodon/components/hover_card_controller.tsx +++ b/app/javascript/mastodon/components/hover_card_controller.tsx @@ -43,6 +43,7 @@ export const HoverCardController: React.FC = () => { useEffect(() => { let isScrolling = false; let currentAnchor: HTMLElement | null = null; + let currentTitle: string | null = null; const open = (target: HTMLElement) => { target.setAttribute('aria-describedby', 'hover-card'); @@ -75,6 +76,9 @@ export const HoverCardController: React.FC = () => { currentAnchor?.removeAttribute('aria-describedby'); currentAnchor = target; + currentTitle = target.getAttribute('title'); + target.removeAttribute('title'); + setEnterTimeout(() => { open(target); }, enterDelay); @@ -90,11 +94,20 @@ export const HoverCardController: React.FC = () => { }; const handleMouseLeave = (e: MouseEvent) => { + const { target } = e; + if (!currentAnchor) { return; } - if (e.target === currentAnchor || e.target === cardRef.current) { + if ( + currentTitle && + target instanceof HTMLElement && + target === currentAnchor + ) + target.setAttribute('title', currentTitle); + + if (target === currentAnchor || target === cardRef.current) { cancelEnterTimeout(); setLeaveTimeout(() => { diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx index 91459a1285c0d1..ed4805b05d50f5 100644 --- a/app/javascript/mastodon/components/media_gallery.jsx +++ b/app/javascript/mastodon/components/media_gallery.jsx @@ -305,13 +305,13 @@ class MediaGallery extends PureComponent { style.aspectRatio = '3 / 2'; } - const size = media.take(4).size; + const size = media.size; const uncached = media.every(attachment => attachment.get('type') === 'unknown'); if (this.isFullSizeEligible()) { children = ; } else { - children = media.take(4).map((attachment, i) => ); + children = media.map((attachment, i) => ); } if (uncached) { diff --git a/app/javascript/mastodon/features/compose/containers/upload_button_container.js b/app/javascript/mastodon/features/compose/containers/upload_button_container.js index 066e1853468680..7cdc12663d70ca 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_button_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_button_container.js @@ -9,7 +9,7 @@ const mapStateToProps = state => { const readyAttachmentsSize = state.getIn(['compose', 'media_attachments']).size ?? 0; const pendingAttachmentsSize = state.getIn(['compose', 'pending_media_attachments']).size ?? 0; const attachmentsSize = readyAttachmentsSize + pendingAttachmentsSize; - const isOverLimit = attachmentsSize > 3; + const isOverLimit = attachmentsSize > state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments'])-1; const hasVideoOrAudio = state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type'))); return { diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx index f0ae40cbc412f5..ee1fbe0f8fe826 100644 --- a/app/javascript/mastodon/features/status/components/card.jsx +++ b/app/javascript/mastodon/features/status/components/card.jsx @@ -141,7 +141,7 @@ export default class Card extends PureComponent { const showAuthor = !!card.getIn(['authors', 0, 'accountId']); const description = ( -
+
{provider} {card.get('published_at') && <> · } diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 323890ba2efe8a..98e84c45d75351 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -35,7 +35,9 @@ "account.follow_back": "Последване взаимно", "account.followers": "Последователи", "account.followers.empty": "Още никой не следва потребителя.", + "account.followers_counter": "{count, plural, one {{counter} последовател} other {{counter} последователи}}", "account.following": "Последвано", + "account.following_counter": "{count, plural, one {{counter} последван} other {{counter} последвани}}", "account.follows.empty": "Потребителят още никого не следва.", "account.go_to_profile": "Към профила", "account.hide_reblogs": "Скриване на подсилвания от @{name}", @@ -61,6 +63,7 @@ "account.requested_follow": "{name} поиска да ви последва", "account.share": "Споделяне на профила на @{name}", "account.show_reblogs": "Показване на подсилвания от @{name}", + "account.statuses_counter": "{count, plural, one {{counter} публикация} other {{counter} публикации}}", "account.unblock": "Отблокиране на @{name}", "account.unblock_domain": "Отблокиране на домейн {domain}", "account.unblock_short": "Отблокиране", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index e96e283970f0ae..12de5d5ecd4794 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -197,7 +197,7 @@ "copy_icon_button.copied": "Zkopírováno do schránky", "copypaste.copied": "Zkopírováno", "copypaste.copy_to_clipboard": "Zkopírovat do schránky", - "directory.federated": "Ze známého fedivesmíru", + "directory.federated": "Ze známého fediversu", "directory.local": "Pouze z {domain}", "directory.new_arrivals": "Nově příchozí", "directory.recently_active": "Nedávno aktivní", @@ -213,7 +213,7 @@ "domain_block_modal.block_account_instead": "Raději blokovat @{name}", "domain_block_modal.they_can_interact_with_old_posts": "Lidé z tohoto serveru mohou interagovat s vašimi starými příspěvky.", "domain_block_modal.they_cant_follow": "Nikdo z tohoto serveru vás nemůže sledovat.", - "domain_block_modal.they_wont_know": "Nebude vědět, že je zablokován.", + "domain_block_modal.they_wont_know": "Nebude vědět, že je zablokován*a.", "domain_block_modal.title": "Blokovat doménu?", "domain_block_modal.you_will_lose_followers": "Všichni vaši sledující z tohoto serveru budou odstraněni.", "domain_block_modal.you_wont_see_posts": "Neuvidíte příspěvky ani upozornění od uživatelů z tohoto serveru.", @@ -341,7 +341,7 @@ "hashtag.column_settings.tag_mode.any": "Jakýkoliv z těchto", "hashtag.column_settings.tag_mode.none": "Žádný z těchto", "hashtag.column_settings.tag_toggle": "Zahrnout v tomto sloupci další štítky", - "hashtag.counter_by_accounts": "{count, plural, one {{counter} účastník} few {{counter} účastníci} other {{counter} účastníků}}", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} účastník*ice} few {{counter} účastníci} other {{counter} účastníků}}", "hashtag.counter_by_uses": "{count, plural, one {{counter} příspěvek} few {{counter} příspěvky} other {{counter} příspěvků}}", "hashtag.counter_by_uses_today": "Dnes {count, plural, one {{counter} příspěvek} few {{counter} příspěvky} other {{counter} příspěvků}}", "hashtag.follow": "Sledovat hashtag", @@ -440,7 +440,7 @@ "mute_modal.show_options": "Zobrazit možnosti", "mute_modal.they_can_mention_and_follow": "Mohou vás zmínit a sledovat, ale neuvidíte je.", "mute_modal.they_wont_know": "Nebudou vědět, že byli skryti.", - "mute_modal.title": "Ztlumit uživatele?", + "mute_modal.title": "Ztlumit uživatele*ku?", "mute_modal.you_wont_see_mentions": "Neuvidíte příspěvky, které je zmiňují.", "mute_modal.you_wont_see_posts": "Stále budou moci vidět vaše příspěvky, ale vy jejich neuvidíte.", "navigation_bar.about": "O aplikaci", @@ -566,8 +566,8 @@ "onboarding.share.message": "Jsem {username} na #Mastodonu! Pojď mě sledovat na {url}", "onboarding.share.next_steps": "Možné další kroky:", "onboarding.share.title": "Sdílejte svůj profil", - "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", - "onboarding.start.skip": "Want to skip right ahead?", + "onboarding.start.lead": "Nyní jste součástí Mastodonu, unikátní sociální sítě, kde vy - ne algoritmus - vytváří vaše vlastní prožitky. Začněte na této nové sociální platformě:", + "onboarding.start.skip": "Nepotřebujete pomoci začít?", "onboarding.start.title": "Dokázali jste to!", "onboarding.steps.follow_people.body": "Mastodon je o sledování zajimavých lidí.", "onboarding.steps.follow_people.title": "Přispůsobit vlastní domovský kanál", @@ -581,7 +581,7 @@ "onboarding.tips.accounts_from_other_servers": "Víte, že? Protože je Mastodon decentralizovaný, některé profily, na které narazíte, budou hostovány na jiných serverech, než je ten váš. A přesto s nimi můžete bezproblémově komunikovat! Jejich server se nachází v druhé polovině uživatelského jména!", "onboarding.tips.migration": "Víte, že? Pokud máte pocit, že {domain} pro vás v budoucnu není vhodnou volbou, můžete se přesunout na jiný Mastodon server, aniž byste přišli o své sledující. Můžete dokonce hostovat svůj vlastní server!", "onboarding.tips.verification": "Víte, že? Svůj účet můžete ověřit tak, že na své webové stránky umístíte odkaz na váš Mastodon profil a odkaz na stránku přidáte do svého profilu. Nejsou k tomu potřeba žádné poplatky ani dokumenty!", - "password_confirmation.exceeds_maxlength": "Potvrzení hesla překračuje maximální délku hesla", + "password_confirmation.exceeds_maxlength": "Potvrzení hesla překračuje maximální povolenou délku hesla", "password_confirmation.mismatching": "Zadaná hesla se neshodují", "picture_in_picture.restore": "Vrátit zpět", "poll.closed": "Uzavřeno", @@ -665,7 +665,7 @@ "report.unfollow": "Přestat sledovat @{name}", "report.unfollow_explanation": "Tento účet sledujete. Abyste už neviděli jeho příspěvky ve své domovské časové ose, přestaňte jej sledovat.", "report_notification.attached_statuses": "{count, plural, one {{count} připojený příspěvek} few {{count} připojené příspěvky} many {{count} připojených příspěvků} other {{count} připojených příspěvků}}", - "report_notification.categories.legal": "Zákonné", + "report_notification.categories.legal": "Právní ustanovení", "report_notification.categories.other": "Ostatní", "report_notification.categories.spam": "Spam", "report_notification.categories.violation": "Porušení pravidla", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 575c68de038955..f3ba028eabde00 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -411,6 +411,7 @@ "limited_account_hint.action": "構わず表示する", "limited_account_hint.title": "このプロフィールは{domain}のモデレーターによって非表示にされています。", "link_preview.author": "{name}", + "link_preview.more_from_author": "{name}さんの投稿をもっと読む", "lists.account.add": "リストに追加", "lists.account.remove": "リストから外す", "lists.delete": "リストを削除", @@ -691,8 +692,11 @@ "server_banner.about_active_users": "過去30日間にこのサーバーを使用している人 (月間アクティブユーザー)", "server_banner.active_users": "人のアクティブユーザー", "server_banner.administered_by": "管理者", + "server_banner.is_one_of_many": "{domain} は、数々の独立したMastodonサーバーのうちのひとつです。サーバーに登録してFediverseのコミュニティに加わってみませんか。", "server_banner.server_stats": "サーバーの情報", "sign_in_banner.create_account": "アカウント作成", + "sign_in_banner.follow_anyone": "連合内の誰でもフォローして投稿を時系列で見ることができます。アルゴリズム、広告、クリックベイトはありません。", + "sign_in_banner.mastodon_is": "Mastodonに参加して、世界で起きていることを見つけよう。", "sign_in_banner.sign_in": "ログイン", "sign_in_banner.sso_redirect": "ログインまたは登録", "status.admin_account": "@{name}さんのモデレーション画面を開く", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index de866cc1bc4c33..fcaa8f143ed445 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -1,6 +1,10 @@ { + "about.blocks": "Ulac agbur", "about.contact": "Anermis:", "about.disclaimer": "Mastodon d aseɣẓan ilelli, d aseɣẓan n uɣbalu yeldin, d tnezzut n Mastodon gGmbH.", + "about.domain_blocks.preamble": "Maṣṭudun s umata yeḍmen-ak ad teẓreḍ agbur, ad tesdemreḍ akked yimseqdacen-nniḍen seg yal aqeddac deg fedivers. Ha-tent-an ɣur-k tsuraf i yellan deg uqeddac-agi.", + "about.domain_blocks.silenced.title": "Ɣur-s talast", + "about.domain_blocks.suspended.title": "Yeḥbes", "about.not_available": "Talɣut-a ur tettwabder ara deg uqeddac-a.", "about.powered_by": "Azeṭṭa inmetti yettwasɣelsen sɣur {mastodon}", "about.rules": "Ilugan n uqeddac", @@ -166,6 +170,7 @@ "dismissable_banner.explore_tags": "D wiyi i d ihacṭagen i d-yettawin tamyigawt deg web anmetti ass-a. Ihacṭagen i sseqdacen ugar n medden, εlayit d imezwura.", "domain_block_modal.block": "Sewḥel aqeddac", "domain_block_modal.they_cant_follow": "Yiwen ur yezmir ad k·m-id-yeḍfer seg uqeddac-a.", + "domain_block_modal.title": "Sewḥel taɣult?", "domain_pill.activitypub_like_language": "ActivityPub am tutlayt yettmeslay Mastodon d izeḍwan inmettiyen nniḍen.", "domain_pill.server": "Aqeddac", "domain_pill.username": "Isem n useqdac", @@ -214,6 +219,7 @@ "filter_modal.added.review_and_configure_title": "Iɣewwaṛen n imzizdig", "filter_modal.added.settings_link": "asebter n yiɣewwaṛen", "filter_modal.added.short_explanation": "Tasuffeɣt-a tettwarna ɣer taggayt-a n yimsizdegen: {title}.", + "filter_modal.added.title": "Yettwarna umsizdeg!", "filter_modal.select_filter.expired": "yemmut", "filter_modal.select_filter.prompt_new": "Taggayt tamaynutt : {name}", "filter_modal.select_filter.search": "Nadi neɣ snulfu-d", @@ -224,9 +230,9 @@ "firehose.remote": "Iqeddacen nniḍen", "follow_request.authorize": "Ssireg", "follow_request.reject": "Agi", - "follow_suggestions.dismiss": "Ur ttɛawad ara ad t-id-sekneṭ", + "follow_suggestions.dismiss": "Dayen ur t-id-skan ara", "follow_suggestions.view_all": "Wali-ten akk", - "follow_suggestions.who_to_follow": "Menhu ara ḍefṛeḍ", + "follow_suggestions.who_to_follow": "Ad tḍefreḍ?", "followed_tags": "Ihacṭagen yettwaḍfaren", "footer.about": "Ɣef", "footer.directory": "Akaram n imeɣna", @@ -235,6 +241,7 @@ "footer.keyboard_shortcuts": "Inegzumen n unasiw", "footer.privacy_policy": "Tasertit tabaḍnit", "footer.source_code": "Wali tangalt taɣbalut", + "footer.status": "N tsuffeɣt", "generic.saved": "Yettwasekles", "getting_started.heading": "Bdu", "hashtag.column_header.tag_mode.all": "d {additional}", @@ -313,11 +320,14 @@ "lightbox.previous": "Ɣer deffir", "limited_account_hint.action": "Wali amaɣnu akken yebɣu yili", "link_preview.author": "S-ɣur {name}", + "link_preview.more_from_author": "Ugar sɣur {name}", + "link_preview.shares": "{count, plural, one {{counter} post} other {{counter} posts}}", "lists.account.add": "Rnu ɣer tebdart", "lists.account.remove": "Kkes seg tebdart", "lists.delete": "Kkes tabdart", "lists.edit": "Ẓreg tabdart", "lists.edit.submit": "Beddel azwel", + "lists.exclusive": "Ffer tisuffaɣ-a seg ugejdan", "lists.new.create": "Rnu tabdart", "lists.new.title_placeholder": "Azwel amaynut n tebdart", "lists.replies_policy.followed": "Kra n useqdac i yettwaḍefren", @@ -338,6 +348,7 @@ "navigation_bar.bookmarks": "Ticraḍ", "navigation_bar.community_timeline": "Tasuddemt tadigant", "navigation_bar.compose": "Aru tajewwiqt tamaynut", + "navigation_bar.direct": "Tibdarin tusligin", "navigation_bar.discover": "Ẓer", "navigation_bar.domain_blocks": "Tiɣula yeffren", "navigation_bar.explore": "Snirem", @@ -357,9 +368,14 @@ "navigation_bar.search": "Nadi", "navigation_bar.security": "Taɣellist", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", + "notification.admin.report": "Yemla-t-id {name} {target}", + "notification.admin.sign_up": "Ijerred {name}", + "notification.favourite": "{name} yesmenyaf addad-ik·im", "notification.follow": "iṭṭafar-ik·em-id {name}", "notification.follow_request": "{name} yessuter-d ad k·m-yeḍfeṛ", "notification.mention": "{name} yebder-ik-id", + "notification.moderation-warning.learn_more": "Issin ugar", + "notification.moderation_warning.action_suspend": "Yettwaseḥbes umiḍan-ik.", "notification.own_poll": "Tafrant-ik·im tfuk", "notification.poll": "Tfukk tefrant ideg tettekkaḍ", "notification.reblog": "{name} yebḍa tajewwiqt-ik i tikelt-nniḍen", @@ -370,6 +386,7 @@ "notification_requests.notifications_from": "Ilɣa sɣur {name}", "notifications.clear": "Sfeḍ tilɣa", "notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk tilɣa-inek·em i lebda?", + "notifications.column_settings.admin.report": "Ineqqisen imaynuten:", "notifications.column_settings.alert": "Tilɣa n tnarit", "notifications.column_settings.favourite": "Imenyafen:", "notifications.column_settings.filter_bar.advanced": "Sken-d akk taggayin", @@ -384,6 +401,7 @@ "notifications.column_settings.sound": "Rmed imesli", "notifications.column_settings.status": "Tisuffaɣ timaynutin :", "notifications.column_settings.unread_notifications.category": "Ilɣa ur nettwaɣra", + "notifications.column_settings.update": "Iẓreg:", "notifications.filter.all": "Akk", "notifications.filter.boosts": "Seǧhed", "notifications.filter.favourites": "Imenyafen", @@ -413,6 +431,7 @@ "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Ttwassnen deg Mastodon", "onboarding.profile.display_name": "Isem ara d-yettwaskanen", + "onboarding.profile.display_name_hint": "Isem-ik·im ummid neɣ isem-ik·im n uqeṣṣer…", "onboarding.profile.note": "Tameddurt", "onboarding.profile.note_hint": "Tzemreḍ ad d-@tbedreḍ imdanen niḍen neɣ #ihacṭagen …", "onboarding.profile.save_and_continue": "Sekles, tkemmleḍ", @@ -441,6 +460,7 @@ "poll.total_votes": "{count, plural, one {# n udɣaṛ} other {# n yedɣaṛen}}", "poll.vote": "Dɣeṛ", "poll.voted": "Tdeɣṛeḍ ɣef tririt-ayi", + "poll.votes": "{votes, plural, one {# n udɣaṛ} other {# n yedɣaṛen}}", "poll_button.add_poll": "Rnu asenqed", "poll_button.remove_poll": "Kkes asenqed", "privacy.change": "Seggem tabaḍnit n yizen", @@ -465,9 +485,12 @@ "relative_time.seconds": "{number}tas", "relative_time.today": "assa", "reply_indicator.cancel": "Sefsex", + "reply_indicator.poll": "Afmiḍi", "report.block": "Sewḥel", + "report.categories.legal": "Azerfan", "report.categories.other": "Tiyyaḍ", "report.categories.spam": "Aspam", + "report.category.subtitle": "Fren amṣada akk ufrin", "report.category.title_account": "ameɣnu", "report.category.title_status": "tasuffeɣt", "report.close": "Immed", @@ -476,13 +499,25 @@ "report.next": "Uḍfiṛ", "report.placeholder": "Iwenniten-nniḍen", "report.reasons.dislike": "Ur t-ḥemmleɣ ara", + "report.reasons.dislike_description": "D ayen akk ur bɣiɣ ara ad waliɣ", "report.reasons.other": "D ayen nniḍen", + "report.reasons.other_description": "Ugur ur yemṣada ara akk d taggayin-nniḍen", "report.reasons.spam": "D aspam", + "report.reasons.spam_description": "Yir iseɣwan, yir agman d tririyin i d-yettuɣalen", + "report.reasons.violation": "Truẓi n yilugan n uqeddac", + "report.reasons.violation_description": "Teẓriḍ y·tettruẓu kra n yilugan", + "report.rules.subtitle": "Fren ayen akk yemṣadan", + "report.rules.title": "Acu n yilugan i yettwarẓan?", + "report.statuses.subtitle": "Fren ayen akk yemṣadan", + "report.statuses.title": "Llant tsuffaɣ ara isdemren aneqqis-a?", "report.submit": "Azen", "report.target": "Mmel {target}", + "report.thanks.take_action_actionable": "Ideg nekkni nessenqad tuttra-inek•inem, tzemreḍ ad tḥadreḍ mgal @{name}:", "report.thanks.title": "Ur tebɣiḍ ara ad twaliḍ aya?", + "report.thanks.title_actionable": "Tanemmirt ɣef uneqqis, ad nwali deg waya.", "report.unfollow": "Seḥbes aḍfar n @{name}", "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", + "report_notification.categories.legal": "Azerfan", "report_notification.categories.other": "Ayen nniḍen", "report_notification.categories.spam": "Aspam", "report_notification.open": "Ldi aneqqis", @@ -497,6 +532,7 @@ "search_popout.full_text_search_disabled_message": "Ur yelli ara deg {domain}.", "search_popout.language_code": "Tangalt ISO n tutlayt", "search_popout.options": "Iwellihen n unadi", + "search_popout.quick_actions": "Tigawin tiruradin", "search_popout.recent": "Inadiyen ineggura", "search_popout.user": "amseqdac", "search_results.accounts": "Imeɣna", @@ -505,7 +541,9 @@ "search_results.see_all": "Wali-ten akk", "search_results.statuses": "Tisuffaɣ", "search_results.title": "Anadi ɣef {q}", + "server_banner.active_users": "iseqdacen urmiden", "server_banner.administered_by": "Yettwadbel sɣur :", + "server_banner.server_stats": "Tidaddanin n uqeddac:", "sign_in_banner.create_account": "Snulfu-d amiḍan", "sign_in_banner.sign_in": "Qqen", "sign_in_banner.sso_redirect": "Qqen neɣ jerred", @@ -516,13 +554,20 @@ "status.cannot_reblog": "Tasuffeɣt-a ur tezmir ara ad tettwabḍu tikelt-nniḍen", "status.copy": "Nɣel assaɣ ɣer tasuffeɣt", "status.delete": "Kkes", + "status.direct": "Bder-d @{name} weḥd-s", + "status.direct_indicator": "Abdar uslig", "status.edit": "Ẓreg", "status.edited_x_times": "Tettwaẓreg {count, plural, one {{count} n tikkelt} other {{count} n tikkal}}", "status.embed": "Seddu", + "status.favourite": "Amenyaf", "status.filter": "Sizdeg tassufeɣt-a", "status.filtered": "Yettwasizdeg", "status.hide": "Ffer tasuffeɣt", + "status.history.created": "Yerna-t {name} {date}", + "status.history.edited": "Ibeddel-it {name} {date}", "status.load_more": "Sali ugar", + "status.media.open": "Sit i ulday", + "status.media.show": "Sit i uskan", "status.media_hidden": "Amidya yettwaffer", "status.mention": "Bder-d @{name}", "status.more": "Ugar", @@ -548,6 +593,7 @@ "status.show_less_all": "Semẓi akk tisuffɣin", "status.show_more": "Ssken-d ugar", "status.show_more_all": "Ẓerr ugar lebda", + "status.show_original": "Sken aɣbalu", "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}", "status.translate": "Suqel", "status.translated_from_with": "Yettwasuqel seg {lang} s {provider}", @@ -582,6 +628,7 @@ "upload_form.video_description": "Glem-d i yemdanen i yesɛan ugur deg tmesliwt neɣ deg yiẓri", "upload_modal.analyzing_picture": "Tasleḍt n tugna tetteddu…", "upload_modal.apply": "Snes", + "upload_modal.applying": "Asnas…", "upload_modal.choose_image": "Fren tugna", "upload_modal.description_placeholder": "Aberraɣ arurad ineggez nnig n uqjun amuṭṭis", "upload_modal.detect_text": "Sefru-d aḍris seg tugna", @@ -589,6 +636,7 @@ "upload_modal.preparing_ocr": "Aheyyi n OCR…", "upload_modal.preview_label": "Taskant ({ratio})", "upload_progress.label": "Asali iteddu...", + "upload_progress.processing": "Asesfer…", "username.taken": "Yettwaṭṭef yisem-a n useqdac. Ɛreḍ wayeḍ", "video.close": "Mdel tabidyutt", "video.download": "Sidered afaylu", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 041072c6adecef..701569fa05ce1c 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -35,6 +35,7 @@ "account.follow_back": "Sekot atpakaļ", "account.followers": "Sekotāji", "account.followers.empty": "Šim lietotājam vēl nav sekotāju.", + "account.followers_counter": "{count, plural, zero {{count} sekotāju} one {{count} sekotājs} other {{count} sekotāji}}", "account.following": "Seko", "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.", "account.go_to_profile": "Doties uz profilu", @@ -312,9 +313,9 @@ "home.column_settings.show_reblogs": "Rādīt pastiprinātos ierakstus", "home.column_settings.show_replies": "Rādīt atbildes", "home.hide_announcements": "Slēpt paziņojumus", - "home.pending_critical_update.body": "Lūdzu, pēc iespējas ātrāk atjaunini savu Mastodon serveri!", + "home.pending_critical_update.body": "Lūgums pēc iespējas drīzāk atjaunināt savu Mastodon serveri.", "home.pending_critical_update.link": "Skatīt jauninājumus", - "home.pending_critical_update.title": "Pieejams kritisks drošības jauninājums!", + "home.pending_critical_update.title": "Ir pieejams būtisks drošības atjauninājums.", "home.show_announcements": "Rādīt paziņojumus", "interaction_modal.description.favourite": "Ar Mastodon kontu tu vari pievienot šo ziņu izlasei, lai informētu autoru, ka to novērtē, un saglabātu to vēlākai lasīšanai.", "interaction_modal.description.follow": "Ar Mastodon kontu Tu vari sekot {name}, lai saņemtu lietotāja ierakstus savā mājas plūsmā.", diff --git a/app/javascript/mastodon/locales/ry.json b/app/javascript/mastodon/locales/ry.json index 67aad910054010..4f2e2410eff4a2 100644 --- a/app/javascript/mastodon/locales/ry.json +++ b/app/javascript/mastodon/locales/ry.json @@ -3,6 +3,8 @@ "about.contact": "Контакт:", "about.disclaimer": "Mastodon є задарьнов проґрамов из удпертым кодом тай торговов значков Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "Причины не ясні", + "about.domain_blocks.preamble": "Майбульш Mastodon поволят вам позирати контент тай комуніковати из хосновачами из другых федерованых серверув. Туй лиш уняткы учинені про сись конкретный сервер.", + "about.domain_blocks.silenced.explanation": "Вы майбульш не будете видіти профілі тай контент из сього сервера, кидь не будете го самі глядати авадь пудпишете ся на нього.", "about.domain_blocks.silenced.title": "Обмежено", "about.domain_blocks.suspended.explanation": "Ниякі податкы из сього сервера не будут уброблені, усокочені ци поміняні, што чинит невозможнов хоть-яку інтеракцію ци зязок из хосновачами из сього сервера.", "about.domain_blocks.suspended.title": "Заблоковано", @@ -20,6 +22,7 @@ "account.browse_more_on_origin_server": "Позирайте бульше на ориґіналнум профілю", "account.cancel_follow_request": "Удмінити пудписку", "account.copy": "Зкопіровати удкликованя на профіл", + "account.direct": "Пошептати @{name}", "account.disable_notifications": "Бульше не сповіщати ми коли {name} пише", "account.domain_blocked": "Домен заблокованый", "account.edit_profile": "Управити профіл", @@ -39,8 +42,10 @@ "account.joined_short": "Датум прикапчованя", "account.languages": "Поміняти убрані языкы", "account.link_verified_on": "Властность сього удкликованя было звірено {date}", + "account.locked_info": "Сись профіл є замкнутый. Ґазда акаунта буде ручно провіряти тко го може зафоловити.", "account.media": "Медіа", - "account.moved_to": "Хосновач {name} указав, ож новый профіл йим є:", + "account.mention": "Спомянути @{name}", + "account.moved_to": "Хосновач {name} указав, ож новый профіл му є:", "account.mute": "Стишити {name}", "account.mute_notifications_short": "Стишити голошіня", "account.mute_short": "Стишити", @@ -60,9 +65,12 @@ "account.unblock_short": "Розблоковати", "account.unendorse": "Не указовати на профілови", "account.unfollow": "Удписати ся", + "account.unmute": "Указовати {name}", "account.unmute_notifications_short": "Указовати голошіня", "account.unmute_short": "Указовати", "account_note.placeholder": "Клопкніт обы додати примітку", + "admin.dashboard.retention.average": "Середньоє", + "admin.dashboard.retention.cohort": "Місяць прикапчованя", "admin.dashboard.retention.cohort_size": "Нові хосновачі", "admin.impact_report.instance_accounts": "Профілі из акаунтув, котрі ся удалят", "admin.impact_report.instance_followers": "Пудписникы, котрых стратят наші хосновачі", @@ -70,11 +78,77 @@ "admin.impact_report.title": "Вплыв цілком", "alert.rate_limited.message": "Попробуйте зась по {retry_time, time, medium}.", "alert.rate_limited.title": "Частота обмежена", + "alert.unexpected.message": "Стала ся нечекана хыба.", + "alert.unexpected.title": "Ийой!", + "announcement.announcement": "Голошіня", + "audio.hide": "Зпрятати звук", + "block_modal.remote_users_caveat": "Попросиме ґазду сервера {domain} честовати вашоє рішеня. Айбо не ґарантуєме повный соглас, бо даякі серверы можут брати блокованя по-инчакому. Публичні дописы годно быти видко незалоґованым хосновачам.", + "block_modal.show_less": "Указати менше", + "block_modal.show_more": "Указати бульше", + "block_modal.they_cant_mention": "Они не можут вас споминати авадь слідовати.", + "block_modal.they_cant_see_posts": "Они не можут видіти ваші публикації, тай наспак — вы йихні.", + "block_modal.they_will_know": "Они видят, ож сут заблоковані.", + "block_modal.title": "Заблоковати хосновача?", + "block_modal.you_wont_see_mentions": "Не будете видіти публикації тай споминкы сього хосновача.", + "boost_modal.combo": "Можете клынцнути {combo} другый раз обы сесе пропустити", + "bundle_column_error.copy_stacktrace": "Укопіровати звіт за хыбу", + "bundle_column_error.error.body": "Не годни сьме указати зажадану сторунку. Годно быти спозад хыбы у нашум сістемі, авадь проблемы зумісности бравзера.", + "bundle_column_error.error.title": "Ийой!", + "bundle_column_error.network.body": "Стала ся хыба як сьме пробовали напаровати сторунку. Годно ся йсе было стати спозад слабого споєня вашого інтернета, авадь сервера.", + "bundle_column_error.network.title": "Хыба споєня", + "bundle_column_error.retry": "Попробуйте зась", "bundle_column_error.return": "Вернути ся на головну", "bundle_column_error.routing.body": "Не можеме найти сяку сторунку. Бизувні сьте, ож URL у адресному шорикови є добрый?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Заперти", "bundle_modal_error.message": "Штось ся показило, закидь сьме ладовали сись компонент.", "bundle_modal_error.retry": "Попробовати зась", - "closed_registrations.other_server_instructions": "Mastodon є децентралізованов платформов, можете си учинити профіл и на другому серверови тай комуніковати из сим." + "closed_registrations.other_server_instructions": "Mastodon є децентралізованов платформов, можете си учинити профіл и на другому серверови тай комуніковати из сим.", + "closed_registrations_modal.description": "Раз не мож учинити профіл на {domain}, айбо не мусите мати профіл ипен на серверови {domain} обы хосновати Mastodon.", + "closed_registrations_modal.find_another_server": "Найти другый сервер", + "column.about": "За сайт", + "column.blocks": "Заблоковані хосновачі", + "column.bookmarks": "Усокоченоє", + "column.direct": "Шептаня", + "column.directory": "Никати профілі", + "column.domain_blocks": "Заблоковані домены", + "column.favourites": "Убраноє", + "column.follow_requests": "Запросы на пудписку", + "column.lists": "Исписы", + "column.mutes": "Стишені хосновачі", + "column.notifications": "Убвіщеня", + "column.pins": "Закріплені публикації", + "column_back_button.label": "Назад", + "column_header.hide_settings": "Спрятати штімованя", + "column_header.moveLeft_settings": "Посунути колонку до ліва", + "column_header.moveRight_settings": "Посунути колонку до права", + "column_header.pin": "Закріпити", + "column_header.show_settings": "Указати штімованя", + "column_header.unpin": "Удкріпити", + "column_subheading.settings": "Штімованя", + "compose.language.change": "Поміняти язык", + "compose.language.search": "Глядати языкы...", + "compose.published.body": "Пост опубликованый.", + "compose.saved.body": "Пост усокоченый.", + "compose_form.direct_message_warning_learn_more": "Читайте бульше", + "compose_form.encryption_warning": "Публикації на Mastodon не шіфрувут ся. Не шырьте чутливу інформацію через Mastodon.", + "compose_form.hashtag_warning": "Сись пост не буде ся появляти у исписови по гештеґови, бо вун не є публичный. Лишек публичні посты буде видко за гештеґом.", + "compose_form.lock_disclaimer": "Ваш профіл є {locked}. Хоть-тко може ся на вас пудписати, обы видїти ваші ексклузівні посты.", + "compose_form.lock_disclaimer.lock": "замкнено", + "compose_form.placeholder": "Што нового?", + "compose_form.poll.duration": "Трывалость убзвідованя", + "compose_form.poll.multiple": "Дакулько варіантув", + "compose_form.poll.option_placeholder": "Варіант {number}", + "compose_form.poll.single": "Уберіт єден", + "compose_form.poll.switch_to_multiple": "Змінити убзвідованя обы поволити дакулько варіантув", + "compose_form.poll.switch_to_single": "Змінити убзвідованя обы поволити лишек єден варіант", + "compose_form.poll.type": "Стіл", + "compose_form.publish": "Публикація", + "compose_form.publish_form": "Нова публикація", + "compose_form.reply": "Удповідь", + "copypaste.copy_to_clipboard": "Копіровати у памнять", + "directory.recently_active": "Недавно актівні", + "disabled_account_banner.account_settings": "Штімованя акаунта", + "disabled_account_banner.text": "Ваш акаунт {disabledAccount} раз є неактівный.", + "dismissable_banner.community_timeline": "Туй сут недавні публикації уд профілув на серверови {domain}." } diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 150b808f894651..67ebb031aefcd0 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "Немає дописів", "account.featured_tags.title": "{name} виділяє хештеґи", "account.follow": "Підписатися", - "account.follow_back": "Підписатися взаємно", + "account.follow_back": "Стежити також", "account.followers": "Підписники", "account.followers.empty": "Ніхто ще не підписаний на цього користувача.", "account.followers_counter": "{count, plural, one {{counter} підписник} few {{counter} підписники} many {{counter} підписників} other {{counter} підписники}}", @@ -217,18 +217,18 @@ "domain_block_modal.title": "Заблокувати домен?", "domain_block_modal.you_will_lose_followers": "Усіх ваших підписників з цього сервера буде вилучено.", "domain_block_modal.you_wont_see_posts": "Ви не бачитимете дописів і сповіщень від користувачів на цьому сервері.", - "domain_pill.activitypub_lets_connect": "Це дозволяє вам спілкуватися та взаємодіяти з людьми не лише на Mastodon, але й у різних соціальних додатках.", - "domain_pill.activitypub_like_language": "ActivityPub - це як мова, якою Мастодонт розмовляє з іншими соціальними мережами.", + "domain_pill.activitypub_lets_connect": "Це дозволяє вам спілкуватися та взаємодіяти з людьми не лише на Mastodon, але й у різних соціальних застосунках.", + "domain_pill.activitypub_like_language": "ActivityPub - це як мова, якою Mastodon розмовляє з іншими соціальними мережами.", "domain_pill.server": "Сервер", "domain_pill.their_handle": "Їхня адреса:", - "domain_pill.their_server": "Їхній цифровий дім, де живуть усі їхні пости.", + "domain_pill.their_server": "Їхній цифровий дім, де живуть усі їхні дописи.", "domain_pill.their_username": "Їхній унікальний ідентифікатор на їхньому сервері. Ви можете знайти користувачів з однаковими іменами на різних серверах.", "domain_pill.username": "Ім'я користувача", "domain_pill.whats_in_a_handle": "Що є в адресі?", "domain_pill.who_they_are": "Оскільки дескриптори вказують, хто це і де він знаходиться, ви можете взаємодіяти з людьми через соціальну мережу платформ на основі .", "domain_pill.who_you_are": "Оскільки ваш нікнейм вказує, хто ви та де ви, люди можуть взаємодіяти з вами через соціальну мережу платформ на основі .", "domain_pill.your_handle": "Ваша адреса:", - "domain_pill.your_server": "Ваш цифровий дім, де живуть усі ваші публікації. Не подобається цей? Перенесіть сервери в будь-який час і залучайте своїх підписників.", + "domain_pill.your_server": "Ваш цифровий дім, де живуть усі ваші дописи. Не подобається цей? Перенесіть сервери в будь-який час і залучайте своїх підписників.", "domain_pill.your_username": "Ваш унікальний ідентифікатор на цьому сервері. Ви можете знайти користувачів з однаковими іменами на різних серверах.", "embed.instructions": "Вбудуйте цей допис до вашого вебсайту, скопіювавши код нижче.", "embed.preview": "Ось який вигляд це матиме:", @@ -489,9 +489,9 @@ "notification.reblog": "{name} поширює ваш допис", "notification.relationships_severance_event": "Втрачено з'єднання з {name}", "notification.relationships_severance_event.account_suspension": "Адміністратор з {from} призупинив {target}, що означає, що ви більше не можете отримувати оновлення від них або взаємодіяти з ними.", - "notification.relationships_severance_event.domain_block": "Адміністратор з {from} заблокував {target}, включаючи {followersCount} ваших підписників і {{followingCount, plural, one {# account} other {# accounts}}, на які ви підписані.", - "notification.relationships_severance_event.learn_more": "Дізнатися більше", - "notification.relationships_severance_event.user_domain_block": "Ви заблокували {target}, видаливши {followersCount} ваших підписників і {followingCount, plural, one {# account} other {# accounts}}, за якими ви стежите.", + "notification.relationships_severance_event.domain_block": "Адміністратор з {from} заблокував {target}, включаючи {followersCount} ваших підписників і {followingCount , plural, one {# обліковий запис} few {# облікові записи} many {# облікових записів} other {# обліковий запис}}, на які ви підписані.", + "notification.relationships_severance_event.learn_more": "Докладніше", + "notification.relationships_severance_event.user_domain_block": "Ви заблокували {target}, видаливши {followersCount} ваших підписників і {followingCount, plural, one {# обліковий запис} few {# облікові записи} many {# облікових записів} other {# обліковий запис}}, за якими ви стежите.", "notification.status": "{name} щойно дописує", "notification.update": "{name} змінює допис", "notification_requests.accept": "Прийняти", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 12eac79b984dfa..da86a4caa71aac 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1366,6 +1366,8 @@ body > [data-popper-placement] { min-height: 54px; border-bottom: 1px solid var(--background-border-color); cursor: auto; + opacity: 1; + animation: fade 150ms linear; @keyframes fade { 0% { @@ -1377,9 +1379,6 @@ body > [data-popper-placement] { } } - opacity: 1; - animation: fade 150ms linear; - .media-gallery, .video-player, .audio-player, @@ -4851,8 +4850,10 @@ a.status-card { &__menu { @include search-popout; - padding: 0; - background: $ui-secondary-color; + & { + padding: 0; + background: $ui-secondary-color; + } } &__menu-list { @@ -10453,7 +10454,7 @@ noscript { gap: 4px; dt { - flex: 0 0 auto; + flex: 0 1 auto; color: $dark-text-color; min-width: 0; overflow: hidden; diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb index dbfdd33fccaf3a..72992d2f42ad80 100644 --- a/app/lib/link_details_extractor.rb +++ b/app/lib/link_details_extractor.rb @@ -62,7 +62,8 @@ def date_modified end def author_name - author['name'] + name = author['name'] + name.is_a?(Array) ? name.join(', ') : name end def author_url @@ -156,11 +157,11 @@ def height end def title - html_entities.decode(structured_data&.headline || opengraph_tag('og:title') || document.xpath('//title').map(&:content).first).strip + html_entities_decode(structured_data&.headline || opengraph_tag('og:title') || document.xpath('//title').map(&:content).first)&.strip end def description - html_entities.decode(structured_data&.description || opengraph_tag('og:description') || meta_tag('description')) + html_entities_decode(structured_data&.description || opengraph_tag('og:description') || meta_tag('description')) end def published_at @@ -180,7 +181,7 @@ def canonical_url end def provider_name - html_entities.decode(structured_data&.publisher_name || opengraph_tag('og:site_name')) + html_entities_decode(structured_data&.publisher_name || opengraph_tag('og:site_name')) end def provider_url @@ -188,7 +189,7 @@ def provider_url end def author_name - html_entities.decode(structured_data&.author_name || opengraph_tag('og:author') || opengraph_tag('og:author:username')) + html_entities_decode(structured_data&.author_name || opengraph_tag('og:author') || opengraph_tag('og:author:username')) end def author_url @@ -257,7 +258,7 @@ def structured_data next if json_ld.blank? - structured_data = StructuredData.new(html_entities.decode(json_ld)) + structured_data = StructuredData.new(html_entities_decode(json_ld)) next unless structured_data.valid? @@ -273,10 +274,11 @@ def document end def detect_encoding_and_parse_document - [detect_encoding, nil, @html_charset, 'UTF-8'].uniq.each do |encoding| + [detect_encoding, nil, @html_charset].uniq.each do |encoding| document = Nokogiri::HTML(@html, nil, encoding) return document if document.to_s.valid_encoding? end + Nokogiri::HTML(@html, nil, 'UTF-8') end def detect_encoding @@ -290,6 +292,15 @@ def detector end end + def html_entities_decode(string) + return if string.nil? + + unicode_string = string.to_s.encode('UTF-8') + raise EncodingError, 'cannot convert string to valid UTF-8' unless unicode_string.valid_encoding? + + html_entities.decode(unicode_string) + end + def html_entities @html_entities ||= HTMLEntities.new(:expanded) end diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb index eac02ac14ff05c..5a11351e58808a 100644 --- a/app/models/preview_card.rb +++ b/app/models/preview_card.rb @@ -46,6 +46,11 @@ class PreviewCard < ApplicationRecord y_comp: 4, }.freeze + # URL size limit to safely store in PosgreSQL's unique indexes + # Technically this is a byte-size limit but we use it as a + # character limit to work with length validation + URL_CHARACTER_LIMIT = 2692 + self.inheritance_column = false enum :type, { link: 0, photo: 1, video: 2, rich: 3 } @@ -63,7 +68,7 @@ class PreviewCard < ApplicationRecord convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' }, validate_media_type: false - validates :url, presence: true, uniqueness: true, url: true + validates :url, presence: true, uniqueness: true, url: true, length: { maximum: URL_CHARACTER_LIMIT } validates_attachment_content_type :image, content_type: IMAGE_MIME_TYPES validates_attachment_size :image, less_than: LIMIT remotable_attachment :image, LIMIT diff --git a/app/models/status.rb b/app/models/status.rb index baa6578005532e..73f0052673569c 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -288,7 +288,7 @@ def ordered_media_attachments else map = media_attachments.index_by(&:id) ordered_media_attachment_ids.filter_map { |media_attachment_id| map[media_attachment_id] } - end + end.take(MEDIA_ATTACHMENTS_LIMIT) end def replies_count diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb index 089c42fb99493d..6e25a6f3bbdd6b 100644 --- a/app/models/status_edit.rb +++ b/app/models/status_edit.rb @@ -53,12 +53,14 @@ def emojis def ordered_media_attachments return @ordered_media_attachments if defined?(@ordered_media_attachments) - @ordered_media_attachments = if ordered_media_attachment_ids.nil? - [] - else - map = status.media_attachments.index_by(&:id) - ordered_media_attachment_ids.map.with_index { |media_attachment_id, index| PreservedMediaAttachment.new(media_attachment: map[media_attachment_id], description: media_descriptions[index]) } - end + @ordered_media_attachments = begin + if ordered_media_attachment_ids.nil? + [] + else + map = status.media_attachments.index_by(&:id) + ordered_media_attachment_ids.map.with_index { |media_attachment_id, index| PreservedMediaAttachment.new(media_attachment: map[media_attachment_id], description: media_descriptions[index]) } + end + end.take(Status::MEDIA_ATTACHMENTS_LIMIT) end def proper diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index 8bc9f912c55da0..adabb1096e86eb 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -15,9 +15,6 @@ class FetchLinkCardService < BaseService ) }iox - # URL size limit to safely store in PosgreSQL's unique indexes - BYTESIZE_LIMIT = 2692 - def call(status) @status = status @original_url = parse_urls @@ -32,7 +29,7 @@ def call(status) end attach_card if @card&.persisted? - rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Encoding::UndefinedConversionError => e + rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, EncodingError, ActiveRecord::RecordInvalid => e Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" } nil end @@ -88,7 +85,7 @@ def parse_urls def bad_url?(uri) # Avoid local instance URLs and invalid URLs - uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme) || uri.to_s.bytesize > BYTESIZE_LIMIT + uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme) end def mention_link?(anchor) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 53b02edc40227e..e1d98b8ba3be33 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -2,9 +2,21 @@ require_relative '../../lib/mastodon/sidekiq_middleware' +SIDEKIQ_WILL_PROCESSES_JOBS_FILE = Rails.root.join('tmp', 'sidekiq_process_has_started_and_will_begin_processing_jobs').freeze + Sidekiq.configure_server do |config| config.redis = REDIS_SIDEKIQ_PARAMS + # This is used in Kubernetes setups, to signal that the Sidekiq process has started and will begin processing jobs + # This comes from https://github.com/sidekiq/sidekiq/wiki/Kubernetes#sidekiq + config.on(:startup) do + FileUtils.touch(SIDEKIQ_WILL_PROCESSES_JOBS_FILE) + end + + config.on(:shutdown) do + FileUtils.rm_f(SIDEKIQ_WILL_PROCESSES_JOBS_FILE) + end + config.server_middleware do |chain| chain.add Mastodon::SidekiqMiddleware end diff --git a/config/initializers/vapid.rb b/config/initializers/vapid.rb index 7dd870c8b7d9af..551ede34fb9004 100644 --- a/config/initializers/vapid.rb +++ b/config/initializers/vapid.rb @@ -5,7 +5,7 @@ # You should only generate this once per instance. If you later decide to change it, all push subscription will # be invalidated, requiring the users to access the website again to resubscribe. # - # Generate with `rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose) + # Generate with `bundle exec rails mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web bundle exec rails mastodon:webpush:generate_vapid_key` if you use docker compose) # # For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html diff --git a/config/locales/activerecord.kab.yml b/config/locales/activerecord.kab.yml index b3ca90069b50ed..8cdc6501cbb494 100644 --- a/config/locales/activerecord.kab.yml +++ b/config/locales/activerecord.kab.yml @@ -21,6 +21,18 @@ kab: username: invalid: ilaq ad ilin isekkilen, uṭṭunen d yijerriden n wadda kan reserved: yettwaṭṭef + admin/webhook: + attributes: + url: + invalid: mačči d URL ameɣtu + doorkeeper/application: + attributes: + website: + invalid: mačči d URL ameɣtu + import: + attributes: + data: + malformed: yir amsal status: attributes: reblog: @@ -28,4 +40,20 @@ kab: user: attributes: email: + blocked: isseqdac asaǧǧaw n yimayl ur yettusirgen ara unreachable: ur d-ttban ara d akken yella + role_id: + elevated: ur yezmir ara ad iεeddi tamlilt-ik tamirant + user_role: + attributes: + permissions_as_keys: + dangerous: deg-s tisirag tiriɣelsanin i temlilt tazadurt + elevated: ur yezmir ara ad yesεu tirirag ur nelli ara deg temlilit-ik tamirant + own_role: ur yezmir ara ad yettwabeddel s temlilt-ik tamirant + position: + elevated: ur yezmir ara ad iεeddi tamlilt-ik tamirant + own_role: ur yezmir ara ad yettwabeddel s temlilt-ik tamirant + webhook: + attributes: + events: + invalid_permissions: ur yezmir ara ad yesεu tidyanin iwumi ur tesεiḍ ara tisirag diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 20e7e4d46b81d5..7e0aaaeefb6fe3 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -118,7 +118,7 @@ cs: promote: Povýšit protocol: Protokol public: Veřejný - push_subscription_expires: Odebírání PuSH expiruje + push_subscription_expires: Odebírání PuSH vyprší redownload: Obnovit profil redownloaded_msg: Profil účtu %{username} byl úspěšně obnoven ze zdroje reject: Zamítnout diff --git a/config/locales/devise.kab.yml b/config/locales/devise.kab.yml index 438c1df2b9a46f..3fbc58c1f57fcb 100644 --- a/config/locales/devise.kab.yml +++ b/config/locales/devise.kab.yml @@ -12,6 +12,7 @@ kab: last_attempt: Γur-k yiwen n uɛraḍ-nniḍen kan send ad yettucekkel umiḍan-ik. locked: Amiḍan-ik yettwargel. not_found_in_database: Tella tuccḍa deg %{authentication_keys} neγ deg wawal uffir. + omniauth_user_creation_failure: Tuccḍa lawan n tmerna n umiḍan i timagit-a. pending: Amiḍan-inek mazal-it deg ɛiwed n tmuγli. timeout: Tiɣimit n tuqqna tezri. Ma ulac aɣilif ɛiwed tuqqna akken ad tkemmleḍ. unauthenticated: Ilaq ad teqqneḍ neɣ ad tjerrḍeḍ akken ad tkemmelḍ. @@ -47,21 +48,41 @@ kab: subject: 'Mastodon: Iwellihen n uwennez n wawal uffir' title: Aɛiwed n wawal uffir two_factor_disabled: + explanation: Tuqqna tella tura s useqdec n tansa n yimayl tasuft d wawal n uεeddi. subject: 'Mastodon: Asesteb s snat n tarrayin yensa' + subtitle: Asesteb s snat tarrayin i umiḍan-ik yensan. title: Asesteb s snat n tarrayin insa two_factor_enabled: + explanation: Ajuṭu yettusirwen s usnas TOTP yeqqnen ilaq i wakken ad teqqneḍ. subject: 'Mastodon: Asesteb s snat n tarrayin yermed' + subtitle: Asesteb s snat tarrayin yettwarmed i umiḍan-ik. title: Asesteb s snat n tarrayin irmed two_factor_recovery_codes_changed: explanation: Tangalt n tuɣalin tettwaḥbes sakin nesnulfa-d yiwet d tamaynut. subject: 'Mastodon: Tingalin n tuɣalin n snat n tarayin ttwarnanat i tikkelt-nniḍen' + subtitle: Tangalt n tuɣalin tettwaḥbes sakin nesnulfa-d yiwet d tamaynut. title: Tangalt n tuɣalin 2FA tettwabeddel unlock_instructions: subject: 'Mastodon: iwelihhen n userreḥ' webauthn_credential: added: + explanation: Tasarut-a n tɣellist tettwarna ɣer umiḍan-ik·im subject: 'Maṣṭudun : Tasarutt tamaynutt n tɣellist' title: Tasarut tamaynutt n tɣellist tamaynut tettwarna + deleted: + explanation: Tasarut-a n tɣellist tettwakkes seg umiḍan-ik·im + subject: 'Mastodon: Tasarut n tɣellsit tettwakkes' + title: Yiwet seg tsura-k·m n tɣellist tettwakkes + webauthn_disabled: + explanation: Yensa usesteb s tsura n tɣellist i umiḍan-ik. + extra: Tzemreḍ ad tkecmeḍ tura s useqdec asuf n ujuṭu yettwasran s usnas TOPTP yeqqnen. + subject: 'Mastodon: Asesteb s tsura n tɣellist yensa' + title: Tisura n tɣellist nsant + webauthn_enabled: + explanation: Asesteb n tsarut n tɣellist tettwarmed i umiḍan-ik. + extra: Tasarut-ik n tɣellist tezmer tura ad tettuseqdec i unekcum. + subject: 'Mastodon: Asesteb n tsarut n tɣellist yermed' + title: Tisura n tɣellist remdent omniauth_callbacks: failure: Ur nezmir ara ad ak·akem-nsesṭeb seg %{kind} acku "%{reason}". success: Asesṭeb idda akken iwata seg umiḍan %{kind}. diff --git a/config/locales/doorkeeper.kab.yml b/config/locales/doorkeeper.kab.yml index 1b1a7df957645f..33aecd8c6f03d7 100644 --- a/config/locales/doorkeeper.kab.yml +++ b/config/locales/doorkeeper.kab.yml @@ -5,6 +5,7 @@ kab: doorkeeper/application: name: Isem n usnas redirect_uri: URI n uwelleh + scopes: Tinerfadin website: Asmel web n usnas errors: models: @@ -39,6 +40,7 @@ kab: empty: Ulac ɣur-k·m isnasen. name: Isem new: Asnas amaynut + scopes: Tinerfadin show: Ẓer title: Isnasen-ik·im new: @@ -47,6 +49,8 @@ kab: actions: Tigawin application_id: ID n usnas callback_urls: URL n tririt n wawal + scopes: Tinerfadin + secret: Tuffirt n umsaɣ title: 'Asnas: %{name}' authorizations: buttons: @@ -55,6 +59,7 @@ kab: error: title: Tella-d tuccḍa new: + review_permissions: Asenqed n tsirag title: Tlaq tsiregt show: title: Nɣel tangalt n wurag sakkin senteḍ-itt deg usnas. @@ -64,8 +69,12 @@ kab: confirmations: revoke: Tetḥeqqeḍ? index: + authorized_at: Yettwasireg ɣef %{date} description_html: Ha-t-an yisnasen i izemren ad kecmen ɣer umiḍan-ik·im, s useqdec n API. Ma llan yisnasen ur teεqileḍ ara da, neɣ kra n wesnas ur iteddu ara akken ilaq, tzemreḍ ad tekkseḍ anekcum-is. last_used_at: Yettwaseqdec i tikkelt taneggarut ass n %{date} + never_used: Urǧin yettwaseqdac + scopes: Tisirag + superapp: Adigan title: Isnasen-ik·im yettusirgen errors: messages: @@ -82,13 +91,28 @@ kab: destroy: notice: Yettwaḥwi wesnas. grouped_scopes: + access: + read: Anekcum i tɣuri kan + read/write: Anekcum i tɣuri d tira + write: Anekcum i tira kan title: accounts: Imiḍanen admin/accounts: Tadbelt n imiḍan + admin/all: Akk timahilin tinebdalin + admin/reports: Tadbelt n yineqqisen + blocks: Yewḥel + bookmarks: Ticraḍ + conversations: Idiwenniyen crypto: Awgelhen seg yixef ɣer yixef + favourites: Imenyafen filters: Imzizdigen + follow: Aḍfar, asgugem akked usewḥel + follows: Aḍfar lists: Tibdarin + media: Imeddayen n umidya + mutes: Yeggugem notifications: Tilɣa + profile: Amaɣnu-k Mastodon push: Tilɣa yettudemmren reports: Ineqqisen search: Nadi diff --git a/config/locales/doorkeeper.ko.yml b/config/locales/doorkeeper.ko.yml index 3ab0698d51c4ef..7ec357bf9fdec4 100644 --- a/config/locales/doorkeeper.ko.yml +++ b/config/locales/doorkeeper.ko.yml @@ -31,7 +31,7 @@ ko: form: error: 이런! 오류를 확인하세요 help: - native_redirect_uri: "%{native_redirect_uri}에서 로컬 테스트를 할 수 있습니다." + native_redirect_uri: "%{native_redirect_uri}를 이용해 로컬 테스트를 할 수 있습니다" redirect_uri: 한 줄에 하나의 URI를 작성하세요 scopes: 스페이스로 범위를 구분하세요. 빈 칸으로 놔두면 기본 범위를 사용합니다. index: diff --git a/config/locales/doorkeeper.lv.yml b/config/locales/doorkeeper.lv.yml index 5aa5daef3f6d16..11c50203050e4c 100644 --- a/config/locales/doorkeeper.lv.yml +++ b/config/locales/doorkeeper.lv.yml @@ -25,7 +25,7 @@ lv: edit: Labot submit: Apstiprināt confirmations: - destroy: Vai esi pārliecināts? + destroy: Vai tiešām? edit: title: Labot lietotni form: @@ -69,7 +69,7 @@ lv: buttons: revoke: Atsaukt confirmations: - revoke: Vai esi pārliecināts? + revoke: Vai tiešām? index: authorized_at: Autorizētas %{date} description_html: Šīs ir lietotnes, kas var piekļūt Tavam kontam ar API. Ja šeit ir lietotnes, kuras neatpazīsti, vai lietotne darbojas ne tā, kā paredzēts, vari atsaukt tās piekļuvi. @@ -135,6 +135,7 @@ lv: media: Multividesu pielikumi mutes: Apklusinātie notifications: Paziņojumi + profile: Tavs Mastodon profils push: Uznirstošie paziņojumi reports: Ziņojumi search: Meklēt @@ -165,6 +166,7 @@ lv: admin:write:reports: veikt moderācijas darbības pārskatos crypto: lieto pilnīgu šifrēšanu follow: mainīt konta attiecības + profile: lasīt tikai Tava konta profila informāciju push: saņemt savus push paziņojumus read: lasīt visus sava konta datus read:accounts: apskatīt kontu informāciju diff --git a/config/locales/gl.yml b/config/locales/gl.yml index ad4744e15b3e7b..c9f08dcad74d3a 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -31,18 +31,18 @@ gl: created_msg: Nota de moderación creada correctamente! destroyed_msg: Nota de moderación eliminada de xeito correcto! accounts: - add_email_domain_block: Bloquear o dominio do email + add_email_domain_block: Bloquear o dominio do enderezo approve: Aprobar approved_msg: Aprobada a solicitude de rexistro de %{username} are_you_sure: Está segura? avatar: Imaxe de perfil by_domain: Dominio change_email: - changed_msg: Email mudado de xeito correcto! - current_email: Email actual - label: Mudar email - new_email: Novo email - submit: Mudar email + changed_msg: Correo cambiado de xeito correcto! + current_email: Enderezo actual + label: Cambiar de enderezo + new_email: Novo enderezo + submit: Cambiar de enderezo title: Mudar email de %{username} change_role: changed_msg: Rol mudado correctamente! @@ -64,10 +64,10 @@ gl: display_name: Nome a amosar domain: Dominio edit: Editar - email: Email - email_status: Estado do email + email: Enderezo de correo + email_status: Estado do correo enable: Activar - enable_sign_in_token_auth: Activar autenticación cun token no email + enable_sign_in_token_auth: Activar autenticación cun token no correo enabled: Activado enabled_msg: Desbloqueada a conta de %{username} followers: Seguidoras @@ -132,7 +132,7 @@ gl: resubscribe: Resubscribir role: Rol search: Procurar - search_same_email_domain: Outras usuarias co mesmo dominio de email + search_same_email_domain: Outras usuarias co mesmo dominio de correo search_same_ip: Outras usuarias co mesmo IP security: Seguridade security_measures: @@ -154,9 +154,9 @@ gl: suspension_irreversible: Elimináronse de xeito irreversible os datos desta conta. Podes reactivar a conta para facela usable novamente pero non recuperará os datos eliminados. suspension_reversible_hint_html: Esta conta foi suspendida, e os datos serán totalmente eliminados o %{date}. Ata entón, a conta pode ser restaurada sen danos. Se desexas eliminar agora mesmo todos os datos da conta, podes facelo aquí embaixo. title: Contas - unblock_email: Desbloquear enderezo de email - unblocked_email_msg: Enderezo de email de %{username} desbloqueado - unconfirmed_email: Email non confirmado + unblock_email: Desbloquear enderezo de correo + unblocked_email_msg: Enderezo de correo de %{username} desbloqueado + unconfirmed_email: Enderezo de correo sen confirmar undo_sensitized: Desmarcar como sensible undo_silenced: Desfacer acalar undo_suspension: Desfacer suspensión @@ -173,12 +173,12 @@ gl: approve_appeal: Aprobar apelación approve_user: Aprobar Usuaria assigned_to_self_report: Asignar denuncia - change_email_user: Editar email da usuaria + change_email_user: Editar correo electrónico da usuaria change_role_user: Cambiar Rol da Usuaria confirm_user: Confirmar usuaria create_account_warning: Crear aviso create_announcement: Crear anuncio - create_canonical_email_block: Crear Bloqueo de email + create_canonical_email_block: Crear Bloqueo de correo electrónico create_custom_emoji: Crear emoticonas personalizadas create_domain_allow: Crear Dominio Permitido create_domain_block: Crear bloquedo do Dominio @@ -188,7 +188,7 @@ gl: create_user_role: Crear Rol demote_user: Degradar usuaria destroy_announcement: Eliminar anuncio - destroy_canonical_email_block: Eliminar Bloqueo de email + destroy_canonical_email_block: Eliminar Bloqueo de correo electrónico destroy_custom_emoji: Eliminar emoticona personalizada destroy_domain_allow: Eliminar Dominio permitido destroy_domain_block: Eliminar bloqueo do Dominio @@ -200,7 +200,7 @@ gl: destroy_user_role: Eliminar Rol disable_2fa_user: Desactivar 2FA disable_custom_emoji: Desactivar emoticona personalizada - disable_sign_in_token_auth_user: Desactivar Autenticación por token no email para Usuaria + disable_sign_in_token_auth_user: Desactivar Autenticación con token no correo para Usuaria disable_user: Desactivar usuaria enable_custom_emoji: Activar emoticona personalizada enable_sign_in_token_auth_user: Activar Autenticación con token no email para Usuaria @@ -211,14 +211,14 @@ gl: reject_user: Rexeitar Usuaria remove_avatar_user: Eliminar avatar reopen_report: Reabrir denuncia - resend_user: Reenviar o email de confirmación + resend_user: Reenviar o correo de confirmación reset_password_user: Restabelecer contrasinal resolve_report: Resolver denuncia sensitive_account: Marca o multimedia da túa conta como sensible silence_account: Silenciar conta suspend_account: Suspender conta unassigned_report: Desasignar denuncia - unblock_email_account: Desbloquear enderezo de email + unblock_email_account: Desbloquear enderezo de correo unsensitive_account: Retira a marca de sensible do multimedia da conta unsilence_account: Deixar de silenciar conta unsuspend_account: Retirar suspensión de conta @@ -660,7 +660,7 @@ gl: delete_data_html: Eliminar o perfil e contidos de @%{acct} para os próximos 30 días a non ser que sexa suspendida nese período preview_preamble_html: "@%{acct} vai recibir un aviso co seguinte contido:" record_strike_html: Anotar un aviso contra @%{acct} para axudarche a xestionar futuros problemas con esta conta - send_email_html: Enviar un email de aviso a @%{acct} + send_email_html: Enviar un correo de aviso a @%{acct} warning_placeholder: Razóns adicionais optativas para a acción de moderación. target_origin: Orixe da conta denunciada title: Denuncias @@ -1060,7 +1060,7 @@ gl: redirect_to_app_html: Ímoste redirixir á app %{app_name}. Se iso non acontece, proba %{clicking_this_link} ou volve ti manualmente á app. registration_complete: Completouse a creación da conta en %{domain}! welcome_title: Benvida, %{name}! - wrong_email_hint: Se o enderezo de email non é correcto, podes cambialo nos axustes da conta. + wrong_email_hint: Se o enderezo de correo non é correcto, podes cambialo nos axustes da conta. delete_account: Eliminar conta delete_account_html: Se queres eliminar a túa conta, podes facelo aquí. Deberás confirmar a acción. description: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index a8e2ade61df8e5..f7feb73ba0b03d 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1741,7 +1741,7 @@ ko: contrast: 마스토돈 (고대비) default: 마스토돈 (어두움) mastodon-light: 마스토돈 (밝음) - system: 자동 선택 (시스템 테마 이용) + system: 자동 (시스템 테마 사용) time: formats: default: "%Y-%m-%d %H:%M" diff --git a/config/locales/ro.yml b/config/locales/ro.yml index cd54d51051d838..79bc2a275f4045 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -116,6 +116,8 @@ ro: redownloaded_msg: S-a reîmprospătat cu succes profilul %{username} de la origine reject: Respinge rejected_msg: S-a respins cu succes cererea de înregistrare a utilizatorului %{username} + remote_suspension_irreversible: Datele acestui cont au fost șterse în mod ireversibil. + remote_suspension_reversible_hint_html: Contul a fost suspendat pe server-ul respectiv, iar datele vor fi șterse complet pe %{date}. Până atunci, server-ul remote poate restabili acest cont fără consecințe negative. Dacă dorești să elimini toate datele contului numaidecât, poți face acest lucru mai jos. remove_avatar: Elimină avatar remove_header: Elimină antet removed_avatar_msg: S-a îndepărtat cu succes poza de profil a utilizatorului %{username} diff --git a/config/locales/ry.yml b/config/locales/ry.yml index 6fe57b65cdb30e..e384b7f1b74810 100644 --- a/config/locales/ry.yml +++ b/config/locales/ry.yml @@ -1 +1,21 @@ +--- ry: + accounts: + follow: Пудписати ся + following: Пудпискы + posts: + few: Публикації + one: Публикація + other: Публикації + posts_tab_heading: Публикації + imports: + titles: + following: Імпортованя пудписок + types: + following: Испис пудписок + notification_mailer: + follow: + body: "%{name} ся пудписує ся на вас!" + subject: "%{name} ся пудписує ся на вас" + relationships: + following: Пудпискы diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index 0411c45bc169f4..e46ccb8737fd09 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -255,7 +255,7 @@ gl: require_invite_text: Pedir unha razón para unirse show_domain_blocks: Amosar dominios bloqueados show_domain_blocks_rationale: Explicar porque están bloqueados os dominios - site_contact_email: Email de contacto + site_contact_email: Correo de contacto site_contact_username: Nome do contacto site_extended_description: Descrición ampla site_short_description: Descrición do servidor diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml index 9461f16cd54577..63e2b9aacf1bf6 100644 --- a/config/locales/simple_form.kab.yml +++ b/config/locales/simple_form.kab.yml @@ -5,6 +5,7 @@ kab: account: display_name: Isem-ik·im ummid neɣ isem-ik·im n uqeṣṣer. fields: Asebter-ik·im agejdan, imqimen, leεmer, ayen tebɣiḍ. + note: 'Tzemreḍ ad d-@tbedreḍ imdanen niḍen neɣ #ihacṭagen.' account_alias: acct: Sekcem isem n umseqdac@domain n umiḍan s wansa itebγiḍ ad gujjeḍ account_migration: @@ -27,6 +28,8 @@ kab: name: 'Ha-t-an kra seg ihacṭagen i tesseqdaceḍ ussan-a ineggura maḍi :' imports: data: Afaylu CSV id yusan seg uqeddac-nniḍen n Maṣṭudun + invite_request: + text: Aya ad aɣ-iɛiwen ad nessenqed tuttra-k•m ip_block: comment: D afrayan. Cfu ɣef wayɣer i terniḍ alugen-a. severities: @@ -36,6 +39,8 @@ kab: fields: name: Tabzimt value: Agbur + account_alias: + acct: Tansa n umiḍan aqbur account_migration: acct: Tansa n umiḍan amaynut account_warning_preset: @@ -51,6 +56,7 @@ kab: suspend: Ḥbes di leεḍil announcement: ends_at: Tagara n tedyant + starts_at: Tazwara n tedyant text: Alɣu defaults: autofollow: Ɛreḍ-it-id ad yeḍfer amiḍan-ik·im @@ -59,18 +65,25 @@ kab: chosen_languages: Sizdeg tutlayin confirm_new_password: Sentem awal uffir amaynut confirm_password: Sentem awal uffir + context: Isatalen n umsizdeg current_password: Awal uffir n tura data: Isefka display_name: Isem ara d-yettwaskanen email: Tansa imayl expires_in: Ad yemmet + fields: Urtiyen niḍen header: Ixef + honeypot: "%{label} (ur tettaččar ara)" + inbox_url: URL n tbewwaḍt n urmas yettwacudden + irreversible: Kkes deg wadeg n tuffra locale: Tutlayt n wegrudem max_uses: Amḍan afellay n iseqdacen new_password: Awal uffir amaynut note: Tameddurt otp_attempt: Tangalt n snat n tarayin password: Awal uffir + phrase: Awal n tsarut neɣ tafyirt + setting_advanced_layout: Rmed agrudem n web leqqayen setting_default_language: Tutlayt n tira setting_default_privacy: Tabaḍnit n tira setting_display_media_default: Akk-a kan @@ -88,8 +101,15 @@ kab: featured_tag: name: Ahacṭag form_admin_settings: + custom_css: CSS udmawan + profile_directory: Rmed akaram n imaγnuten + site_contact_email: Imayl n unermas + site_short_description: Aglam n uqeddac site_terms: Tasertit tabaḍnit site_title: Isem n uqeddac + status_page_url: URL n uusebter n waddaden + theme: Asentel amezwer + thumbnail: Tanfult n uqeddac interactions: must_be_follower: Ssewḥel ilɣa sɣur wid akked tid ur yellin ara d imeḍfaren-ik·im must_be_following: Ssewḥel ilɣa sɣur wid akked tid ur tettḍafareḍ ara @@ -109,18 +129,25 @@ kab: follow: Yeḍfer-ik·im-id walbɛaḍ follow_request: Ma yella win i d-yessutren ad k·em-yeḍfer mention: Yuder-ik·em-id walbɛaḍ + pending_account: Amiḍan amaynut yesran asenqed reblog: Yella win yesselhan adda-dik·im + report: Aneqis amaynut yettwazen rule: hint: Isallen-nniḍen text: Alugen tag: name: Ahacṭag user: + role: Tamlilt time_zone: Tamnaḍt tasragant user_role: name: Isem permissions_as_keys: Tisirag + webhook: + events: Tidyanin turmidin 'no': Ala + not_recommended: Ur yettuwelleh ara + overridden: Yeččur recommended: Yettuwelleh required: mark: "*" diff --git a/config/locales/simple_form.ro.yml b/config/locales/simple_form.ro.yml index dfb44c77453e56..5df411b9512d3e 100644 --- a/config/locales/simple_form.ro.yml +++ b/config/locales/simple_form.ro.yml @@ -2,6 +2,12 @@ ro: simple_form: hints: + account: + discoverable: Este posibil ca postările și profilul tău să fie recomandate în diferite zone ale Mastodon, iar profilul tău ar poate fi sugerat altor utilizatori. + fields: Pagina ta principală, pronumele tale, vârsta, sau orice îți dorești. + indexable: Postările tale publice pot apărea în rezultatele căutărilor pe Mastodon. Persoanele care au interacționat cu postările tale vor putea să le caute oricând. + note: 'Poți @menționa alte persoane sau #hashtag-uri.' + unlocked: Alte persoane vă vor putea urmări fără a solicita aprobare. Debifați dacă doriți să revizuiți cererile și să alegeți dacă doriți să acceptați sau să respingeți noii urmăritori. account_alias: acct: Specificați numele de utilizator@domeniu al contului de la care doriți să treceți account_migration: @@ -23,12 +29,14 @@ ro: text: Poți folosi sintaxa de postare. Te rugăm să fii atent la spațiul pe care anunțul îl va ocupa pe ecranul utilizatorului defaults: autofollow: Persoanele care se înregistrează datorită invitației tale te vor urmări automat + avatar: WEBP, PNG, GIF sau JPG. Cel mult %{size}. Va fi redimensionată la %{dimensions}px bot: Acest cont performează în cea mai mare parte acțiuni automate și nu poate fi monitorizat context: Contextele în care filtrul trebuie aplicat current_password: În scopuri de securitate, vă rugăm să introduceţi parola contului curent current_username: Pentru a confirma, vă rugăm să introduceţi numele de utilizator al contului curent digest: Este trimis doar după o lungă perioadă de inactivitate și numai dacă primești mesaje personale în perioada de absență email: Vei primi un e-mail de confirmare + header: WEBP, PNG, GIF sau JPG. Cel mult %{size}. Va fi redimensionată la %{dimensions}px inbox_url: Copiază adresa URL de pe prima pagină a reului pe care vrei să îl utilizezi irreversible: Postările sortate vor dispărea ireversibil, chiar dacă filtrul este ulterior șters locale: Limba interfaței de utilizator, e-mailurile si notificările push @@ -36,17 +44,27 @@ ro: phrase: Vor fi potrivite indiferent de textul din casetă sau advertismentul unei postări scopes: La care API-uri aplicația are nevoie de acces. Dacă selectezi un scop principal nu mai e nevoie să selectezi fiecare sub-scop al acestuia. setting_aggregate_reblogs: Nu afișa impulsurile noi pentru postările care au fost deja recent impulsionate (afectează doar noile impulsuri primite) + setting_always_send_emails: În mod normal, notificările prin e-mail nu vor fi trimise când utilizați în mod activ Mastodon setting_default_sensitive: Fișierele media sensibile sunt ascunse implicit și pot fi dezvăluite cu un clic setting_display_media_default: Ascunde conținutul media marcat ca sensibil (NSFW) setting_display_media_hide_all: Întotdeauna ascunde tot conținutul media setting_display_media_show_all: Întotdeauna afișează conținutul media marcat ca sensibil setting_use_blurhash: Gradienții sunt bazați pe culorile vizualelor ascunse, dar ofuscă orice detalii setting_use_pending_items: Ascunde actualizările cronologice din spatele unui click în loc de a derula automat fluxul + username: Poți folosi litere, numere sau liniuțe de subliniere whole_word: Când fraza sau cuvântul este doar alfanumeric, acesta se aplică doar dacă există o potrivire completă domain_allow: domain: Acest domeniu va putea prelua date de pe acest server și datele primite de la el vor fi procesate și stocate email_domain_block: + domain: Acesta poate fi numele de domeniu care apare în adresa de e-mail sau în înregistrarea MX pe care o utilizează. Acestea vor fi verificate la înscriere. with_dns_records: Se va face o încercare de a rezolva înregistrările DNS ale domeniului dat și rezultatele vor fi de asemenea afișate pe lista neagră + featured_tag: + name: 'Iată câteva dintre hashtag-urile pe care le-ai folosit cel mai recent:' + filters: + action: Alege ce acţiune va fi efectuată atunci când o postare corespunde filtrului + actions: + hide: Ascunde complet conținutul filtrat, ca și cum nu ar exista + warn: Ascunde conținutul filtrat în spatele unui avertisment care menționează titlul filtrului form_challenge: current_password: Ați intrat într-o zonă securizată imports: diff --git a/config/routes.rb b/config/routes.rb index 4b3bd4f187a158..2c06762c229224 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -63,12 +63,16 @@ def redirect_with_vary(path) tokens: 'oauth/tokens' end - get '.well-known/oauth-authorization-server', to: 'well_known/oauth_metadata#show', as: :oauth_metadata, defaults: { format: 'json' } - get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' } - get '.well-known/nodeinfo', to: 'well_known/node_info#index', as: :nodeinfo, defaults: { format: 'json' } - get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger - get '.well-known/change-password', to: redirect('/auth/edit') - get '.well-known/proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" } + scope path: '.well-known' do + scope module: :well_known do + get 'oauth-authorization-server', to: 'oauth_metadata#show', as: :oauth_metadata, defaults: { format: 'json' } + get 'host-meta', to: 'host_meta#show', as: :host_meta, defaults: { format: 'xml' } + get 'nodeinfo', to: 'node_info#index', as: :nodeinfo, defaults: { format: 'json' } + get 'webfinger', to: 'webfinger#show', as: :webfinger + end + get 'change-password', to: redirect('/auth/edit'), as: nil + get 'proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }, as: nil + end get '/nodeinfo/2.0', to: 'well_known/node_info#show', as: :nodeinfo_schema @@ -94,7 +98,7 @@ def redirect_with_vary(path) namespace :auth do resource :setup, only: [:show, :update], controller: :setup - resource :challenge, only: [:create], controller: :challenges + resource :challenge, only: [:create] get 'sessions/security_key_options', to: 'sessions#webauthn_options' post 'captcha_confirmation', to: 'confirmations#confirm_captcha', as: :captcha_confirmation end diff --git a/config/routes/api.rb b/config/routes/api.rb index 3eb4bb4b4d58c4..9011916697452d 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -203,9 +203,11 @@ post :unmute end - resource :pin, only: :create, controller: 'accounts/pins' - post :unpin, to: 'accounts/pins#destroy' - resource :note, only: :create, controller: 'accounts/notes' + scope module: :accounts do + resource :pin, only: :create + post :unpin, to: 'pins#destroy' + resource :note, only: :create + end end resources :tags, only: [:show] do @@ -218,7 +220,7 @@ resources :followed_tags, only: [:index] resources :lists, only: [:index, :create, :show, :update, :destroy] do - resource :accounts, only: [:show, :create, :destroy], controller: 'lists/accounts' + resource :accounts, only: [:show, :create, :destroy], module: :lists end namespace :featured_tags do @@ -228,7 +230,7 @@ resources :featured_tags, only: [:index, :create, :destroy] resources :polls, only: [:create, :show] do - resources :votes, only: :create, controller: 'polls/votes' + resources :votes, only: :create, module: :polls end namespace :push do @@ -314,8 +316,10 @@ resources :suggestions, only: [:index] resource :instance, only: [:show] resources :filters, only: [:index, :create, :show, :update, :destroy] do - resources :keywords, only: [:index, :create], controller: 'filters/keywords' - resources :statuses, only: [:index, :create], controller: 'filters/statuses' + scope module: :filters do + resources :keywords, only: [:index, :create] + resources :statuses, only: [:index, :create] + end end namespace :filters do diff --git a/config/routes/settings.rb b/config/routes/settings.rb index 888fa9ecb55543..297b80942c9b5c 100644 --- a/config/routes/settings.rb +++ b/config/routes/settings.rb @@ -26,9 +26,9 @@ resources :follows, only: :index, controller: :following_accounts resources :blocks, only: :index, controller: :blocked_accounts resources :mutes, only: :index, controller: :muted_accounts - resources :lists, only: :index, controller: :lists + resources :lists, only: :index resources :domain_blocks, only: :index, controller: :blocked_domains - resources :bookmarks, only: :index, controller: :bookmarks + resources :bookmarks, only: :index end resources :two_factor_authentication_methods, only: [:index] do @@ -37,13 +37,13 @@ end end - resource :otp_authentication, only: [:show, :create], controller: 'two_factor_authentication/otp_authentication' + scope module: :two_factor_authentication do + resource :otp_authentication, only: [:show, :create], controller: :otp_authentication - resources :webauthn_credentials, only: [:index, :new, :create, :destroy], - path: 'security_keys', - controller: 'two_factor_authentication/webauthn_credentials' do - collection do - get :options + resources :webauthn_credentials, only: [:index, :new, :create, :destroy], path: 'security_keys' do + collection do + get :options + end end end diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index bf7f9bd70485c0..678ceee1158eb1 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -34,7 +34,7 @@ let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } - it 'redirects back to the strike page and notifies target account about approved appeal', :sidekiq_inline do + it 'redirects back to the strike page and notifies target account about approved appeal', :inline_jobs do emails = capture_emails { subject } expect(response) @@ -58,7 +58,7 @@ let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } - it 'redirects back to the strike page and notifies target account about rejected appeal', :sidekiq_inline do + it 'redirects back to the strike page and notifies target account about rejected appeal', :inline_jobs do emails = capture_emails { subject } expect(response) diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb index 87b08323da917c..eb2c6265d12eec 100644 --- a/spec/controllers/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/domain_blocks_controller_spec.rb @@ -176,7 +176,7 @@ end end - describe 'PUT #update', :sidekiq_inline do + describe 'PUT #update', :inline_jobs do subject do post :update, params: { :id => domain_block.id, :domain_block => { domain: 'example.com', severity: new_severity }, 'confirm' => '' } end diff --git a/spec/controllers/admin/resets_controller_spec.rb b/spec/controllers/admin/resets_controller_spec.rb index 10ed2cf969730c..0cbc3b60ab6f88 100644 --- a/spec/controllers/admin/resets_controller_spec.rb +++ b/spec/controllers/admin/resets_controller_spec.rb @@ -13,7 +13,7 @@ sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end - describe 'POST #create', :sidekiq_inline do + describe 'POST #create', :inline_jobs do it 'redirects to admin accounts page' do emails = capture_emails { subject } diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index e78554ec7dc3e8..9a94e5e1a1a464 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -123,7 +123,7 @@ user.update(current_sign_in_at: 1.month.ago) end - it 'logs the user in and sends suspicious email and redirects home', :sidekiq_inline do + it 'logs the user in and sends suspicious email and redirects home', :inline_jobs do emails = capture_emails { subject } expect(response) @@ -263,7 +263,7 @@ travel_to '2023-12-20T10:00:00Z' end - it 'does not log the user in, sets a flash message, and sends a suspicious sign in email', :sidekiq_inline do + it 'does not log the user in, sets a flash message, and sends a suspicious sign in email', :inline_jobs do emails = capture_emails do Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s } diff --git a/spec/controllers/concerns/user_tracking_concern_spec.rb b/spec/controllers/concerns/user_tracking_concern_spec.rb index b1de3cf4e2e2a0..f23d482f5f9303 100644 --- a/spec/controllers/concerns/user_tracking_concern_spec.rb +++ b/spec/controllers/concerns/user_tracking_concern_spec.rb @@ -75,7 +75,7 @@ def show expect(redis.ttl("account:#{user.account_id}:regeneration")).to be >= 0 end - it 'regenerates feed when sign in is older than two weeks', :sidekiq_inline do + it 'regenerates feed when sign in is older than two weeks', :inline_jobs do get :show expect_updated_sign_in_at(user) diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index 99d5a8b17f0252..3e874bbdcc0cab 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -17,7 +17,7 @@ let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } let(:params) { { strike_id: strike.id, appeal: { text: 'Foo' } } } - it 'notifies staff about new appeal and redirects back to strike page', :sidekiq_inline do + it 'notifies staff about new appeal and redirects back to strike page', :inline_jobs do emails = capture_emails { subject } expect(emails.size) @@ -36,7 +36,7 @@ let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } let(:params) { { strike_id: strike.id, appeal: { text: '' } } } - it 'does not send email and renders strike show page', :sidekiq_inline do + it 'does not send email and renders strike show page', :inline_jobs do emails = capture_emails { subject } expect(emails).to be_empty diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb index ccca4564e733a1..3342599bc1172e 100644 --- a/spec/controllers/settings/deletes_controller_spec.rb +++ b/spec/controllers/settings/deletes_controller_spec.rb @@ -50,7 +50,7 @@ delete :destroy, params: { form_delete_confirmation: { password: 'petsmoldoggos' } } end - it 'removes user record and redirects', :aggregate_failures, :sidekiq_inline do + it 'removes user record and redirects', :aggregate_failures, :inline_jobs do expect(response).to redirect_to '/auth/sign_in' expect(User.find_by(id: user.id)).to be_nil expect(user.account.reload).to be_suspended diff --git a/spec/fixtures/requests/latin1_posing_as_utf8_broken.txt b/spec/fixtures/requests/latin1_posing_as_utf8_broken.txt new file mode 100644 index 00000000000000..ed8a4716a3eba6 --- /dev/null +++ b/spec/fixtures/requests/latin1_posing_as_utf8_broken.txt @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +server: nginx +date: Thu, 13 Jun 2024 14:33:13 GMT +content-type: text/html; charset=utf-8 +content-length: 158 +accept-ranges: bytes + + + + + + Tofu l'orange + + +

Tofu l'orange

+ + diff --git a/spec/fixtures/requests/latin1_posing_as_utf8_recoverable.txt b/spec/fixtures/requests/latin1_posing_as_utf8_recoverable.txt new file mode 100644 index 00000000000000..a24985832ca551 --- /dev/null +++ b/spec/fixtures/requests/latin1_posing_as_utf8_recoverable.txt @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +server: nginx +date: Thu, 13 Jun 2024 14:33:13 GMT +content-type: text/html; charset=utf-8 +content-length: 158 +accept-ranges: bytes + + + + + + Tofu with orange sauce + + +

Tofu l'orange

+ + diff --git a/spec/fixtures/requests/long_canonical_url.txt b/spec/fixtures/requests/long_canonical_url.txt new file mode 100644 index 00000000000000..97d6c93961fb47 --- /dev/null +++ b/spec/fixtures/requests/long_canonical_url.txt @@ -0,0 +1,18 @@ +HTTP/1.1 200 OK +server: nginx +date: Thu, 13 Jun 2024 14:33:13 GMT +content-type: text/html; charset=utf-8 +content-length: 3225 +accept-ranges: bytes + + + + + + + Very long canonical URL + + +

We have very long URLs

+ + diff --git a/spec/fixtures/requests/page_without_title.txt b/spec/fixtures/requests/page_without_title.txt new file mode 100644 index 00000000000000..0054aa3b7e0db0 --- /dev/null +++ b/spec/fixtures/requests/page_without_title.txt @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +server: nginx +date: Thu, 13 Jun 2024 14:33:13 GMT +content-type: text/html; charset=utf-8 +content-length: 171 +accept-ranges: bytes + + + + + + + +

I am not a valid page

+

Thankfully, browsers do not care

+ + diff --git a/spec/lib/activitypub/activity/delete_spec.rb b/spec/lib/activitypub/activity/delete_spec.rb index 48421a116294b5..71977a96a2be81 100644 --- a/spec/lib/activitypub/activity/delete_spec.rb +++ b/spec/lib/activitypub/activity/delete_spec.rb @@ -47,7 +47,7 @@ expect(Status.find_by(id: status.id)).to be_nil end - it 'sends delete activity to followers of rebloggers', :sidekiq_inline do + it 'sends delete activity to followers of rebloggers', :inline_jobs do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end diff --git a/spec/lib/activitypub/activity/move_spec.rb b/spec/lib/activitypub/activity/move_spec.rb index 4dda014a068565..d69ef215161210 100644 --- a/spec/lib/activitypub/activity/move_spec.rb +++ b/spec/lib/activitypub/activity/move_spec.rb @@ -38,7 +38,7 @@ subject.perform end - context 'when all conditions are met', :sidekiq_inline do + context 'when all conditions are met', :inline_jobs do it 'sets moved account on old account' do expect(old_account.reload.moved_to_account_id).to eq new_account.id end diff --git a/spec/lib/link_details_extractor_spec.rb b/spec/lib/link_details_extractor_spec.rb index 26d9d4e2659821..2a4df70a8bf226 100644 --- a/spec/lib/link_details_extractor_spec.rb +++ b/spec/lib/link_details_extractor_spec.rb @@ -192,6 +192,35 @@ include_examples 'structured data' end + + context 'with author names as array' do + let(:ld_json) do + { + '@context' => 'https://schema.org', + '@type' => 'NewsArticle', + 'headline' => 'A lot of authors', + 'description' => 'But we decided to cram them into one', + 'author' => { + '@type' => 'Person', + 'name' => ['Author 1', 'Author 2'], + }, + }.to_json + end + let(:html) { <<~HTML } + + + + + + + HTML + + it 'joins author names' do + expect(subject.author_name).to eq 'Author 1, Author 2' + end + end end context 'when Open Graph protocol data is present' do diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb index e55db2f814a19e..49bc2b4a91c46c 100644 --- a/spec/models/admin/account_action_spec.rb +++ b/spec/models/admin/account_action_spec.rb @@ -69,7 +69,7 @@ end end - it 'sends email to target account user', :sidekiq_inline do + it 'sends email to target account user', :inline_jobs do emails = capture_emails { subject } expect(emails).to contain_exactly( diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb index 038d1d0c6cda8f..cb8cb5c11bd67e 100644 --- a/spec/models/custom_emoji_spec.rb +++ b/spec/models/custom_emoji_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe CustomEmoji, :paperclip_processing do +RSpec.describe CustomEmoji, :attachment_processing do describe '#search' do subject { described_class.search(search_term) } diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb index a8f1ce7745ee6e..24e8ca39c11f0e 100644 --- a/spec/models/media_attachment_spec.rb +++ b/spec/models/media_attachment_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe MediaAttachment, :paperclip_processing do +RSpec.describe MediaAttachment, :attachment_processing do describe 'local?' do subject { media_attachment.local? } diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index 271cf8690ecd7b..df67c365eb34a0 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -247,6 +247,41 @@ end end + describe '#ordered_media_attachments' do + let(:status) { Fabricate(:status) } + + let(:first_attachment) { Fabricate(:media_attachment) } + let(:second_attachment) { Fabricate(:media_attachment) } + let(:last_attachment) { Fabricate(:media_attachment) } + let(:extra_attachment) { Fabricate(:media_attachment) } + + before do + stub_const('Status::MEDIA_ATTACHMENTS_LIMIT', 3) + + # Add attachments out of order + status.media_attachments << second_attachment + status.media_attachments << last_attachment + status.media_attachments << extra_attachment + status.media_attachments << first_attachment + end + + context 'when ordered_media_attachment_ids is not set' do + it 'returns up to MEDIA_ATTACHMENTS_LIMIT attachments' do + expect(status.ordered_media_attachments.size).to eq Status::MEDIA_ATTACHMENTS_LIMIT + end + end + + context 'when ordered_media_attachment_ids is set' do + before do + status.update!(ordered_media_attachment_ids: [first_attachment.id, second_attachment.id, last_attachment.id, extra_attachment.id]) + end + + it 'returns up to MEDIA_ATTACHMENTS_LIMIT attachments in the expected order' do + expect(status.ordered_media_attachments).to eq [first_attachment, second_attachment, last_attachment] + end + end + end + describe '.mutes_map' do subject { described_class.mutes_map([status.conversation.id], account) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index fa0a0503a6561d..4755500fc4e356 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -101,7 +101,7 @@ end end - describe 'scopes', :sidekiq_inline do + describe 'scopes', :inline_jobs do describe 'recent' do it 'returns an array of recent users ordered by id' do first_user = Fabricate(:user) @@ -507,7 +507,7 @@ def within_duration_window_days context 'when user is new' do let(:confirmed_at) { nil } - it 'confirms user and delivers welcome email', :sidekiq_inline do + it 'confirms user and delivers welcome email', :inline_jobs do emails = capture_emails { subject } expect(user.confirmed_at).to be_present diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 38aa711089e325..79031f1a9430f7 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -120,7 +120,7 @@ def sign_in(resource, _deprecated = nil, scope: nil) end config.around do |example| - if example.metadata[:sidekiq_inline] == true + if example.metadata[:inline_jobs] == true Sidekiq::Testing.inline! else Sidekiq::Testing.fake! @@ -137,7 +137,7 @@ def sign_in(resource, _deprecated = nil, scope: nil) end config.before do |example| - unless example.metadata[:paperclip_processing] + unless example.metadata[:attachment_processing] allow_any_instance_of(Paperclip::Attachment).to receive(:post_process).and_return(true) # rubocop:disable RSpec/AnyInstance end end diff --git a/spec/requests/api/v1/admin/account_actions_spec.rb b/spec/requests/api/v1/admin/account_actions_spec.rb index 778658508ec100..5bcf809401da4c 100644 --- a/spec/requests/api/v1/admin/account_actions_spec.rb +++ b/spec/requests/api/v1/admin/account_actions_spec.rb @@ -10,7 +10,7 @@ let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } shared_examples 'a successful notification delivery' do - it 'notifies the user about the action taken', :sidekiq_inline do + it 'notifies the user about the action taken', :inline_jobs do emails = capture_emails { subject } expect(emails.size) diff --git a/spec/requests/api/v1/conversations_spec.rb b/spec/requests/api/v1/conversations_spec.rb index caa0f5c52c0975..f4776f18d97453 100644 --- a/spec/requests/api/v1/conversations_spec.rb +++ b/spec/requests/api/v1/conversations_spec.rb @@ -10,7 +10,7 @@ let(:other) { Fabricate(:user) } - describe 'GET /api/v1/conversations', :sidekiq_inline do + describe 'GET /api/v1/conversations', :inline_jobs do before do user.account.follow!(other.account) PostStatusService.new.call(other.account, text: 'Hey @alice', visibility: 'direct') diff --git a/spec/requests/api/v1/featured_tags_spec.rb b/spec/requests/api/v1/featured_tags_spec.rb index f499dd1d09a4d5..4b9698870411aa 100644 --- a/spec/requests/api/v1/featured_tags_spec.rb +++ b/spec/requests/api/v1/featured_tags_spec.rb @@ -147,7 +147,7 @@ expect(body).to be_empty end - it 'deletes the featured tag', :sidekiq_inline do + it 'deletes the featured tag', :inline_jobs do delete "/api/v1/featured_tags/#{id}", headers: headers featured_tag = FeaturedTag.find_by(id: id) diff --git a/spec/requests/api/v1/media_spec.rb b/spec/requests/api/v1/media_spec.rb index 26c76b9c5b98f6..c89c49afdf43aa 100644 --- a/spec/requests/api/v1/media_spec.rb +++ b/spec/requests/api/v1/media_spec.rb @@ -121,19 +121,19 @@ end end - context 'with image/jpeg', :paperclip_processing do + context 'with image/jpeg', :attachment_processing do let(:params) { { file: fixture_file_upload('attachment.jpg', 'image/jpeg'), description: 'jpeg image' } } it_behaves_like 'a successful media upload', 'image' end - context 'with image/gif', :paperclip_processing do + context 'with image/gif', :attachment_processing do let(:params) { { file: fixture_file_upload('attachment.gif', 'image/gif') } } it_behaves_like 'a successful media upload', 'image' end - context 'with video/webm', :paperclip_processing do + context 'with video/webm', :attachment_processing do let(:params) { { file: fixture_file_upload('attachment.webm', 'video/webm') } } it_behaves_like 'a successful media upload', 'gifv' diff --git a/spec/requests/api/v1/notifications/policies_spec.rb b/spec/requests/api/v1/notifications/policies_spec.rb index d02d2ed0d7b27d..cbd4499772d443 100644 --- a/spec/requests/api/v1/notifications/policies_spec.rb +++ b/spec/requests/api/v1/notifications/policies_spec.rb @@ -8,7 +8,7 @@ let(:scopes) { 'read:notifications write:notifications' } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } - describe 'GET /api/v1/notifications/policy', :sidekiq_inline do + describe 'GET /api/v1/notifications/policy', :inline_jobs do subject do get '/api/v1/notifications/policy', headers: headers, params: params end diff --git a/spec/requests/api/v1/notifications/requests_spec.rb b/spec/requests/api/v1/notifications/requests_spec.rb index 772402a6b5a089..23ddfd2bdabe45 100644 --- a/spec/requests/api/v1/notifications/requests_spec.rb +++ b/spec/requests/api/v1/notifications/requests_spec.rb @@ -8,7 +8,7 @@ let(:scopes) { 'read:notifications write:notifications' } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } - describe 'GET /api/v1/notifications/requests', :sidekiq_inline do + describe 'GET /api/v1/notifications/requests', :inline_jobs do subject do get '/api/v1/notifications/requests', headers: headers, params: params end diff --git a/spec/requests/api/v1/notifications_spec.rb b/spec/requests/api/v1/notifications_spec.rb index 55d3cdac948896..9ff0674317bedd 100644 --- a/spec/requests/api/v1/notifications_spec.rb +++ b/spec/requests/api/v1/notifications_spec.rb @@ -8,7 +8,7 @@ let(:scopes) { 'read:notifications write:notifications' } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } - describe 'GET /api/v1/notifications', :sidekiq_inline do + describe 'GET /api/v1/notifications', :inline_jobs do subject do get '/api/v1/notifications', headers: headers, params: params end diff --git a/spec/requests/api/v1/polls/votes_spec.rb b/spec/requests/api/v1/polls/votes_spec.rb index e2b22708be8720..669f64b6e4577e 100644 --- a/spec/requests/api/v1/polls/votes_spec.rb +++ b/spec/requests/api/v1/polls/votes_spec.rb @@ -10,9 +10,10 @@ describe 'POST /api/v1/polls/:poll_id/votes' do let(:poll) { Fabricate(:poll) } + let(:params) { { choices: %w(1) } } before do - post "/api/v1/polls/#{poll.id}/votes", params: { choices: %w(1) }, headers: headers + post "/api/v1/polls/#{poll.id}/votes", params: params, headers: headers end it 'creates a vote', :aggregate_failures do @@ -24,6 +25,14 @@ expect(poll.reload.cached_tallies).to eq [0, 1] end + context 'when the required choices param is not provided' do + let(:params) { {} } + + it 'returns http bad request' do + expect(response).to have_http_status(400) + end + end + private def vote diff --git a/spec/requests/api/v1/reports_spec.rb b/spec/requests/api/v1/reports_spec.rb index 9e8954a4c65dd8..491c6263d3397e 100644 --- a/spec/requests/api/v1/reports_spec.rb +++ b/spec/requests/api/v1/reports_spec.rb @@ -33,7 +33,7 @@ it_behaves_like 'forbidden for wrong scope', 'read read:reports' - it 'creates a report', :aggregate_failures, :sidekiq_inline do + it 'creates a report', :aggregate_failures, :inline_jobs do emails = capture_emails { subject } expect(response).to have_http_status(200) diff --git a/spec/requests/api/v1/statuses/favourites_spec.rb b/spec/requests/api/v1/statuses/favourites_spec.rb index 033aed7e285ddc..22d0e4831fc64d 100644 --- a/spec/requests/api/v1/statuses/favourites_spec.rb +++ b/spec/requests/api/v1/statuses/favourites_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe 'Favourites', :sidekiq_inline do +RSpec.describe 'Favourites', :inline_jobs do let(:user) { Fabricate(:user) } let(:scopes) { 'write:favourites' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } diff --git a/spec/requests/api/v1/statuses/reblogs_spec.rb b/spec/requests/api/v1/statuses/reblogs_spec.rb index cf0a1f861d9bde..503d804ed01c0b 100644 --- a/spec/requests/api/v1/statuses/reblogs_spec.rb +++ b/spec/requests/api/v1/statuses/reblogs_spec.rb @@ -41,7 +41,7 @@ end end - describe 'POST /api/v1/statuses/:status_id/unreblog', :sidekiq_inline do + describe 'POST /api/v1/statuses/:status_id/unreblog', :inline_jobs do context 'with public status' do let(:status) { Fabricate(:status, account: user.account) } diff --git a/spec/requests/api/v1/timelines/home_spec.rb b/spec/requests/api/v1/timelines/home_spec.rb index 2bebe8cf452847..96bd153affe5a4 100644 --- a/spec/requests/api/v1/timelines/home_spec.rb +++ b/spec/requests/api/v1/timelines/home_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'Home', :sidekiq_inline do +describe 'Home', :inline_jobs do let(:user) { Fabricate(:user) } let(:scopes) { 'read:statuses' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } diff --git a/spec/requests/api/v2/media_spec.rb b/spec/requests/api/v2/media_spec.rb index 990fa5d0baeeab..97540413f152d4 100644 --- a/spec/requests/api/v2/media_spec.rb +++ b/spec/requests/api/v2/media_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe 'Media API', :paperclip_processing do +RSpec.describe 'Media API', :attachment_processing do let(:user) { Fabricate(:user) } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } let(:scopes) { 'write' } diff --git a/spec/requests/api/v2_alpha/notifications_spec.rb b/spec/requests/api/v2_alpha/notifications_spec.rb index ac44605ac5d212..104651ebe39f44 100644 --- a/spec/requests/api/v2_alpha/notifications_spec.rb +++ b/spec/requests/api/v2_alpha/notifications_spec.rb @@ -8,7 +8,7 @@ let(:scopes) { 'read:notifications write:notifications' } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } - describe 'GET /api/v2_alpha/notifications', :sidekiq_inline do + describe 'GET /api/v2_alpha/notifications', :inline_jobs do subject do get '/api/v2_alpha/notifications', headers: headers, params: params end diff --git a/spec/search/models/concerns/account/statuses_search_spec.rb b/spec/search/models/concerns/account/statuses_search_spec.rb index a1b0bf405c5133..b1bf4968ca9abd 100644 --- a/spec/search/models/concerns/account/statuses_search_spec.rb +++ b/spec/search/models/concerns/account/statuses_search_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Account::StatusesSearch, :sidekiq_inline do +describe Account::StatusesSearch, :inline_jobs do describe 'a non-indexable account becoming indexable' do let(:account) { Account.find_by(username: 'search_test_account_1') } diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index a86f141fe0b747..c3adb9c470afd1 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -225,7 +225,7 @@ end end - context 'with statuses referencing other statuses', :sidekiq_inline do + context 'with statuses referencing other statuses', :inline_jobs do before do stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5 end diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index 8b80dafe45a924..4fbb527b39041e 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -224,7 +224,7 @@ end end - it 'creates accounts without exceeding rate limit', :sidekiq_inline do + it 'creates accounts without exceeding rate limit', :inline_jobs do expect { subject.call('user1', 'foo.test', payload) } .to create_some_remote_accounts .and create_fewer_than_rate_limit_accounts diff --git a/spec/services/appeal_service_spec.rb b/spec/services/appeal_service_spec.rb index 3fad74db9d8951..6a47bb2cea61d2 100644 --- a/spec/services/appeal_service_spec.rb +++ b/spec/services/appeal_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe AppealService, :sidekiq_inline do +RSpec.describe AppealService, :inline_jobs do describe '#call' do let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } diff --git a/spec/services/authorize_follow_service_spec.rb b/spec/services/authorize_follow_service_spec.rb index be2a8641854054..533b791fb7f6e7 100644 --- a/spec/services/authorize_follow_service_spec.rb +++ b/spec/services/authorize_follow_service_spec.rb @@ -41,7 +41,7 @@ expect(bob.following?(sender)).to be true end - it 'sends an accept activity', :sidekiq_inline do + it 'sends an accept activity', :inline_jobs do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index e501b9ba84a94c..628bb198ef06f3 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe BatchedRemoveStatusService, :sidekiq_inline do +RSpec.describe BatchedRemoveStatusService, :inline_jobs do subject { described_class.new } let!(:alice) { Fabricate(:account) } diff --git a/spec/services/block_domain_service_spec.rb b/spec/services/block_domain_service_spec.rb index d4f0c042d453c9..839137db4498e8 100644 --- a/spec/services/block_domain_service_spec.rb +++ b/spec/services/block_domain_service_spec.rb @@ -49,7 +49,7 @@ end describe 'for a silence with reject media' do - it 'does not mark the domain as blocked, but silences accounts with an appropriate silencing date, clears media', :aggregate_failures, :sidekiq_inline do + it 'does not mark the domain as blocked, but silences accounts with an appropriate silencing date, clears media', :aggregate_failures, :inline_jobs do subject.call(DomainBlock.create!(domain: 'evil.org', severity: :silence, reject_media: true)) expect(DomainBlock.blocked?('evil.org')).to be false diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index d096aa1ea35566..46dd69198699a4 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -33,7 +33,7 @@ expect(sender.blocking?(bob)).to be true end - it 'sends a block activity', :sidekiq_inline do + it 'sends a block activity', :inline_jobs do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index de93862435afbe..741ac340cfa0be 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -62,7 +62,7 @@ def expect_deletion_of_associated_target_notifications end end - describe '#call on local account', :sidekiq_inline do + describe '#call on local account', :inline_jobs do before do stub_request(:post, remote_alice.inbox_url).to_return(status: 201) stub_request(:post, remote_bob.inbox_url).to_return(status: 201) @@ -83,7 +83,7 @@ def expect_deletion_of_associated_target_notifications end end - describe '#call on remote account', :sidekiq_inline do + describe '#call on remote account', :inline_jobs do before do stub_request(:post, account.inbox_url).to_return(status: 201) end diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index b51d802a5b9ae2..82cdffb8cf9f5c 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -38,7 +38,7 @@ def home_feed_of(account) expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of a follower', :sidekiq_inline do + it 'is added to the home feed of a follower', :inline_jobs do expect(home_feed_of(bob)).to include status.id expect(home_feed_of(tom)).to include status.id end @@ -62,7 +62,7 @@ def home_feed_of(account) expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of the mentioned follower', :sidekiq_inline do + it 'is added to the home feed of the mentioned follower', :inline_jobs do expect(home_feed_of(bob)).to include status.id end @@ -83,7 +83,7 @@ def home_feed_of(account) expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of a follower', :sidekiq_inline do + it 'is added to the home feed of a follower', :inline_jobs do expect(home_feed_of(bob)).to include status.id expect(home_feed_of(tom)).to include status.id end @@ -101,7 +101,7 @@ def home_feed_of(account) expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of the mentioned follower', :sidekiq_inline do + it 'is added to the home feed of the mentioned follower', :inline_jobs do expect(home_feed_of(bob)).to include status.id end diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb index d0f1ff17c1ebd9..c39362def2f7f3 100644 --- a/spec/services/favourite_service_spec.rb +++ b/spec/services/favourite_service_spec.rb @@ -33,7 +33,7 @@ expect(status.favourites.first).to_not be_nil end - it 'sends a like activity', :sidekiq_inline do + it 'sends a like activity', :inline_jobs do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb index d83a5275149962..342902cdb3d894 100644 --- a/spec/services/fetch_link_card_service_spec.rb +++ b/spec/services/fetch_link_card_service_spec.rb @@ -27,7 +27,11 @@ stub_request(:get, 'http://example.com/koi8-r').to_return(request_fixture('koi8-r.txt')) stub_request(:get, 'http://example.com/windows-1251').to_return(request_fixture('windows-1251.txt')) stub_request(:get, 'http://example.com/low_confidence_latin1').to_return(request_fixture('low_confidence_latin1.txt')) + stub_request(:get, 'http://example.com/latin1_posing_as_utf8_broken').to_return(request_fixture('latin1_posing_as_utf8_broken.txt')) + stub_request(:get, 'http://example.com/latin1_posing_as_utf8_recoverable').to_return(request_fixture('latin1_posing_as_utf8_recoverable.txt')) stub_request(:get, 'http://example.com/aergerliche-umlaute').to_return(request_fixture('redirect_with_utf8_url.txt')) + stub_request(:get, 'http://example.com/page_without_title').to_return(request_fixture('page_without_title.txt')) + stub_request(:get, 'http://example.com/long_canonical_url').to_return(request_fixture('long_canonical_url.txt')) Rails.cache.write('oembed_endpoint:example.com', oembed_cache) if oembed_cache @@ -110,6 +114,14 @@ end end + context 'with a page that has no title' do + let(:status) { Fabricate(:status, text: 'http://example.com/page_without_title') } + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end + context 'with a 404 URL' do let(:status) { Fabricate(:status, text: 'http://example.com/not-found') } @@ -159,10 +171,30 @@ end context 'with a URL of a page in ISO-8859-1 encoding, that charlock_holmes cannot detect' do - let(:status) { Fabricate(:status, text: 'Check out http://example.com/low_confidence_latin1') } + context 'when encoding in http header is correct' do + let(:status) { Fabricate(:status, text: 'Check out http://example.com/low_confidence_latin1') } - it 'decodes the HTML' do - expect(status.preview_card.title).to eq("Tofu á l'orange") + it 'decodes the HTML' do + expect(status.preview_card.title).to eq("Tofu á l'orange") + end + end + + context 'when encoding in http header is incorrect' do + context 'when encoding problems appear in unrelated tags' do + let(:status) { Fabricate(:status, text: 'Check out http://example.com/latin1_posing_as_utf8_recoverable') } + + it 'decodes the HTML' do + expect(status.preview_card.title).to eq('Tofu with orange sauce') + end + end + + context 'when encoding problems appear in title tag' do + let(:status) { Fabricate(:status, text: 'Check out http://example.com/latin1_posing_as_utf8_broken') } + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end end end @@ -202,19 +234,6 @@ end end - context 'with an URL too long for PostgreSQL unique indexes' do - let(:url) { "http://example.com/#{'a' * 2674}" } - let(:status) { Fabricate(:status, text: url) } - - it 'does not fetch the URL' do - expect(a_request(:get, url)).to_not have_been_made - end - - it 'does not create a preview card' do - expect(status.preview_card).to be_nil - end - end - context 'with a URL of a page with oEmbed support' do let(:html) { 'Hello world' } let(:status) { Fabricate(:status, text: 'http://example.com/html') } @@ -265,6 +284,14 @@ end end end + + context 'with a URL of a page that includes a canonical URL too long for PostgreSQL unique indexes' do + let(:status) { Fabricate(:status, text: 'test http://example.com/long_canonical_url') } + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end end context 'with a remote status' do diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb index bea2412a3d36fe..0c4cd600460922 100644 --- a/spec/services/follow_service_spec.rb +++ b/spec/services/follow_service_spec.rb @@ -150,7 +150,7 @@ expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil end - it 'sends a follow activity to the inbox', :sidekiq_inline do + it 'sends a follow activity to the inbox', :inline_jobs do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index 90877d99975200..0a99c5e748db55 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ImportService, :sidekiq_inline do +RSpec.describe ImportService, :inline_jobs do include RoutingHelper let!(:account) { Fabricate(:account, locked: false) } diff --git a/spec/services/mute_service_spec.rb b/spec/services/mute_service_spec.rb index 681afc0b16ec39..3bde92b87aebdc 100644 --- a/spec/services/mute_service_spec.rb +++ b/spec/services/mute_service_spec.rb @@ -17,7 +17,7 @@ redis.del(home_timeline_key) end - it "clears account's statuses", :sidekiq_inline do + it "clears account's statuses", :inline_jobs do FeedManager.instance.push_to_home(account, status) FeedManager.instance.push_to_home(account, other_account_status) diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb index 8c810f1c32b521..c695855bec0d1c 100644 --- a/spec/services/notify_service_spec.rb +++ b/spec/services/notify_service_spec.rb @@ -105,7 +105,7 @@ context 'when email notification is enabled' do let(:enabled) { true } - it 'sends email', :sidekiq_inline do + it 'sends email', :inline_jobs do emails = capture_emails { subject } expect(emails.size) diff --git a/spec/services/reject_follow_service_spec.rb b/spec/services/reject_follow_service_spec.rb index 98aaf70478539b..d2c7a00206210b 100644 --- a/spec/services/reject_follow_service_spec.rb +++ b/spec/services/reject_follow_service_spec.rb @@ -41,7 +41,7 @@ expect(bob.following?(sender)).to be false end - it 'sends a reject activity', :sidekiq_inline do + it 'sends a reject activity', :inline_jobs do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/remove_from_followers_service_spec.rb b/spec/services/remove_from_followers_service_spec.rb index d6420f76742dfe..515600096cfc04 100644 --- a/spec/services/remove_from_followers_service_spec.rb +++ b/spec/services/remove_from_followers_service_spec.rb @@ -33,7 +33,7 @@ expect(bob.followed_by?(sender)).to be false end - it 'sends a reject activity', :sidekiq_inline do + it 'sends a reject activity', :inline_jobs do expect(a_request(:post, sender.inbox_url)).to have_been_made.once end end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index 917b66c6df467b..08f519b5360d99 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe RemoveStatusService, :sidekiq_inline do +RSpec.describe RemoveStatusService, :inline_jobs do subject { described_class.new } let!(:alice) { Fabricate(:account) } diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb index 141dc8c3be5623..bf1f937191b74c 100644 --- a/spec/services/report_service_spec.rb +++ b/spec/services/report_service_spec.rb @@ -23,7 +23,7 @@ stub_request(:post, 'http://example.com/inbox').to_return(status: 200) end - context 'when forward is true', :sidekiq_inline do + context 'when forward is true', :inline_jobs do let(:forward) { true } it 'sends ActivityPub payload when forward is true' do diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index 316266c8f8e539..e0084a15791a1a 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -195,7 +195,7 @@ expect(account.uri).to eq 'https://ap.example.com/users/foo' end - it 'merges accounts', :sidekiq_inline do + it 'merges accounts', :inline_jobs do account = subject.call('foo@ap.example.com') expect(status.reload.account_id).to eq account.id diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index 7c72a4776b4b1d..4a2f494e0cb1b8 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe SuspendAccountService, :sidekiq_inline do +RSpec.describe SuspendAccountService, :inline_jobs do shared_examples 'common behavior' do subject { described_class.new.call(account) } diff --git a/spec/services/unallow_domain_service_spec.rb b/spec/services/unallow_domain_service_spec.rb index caec3d596ff144..4bf6c540432027 100644 --- a/spec/services/unallow_domain_service_spec.rb +++ b/spec/services/unallow_domain_service_spec.rb @@ -13,7 +13,7 @@ let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: bad_domain, suspended: true, silenced: true) } let!(:domain_allow) { Fabricate(:domain_allow, domain: bad_domain) } - context 'with limited federation mode', :sidekiq_inline do + context 'with limited federation mode', :inline_jobs do before do allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) end diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb index 4c9fcb9aeecdd0..6132e74415ecd6 100644 --- a/spec/services/unblock_service_spec.rb +++ b/spec/services/unblock_service_spec.rb @@ -33,7 +33,7 @@ expect(sender.blocking?(bob)).to be false end - it 'sends an unblock activity', :sidekiq_inline do + it 'sends an unblock activity', :inline_jobs do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb index bba17a8d2709a2..0c206c4b983215 100644 --- a/spec/services/unfollow_service_spec.rb +++ b/spec/services/unfollow_service_spec.rb @@ -20,7 +20,7 @@ end end - describe 'remote ActivityPub', :sidekiq_inline do + describe 'remote ActivityPub', :inline_jobs do let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do @@ -38,7 +38,7 @@ end end - describe 'remote ActivityPub (reverse)', :sidekiq_inline do + describe 'remote ActivityPub (reverse)', :inline_jobs do let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb index 79a4441d3ec9ef..8d4882c37f88aa 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -45,7 +45,7 @@ def match_update_actor_request(req, account) remote_follower.follow!(account) end - it 'merges back into feeds of local followers and sends update', :sidekiq_inline do + it 'merges back into feeds of local followers and sends update', :inline_jobs do subject expect_feeds_merged diff --git a/spec/services/update_account_service_spec.rb b/spec/services/update_account_service_spec.rb index 5204f1f34d469d..d066db481e5568 100644 --- a/spec/services/update_account_service_spec.rb +++ b/spec/services/update_account_service_spec.rb @@ -5,7 +5,7 @@ RSpec.describe UpdateAccountService do subject { described_class.new } - describe 'switching form locked to unlocked accounts', :sidekiq_inline do + describe 'switching form locked to unlocked accounts', :inline_jobs do let(:account) { Fabricate(:account, locked: true) } let(:alice) { Fabricate(:account) } let(:bob) { Fabricate(:account) } diff --git a/spec/support/examples/models/concerns/account_avatar.rb b/spec/support/examples/models/concerns/account_avatar.rb index 2c9b5514aad7d6..ab6020d834a8f7 100644 --- a/spec/support/examples/models/concerns/account_avatar.rb +++ b/spec/support/examples/models/concerns/account_avatar.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true shared_examples 'AccountAvatar' do |fabricator| - describe 'static avatars', :paperclip_processing do + describe 'static avatars', :attachment_processing do describe 'when GIF' do it 'creates a png static style' do account = Fabricate(fabricator, avatar: attachment_fixture('avatar.gif')) @@ -17,7 +17,7 @@ end end - describe 'base64-encoded files', :paperclip_processing do + describe 'base64-encoded files', :attachment_processing do let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('attachment.jpg').read)}" } let(:account) { Fabricate(fabricator, avatar: base64_attachment) } diff --git a/spec/support/examples/models/concerns/account_header.rb b/spec/support/examples/models/concerns/account_header.rb index ce09eb006b8ae4..43bbdaacf425d9 100644 --- a/spec/support/examples/models/concerns/account_header.rb +++ b/spec/support/examples/models/concerns/account_header.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true shared_examples 'AccountHeader' do |fabricator| - describe 'base64-encoded files', :paperclip_processing do + describe 'base64-encoded files', :attachment_processing do let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('attachment.jpg').read)}" } let(:account) { Fabricate(fabricator, header: base64_attachment) } diff --git a/spec/system/admin/accounts_spec.rb b/spec/system/admin/accounts_spec.rb index 54d755b914de12..20813f6be42505 100644 --- a/spec/system/admin/accounts_spec.rb +++ b/spec/system/admin/accounts_spec.rb @@ -48,7 +48,7 @@ end end - context 'with action of `reject`', :sidekiq_inline do + context 'with action of `reject`', :inline_jobs do it 'rejects and removes the account' do batch_checkbox_for(unapproved_user_account).check diff --git a/spec/system/new_statuses_spec.rb b/spec/system/new_statuses_spec.rb index 725ea8fe5209d4..2f2fcf22485ee4 100644 --- a/spec/system/new_statuses_spec.rb +++ b/spec/system/new_statuses_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'NewStatuses', :js, :sidekiq_inline, :streaming do +describe 'NewStatuses', :inline_jobs, :js, :streaming do include ProfileStories subject { page } diff --git a/spec/system/ocr_spec.rb b/spec/system/ocr_spec.rb index 4f4941adca581c..17d18af1586ed7 100644 --- a/spec/system/ocr_spec.rb +++ b/spec/system/ocr_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'OCR', :js, :paperclip_processing, :sidekiq_inline, :streaming do +describe 'OCR', :attachment_processing, :inline_jobs, :js, :streaming do include ProfileStories let(:email) { 'test@example.com' } diff --git a/spec/system/report_interface_spec.rb b/spec/system/report_interface_spec.rb index f82604aae89643..e6cc3b1b68870f 100644 --- a/spec/system/report_interface_spec.rb +++ b/spec/system/report_interface_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'report interface', :js, :paperclip_processing, :streaming do +describe 'report interface', :attachment_processing, :js, :streaming do include ProfileStories let(:email) { 'admin@example.com' } diff --git a/spec/workers/backup_worker_spec.rb b/spec/workers/backup_worker_spec.rb index 74928c7ca6ba63..db1b50140b6790 100644 --- a/spec/workers/backup_worker_spec.rb +++ b/spec/workers/backup_worker_spec.rb @@ -14,7 +14,7 @@ let(:backup) { Fabricate(:backup) } let!(:other_backup) { Fabricate(:backup, user: backup.user) } - it 'sends the backup to the service and removes other backups', :sidekiq_inline do + it 'sends the backup to the service and removes other backups', :inline_jobs do emails = capture_emails { worker.perform(backup.id) } expect(service).to have_received(:call).with(backup) diff --git a/spec/workers/move_worker_spec.rb b/spec/workers/move_worker_spec.rb index 0513dc42e5282d..b25992e44bd615 100644 --- a/spec/workers/move_worker_spec.rb +++ b/spec/workers/move_worker_spec.rb @@ -104,7 +104,7 @@ def mute_account_comment end shared_examples 'lists handling' do - it 'puts the new account on the list and makes valid lists', :sidekiq_inline do + it 'puts the new account on the list and makes valid lists', :inline_jobs do subject.perform(source_account.id, target_account.id) expect(list.accounts.include?(target_account)).to be true diff --git a/spec/workers/post_process_media_worker_spec.rb b/spec/workers/post_process_media_worker_spec.rb index 828da5244f55f9..1a274623d73fba 100644 --- a/spec/workers/post_process_media_worker_spec.rb +++ b/spec/workers/post_process_media_worker_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe PostProcessMediaWorker, :paperclip_processing do +describe PostProcessMediaWorker, :attachment_processing do let(:worker) { described_class.new } describe '#perform' do diff --git a/yarn.lock b/yarn.lock index d61ef41632453b..cf7e5a8b952202 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1558,13 +1558,13 @@ __metadata: languageName: node linkType: hard -"@csstools/cascade-layer-name-parser@npm:^1.0.12": - version: 1.0.12 - resolution: "@csstools/cascade-layer-name-parser@npm:1.0.12" +"@csstools/cascade-layer-name-parser@npm:^1.0.13": + version: 1.0.13 + resolution: "@csstools/cascade-layer-name-parser@npm:1.0.13" peerDependencies: - "@csstools/css-parser-algorithms": ^2.7.0 - "@csstools/css-tokenizer": ^2.3.2 - checksum: 10c0/5f92aefcbb3f4b660cf7b0db54f6a4ba21a32fa1b64ea4f050a6370233152d4f561ecf5c8e98ca231e73c16e0d9f75b20b0a65153e18b14957658c81e0f68213 + "@csstools/css-parser-algorithms": ^2.7.1 + "@csstools/css-tokenizer": ^2.4.1 + checksum: 10c0/a6412fc8601af1baadc8195934aa668d3476e799891c9d0883390f31ec8678e9b565ac14d919bec633bbc086657ac12aa4cd852c718851a2d34517ee6856ff8e languageName: node linkType: hard @@ -1575,52 +1575,52 @@ __metadata: languageName: node linkType: hard -"@csstools/css-calc@npm:^1.2.3": - version: 1.2.3 - resolution: "@csstools/css-calc@npm:1.2.3" +"@csstools/css-calc@npm:^1.2.4": + version: 1.2.4 + resolution: "@csstools/css-calc@npm:1.2.4" peerDependencies: - "@csstools/css-parser-algorithms": ^2.7.0 - "@csstools/css-tokenizer": ^2.3.2 - checksum: 10c0/fb34767ea9638b837167bcecaf945bcc0c5e8f0d811067c4e8c7a57bc8f0955f61107b1ed5e017b95c54acacc8088473e5497a9986bee95b37ec92999e792871 + "@csstools/css-parser-algorithms": ^2.7.1 + "@csstools/css-tokenizer": ^2.4.1 + checksum: 10c0/6233746eb642797b7fbc2cf6e7651e95700b294e78e3c29e8730c3236bb92cf62903efb6e54639e8f877683c40646e137c95e615c4450809b21b61a6192888ca languageName: node linkType: hard -"@csstools/css-color-parser@npm:^2.0.3": - version: 2.0.3 - resolution: "@csstools/css-color-parser@npm:2.0.3" +"@csstools/css-color-parser@npm:^2.0.4": + version: 2.0.4 + resolution: "@csstools/css-color-parser@npm:2.0.4" dependencies: "@csstools/color-helpers": "npm:^4.2.1" - "@csstools/css-calc": "npm:^1.2.3" + "@csstools/css-calc": "npm:^1.2.4" peerDependencies: - "@csstools/css-parser-algorithms": ^2.7.0 - "@csstools/css-tokenizer": ^2.3.2 - checksum: 10c0/d8860e6b9c65de4f90d4c21e4d66471fd858434cf63af80f812a900371343b753b86a256627e8bd024cb8903a6a0181d2d9c0c65ab5d78cf29d084a761e2adba + "@csstools/css-parser-algorithms": ^2.7.1 + "@csstools/css-tokenizer": ^2.4.1 + checksum: 10c0/e009a2f34b6c328daad54262deb86b71c6a7a9a1da1db8ad39cf719641e1a728ed8ddbd23613d519d26deee33b89ba12cb15a6928718c1b3cc5e24ac1ed02f47 languageName: node linkType: hard -"@csstools/css-parser-algorithms@npm:^2.6.3, @csstools/css-parser-algorithms@npm:^2.7.0": - version: 2.7.0 - resolution: "@csstools/css-parser-algorithms@npm:2.7.0" +"@csstools/css-parser-algorithms@npm:^2.6.3, @csstools/css-parser-algorithms@npm:^2.7.1": + version: 2.7.1 + resolution: "@csstools/css-parser-algorithms@npm:2.7.1" peerDependencies: - "@csstools/css-tokenizer": ^2.3.2 - checksum: 10c0/fb84fefdf37c41d170f81b687bf1ee1847a970e51cc1fe3a320e3eaf225383ae9a3c4eb6208b83357dfe18c5114353d780e0c65f05d86d6435e5a9ad9334c834 + "@csstools/css-tokenizer": ^2.4.1 + checksum: 10c0/7d29bef6f5790ddb67d922ad232253bf910e4fa5293f5e4a5ed8b920ae9bd4e8171942df7d8943af23b42fd4e9fb460181394d20c97da9562e6ce98a875e8c47 languageName: node linkType: hard -"@csstools/css-tokenizer@npm:^2.3.1, @csstools/css-tokenizer@npm:^2.3.2": - version: 2.3.2 - resolution: "@csstools/css-tokenizer@npm:2.3.2" - checksum: 10c0/f7d0d8b3e9e2dcdc6547a387253a09dbbacaaffb5c8718bcd7f15dddeefdd441b73fc5f9fad3f03fabef3b37ec4b62be7ff79caab366427fa90eaf54cd8fc452 +"@csstools/css-tokenizer@npm:^2.3.1, @csstools/css-tokenizer@npm:^2.4.1": + version: 2.4.1 + resolution: "@csstools/css-tokenizer@npm:2.4.1" + checksum: 10c0/fe71cee85ec7372da07083d088b6a704f43e5d3d2d8071c4b8a86fae60408b559a218a43f8625bf2f0be5c7f90c8f3ad20a1aae1921119a1c02b51c310cc2b6b languageName: node linkType: hard -"@csstools/media-query-list-parser@npm:^2.1.11, @csstools/media-query-list-parser@npm:^2.1.12": - version: 2.1.12 - resolution: "@csstools/media-query-list-parser@npm:2.1.12" +"@csstools/media-query-list-parser@npm:^2.1.11, @csstools/media-query-list-parser@npm:^2.1.13": + version: 2.1.13 + resolution: "@csstools/media-query-list-parser@npm:2.1.13" peerDependencies: - "@csstools/css-parser-algorithms": ^2.7.0 - "@csstools/css-tokenizer": ^2.3.2 - checksum: 10c0/7395cc710d8f54670c1e7a418a88dcf1ae726316272294ec645f6d79a8e931f5d390ba7ed5d0141d29ad7280cd447b8773143dc7676659413de79228130e1a65 + "@csstools/css-parser-algorithms": ^2.7.1 + "@csstools/css-tokenizer": ^2.4.1 + checksum: 10c0/8bf72342c15581b8f658633436d83c26a214056f6b960ff121b940271f4b1b5b07e9cc3990a73e684fb72319592f0c392408b4f0e08bbe242b2065aa456e2733 languageName: node linkType: hard @@ -1636,46 +1636,60 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-color-function@npm:^3.0.17": - version: 3.0.17 - resolution: "@csstools/postcss-color-function@npm:3.0.17" +"@csstools/postcss-color-function@npm:^3.0.19": + version: 3.0.19 + resolution: "@csstools/postcss-color-function@npm:3.0.19" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/6d347fc9fe65cb897c275c129103576e551b74a7c47a1a4dc8160da2fad7752bf51e3cfbff339f86b39c723efac33643168d2dfaac4d3624d072875d18a65a4b + checksum: 10c0/067e33d7dfc32b56fe63d4f97464a3eaf27dde720961e44feab6076bd2c172dd4c1bad16aa37a922dcbba470756bd6a13e728d9e71eab6937d48d83873cd1879 languageName: node linkType: hard -"@csstools/postcss-color-mix-function@npm:^2.0.17": - version: 2.0.17 - resolution: "@csstools/postcss-color-mix-function@npm:2.0.17" +"@csstools/postcss-color-mix-function@npm:^2.0.19": + version: 2.0.19 + resolution: "@csstools/postcss-color-mix-function@npm:2.0.19" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/ba9a406ebe4caba6709878ee26debb06780be5cbf4e6ab7e902d79ca6e21ec6a8409b9dc0a5ef36fc4bf54bf2bd8f9642b72da8d7939145f99dc40fedd2be9d2 + checksum: 10c0/e967d93672a065806dc78da0153f8b4f5087f7c3ddfe361eba4942780760d47b317124913c9b0dda7f9bfff1253f77d1b6debd8a6a2aa3a6c80e263101da5e8c languageName: node linkType: hard -"@csstools/postcss-exponential-functions@npm:^1.0.8": - version: 1.0.8 - resolution: "@csstools/postcss-exponential-functions@npm:1.0.8" +"@csstools/postcss-content-alt-text@npm:^1.0.0": + version: 1.0.0 + resolution: "@csstools/postcss-content-alt-text@npm:1.0.0" + dependencies: + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" + "@csstools/utilities": "npm:^1.0.0" + peerDependencies: + postcss: ^8.4 + checksum: 10c0/0c2c64857ac652989d00c3d2ba49d0cd1cc245193cba6724d2f5841aa990ee6a07267cfebc6fabde6a6246616df60373006d17c5ea9b904129fbfd826dc10a8d + languageName: node + linkType: hard + +"@csstools/postcss-exponential-functions@npm:^1.0.9": + version: 1.0.9 + resolution: "@csstools/postcss-exponential-functions@npm:1.0.9" dependencies: - "@csstools/css-calc": "npm:^1.2.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/css-calc": "npm:^1.2.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" peerDependencies: postcss: ^8.4 - checksum: 10c0/6b049801fc1275b34f43ffbb915f447a54cbff7bf48ab0705c3ad1ffde055cb876c4dc24e7a9162cd65e219457328e298a673f6176446493db17cf7af6f90dc0 + checksum: 10c0/eaec29ef6ec201786c606176235dced4af1922d5ac56c6b0993ad2e7d87464a32702d9b28cae9a76e8527f741b50cbc31d4c646f45d02dc69d520f241b3e7878 languageName: node linkType: hard @@ -1691,59 +1705,59 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-gamut-mapping@npm:^1.0.10": - version: 1.0.10 - resolution: "@csstools/postcss-gamut-mapping@npm:1.0.10" +"@csstools/postcss-gamut-mapping@npm:^1.0.11": + version: 1.0.11 + resolution: "@csstools/postcss-gamut-mapping@npm:1.0.11" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" peerDependencies: postcss: ^8.4 - checksum: 10c0/6c2dab6a84f81904bed89cb584bd9bc6a904b49a4fa315b17be65c7d68baefe592561ee439660d5602b7481bac3be9a93189dc45404764524495400f34c6b6e6 + checksum: 10c0/29e755013f1d1de34eb62a931ed410d2830ca3dfc81476cb3c72d9d3260b85a9adedc51aa548550c6e308f3f9640c489e6953db40e9cac9835d0421d5b14ef1f languageName: node linkType: hard -"@csstools/postcss-gradients-interpolation-method@npm:^4.0.18": - version: 4.0.18 - resolution: "@csstools/postcss-gradients-interpolation-method@npm:4.0.18" +"@csstools/postcss-gradients-interpolation-method@npm:^4.0.20": + version: 4.0.20 + resolution: "@csstools/postcss-gradients-interpolation-method@npm:4.0.20" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/23c431068ac205392b4953dbce411e208e79e221ba8030c5e23c0b82e8fd53bc3bc4f2cdc47050f5d91a4ac69cb80f4f1853b213aa8072fa60a6cb6ff0621e04 + checksum: 10c0/6588825a72a1471e2d6036c8cf7dbad2bf05f369d96dbdd68ff5ce7ff91803b8ee1146f5f1bf6f3ab6299944549da872914664c3f9e8ae5a31847f76f0085c74 languageName: node linkType: hard -"@csstools/postcss-hwb-function@npm:^3.0.16": - version: 3.0.16 - resolution: "@csstools/postcss-hwb-function@npm:3.0.16" +"@csstools/postcss-hwb-function@npm:^3.0.18": + version: 3.0.18 + resolution: "@csstools/postcss-hwb-function@npm:3.0.18" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/4deca8831a69038aff719a77df92c53578bb28e23cc61dc4ea7b1d912b1b685683a9c6232396c2616948ac2e8488ad1e2009c9c8ed30c493d97ba8ad37b6418d + checksum: 10c0/e9d76b0b2f9c54920124ca1804b49e3f5b26e003729418b5ef4b340ff1baa4779da1c02be618888fdbcc2d0747182352efbbd3ffe128e2417928c35c25443789 languageName: node linkType: hard -"@csstools/postcss-ic-unit@npm:^3.0.6": - version: 3.0.6 - resolution: "@csstools/postcss-ic-unit@npm:3.0.6" +"@csstools/postcss-ic-unit@npm:^3.0.7": + version: 3.0.7 + resolution: "@csstools/postcss-ic-unit@npm:3.0.7" dependencies: - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/a4b962327d433419fdcfdcf620ce6a5cf09aa3c93029ad08b035df1e2bc35caae31de49f1d14218de0656fced35c0d2e07e5ff7b8099c29dbfb40395fc283234 + checksum: 10c0/2add905b75860c64d7174886fecfc76d86e3818f42f003f4bbfc0604cc7f0f31c6dbd1651e6b9512fea876190d80033578ae49e813b64b17c8cf3b1f03d8e146 languageName: node linkType: hard @@ -1768,17 +1782,17 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-light-dark-function@npm:^1.0.6": - version: 1.0.6 - resolution: "@csstools/postcss-light-dark-function@npm:1.0.6" +"@csstools/postcss-light-dark-function@npm:^1.0.8": + version: 1.0.8 + resolution: "@csstools/postcss-light-dark-function@npm:1.0.8" dependencies: - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/6b2c64860d789cd3e3ce875c01259333911f6e32a751a7475604de8022c13abcb578e5cb941b51bd3a2022bee883df3f6b64800c6e3559b06da283d968aeb615 + checksum: 10c0/78fa6d799d38f14af1b32b534eedbec9478033e1fbc5a4e820f2421e865673d010b69b391546686ceb408ead64d79bb4eba2a4fb1fc9f0de70ff21e3ff8477c6 languageName: node linkType: hard @@ -1820,42 +1834,42 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-logical-viewport-units@npm:^2.0.10": - version: 2.0.10 - resolution: "@csstools/postcss-logical-viewport-units@npm:2.0.10" +"@csstools/postcss-logical-viewport-units@npm:^2.0.11": + version: 2.0.11 + resolution: "@csstools/postcss-logical-viewport-units@npm:2.0.11" dependencies: - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/css-tokenizer": "npm:^2.4.1" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/fe142b11e0e8ccab4667cc5db90b45e67b7d11eaf5c038e91d867e1b18a315ef0859114185aeb48fdc1ce05986be8b644d6157fe9e19da7281f7023c99eb8877 + checksum: 10c0/20207e9b7fc3ab52df5fcd06fde71fca4fd22bd6bd451cfc2ec6ea69994708b7fc5381e203dc4367293a8de00b1eca7a3ebe89cfa9b933d2f2cb8e3ac4d5aa86 languageName: node linkType: hard -"@csstools/postcss-media-minmax@npm:^1.1.7": - version: 1.1.7 - resolution: "@csstools/postcss-media-minmax@npm:1.1.7" +"@csstools/postcss-media-minmax@npm:^1.1.8": + version: 1.1.8 + resolution: "@csstools/postcss-media-minmax@npm:1.1.8" dependencies: - "@csstools/css-calc": "npm:^1.2.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/media-query-list-parser": "npm:^2.1.12" + "@csstools/css-calc": "npm:^1.2.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/media-query-list-parser": "npm:^2.1.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/a02943a17b540cbd909b55bbb1f8c9331badc51b613279bbdb7127c9921a5d0675bb41675a3b4d0f15e9586120e5a96d9b9786b63b2c594fbb3a238e860c6ad8 + checksum: 10c0/7d666905282c7a89387dbce84f3429bad04870e0de264c5b1ce3e6f042b8eb72d585a18b2d7ac5e1a8c7f6785892da3cc7f6ea0b48069b06e9d383bdbc149b4a languageName: node linkType: hard -"@csstools/postcss-media-queries-aspect-ratio-number-values@npm:^2.0.10": - version: 2.0.10 - resolution: "@csstools/postcss-media-queries-aspect-ratio-number-values@npm:2.0.10" +"@csstools/postcss-media-queries-aspect-ratio-number-values@npm:^2.0.11": + version: 2.0.11 + resolution: "@csstools/postcss-media-queries-aspect-ratio-number-values@npm:2.0.11" dependencies: - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/media-query-list-parser": "npm:^2.1.12" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/media-query-list-parser": "npm:^2.1.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/d7879e72df98d9fe2e5d85a64837e7a73c2df1aea8659d65516f0acb070317edd353531882f0bdfd81510703d1da30d6da861052a0bda85fde1f9eab94b1e467 + checksum: 10c0/b4023a1951b7661196332852ce714a4e2fb4f1a67164ec0944e28a009b389e59c67e9de790920fcd082b122276414dd39c12ae12a4566e59e1bbcc794560a870 languageName: node linkType: hard @@ -1882,44 +1896,44 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-oklab-function@npm:^3.0.17": - version: 3.0.17 - resolution: "@csstools/postcss-oklab-function@npm:3.0.17" +"@csstools/postcss-oklab-function@npm:^3.0.19": + version: 3.0.19 + resolution: "@csstools/postcss-oklab-function@npm:3.0.19" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/ff27a4b6fd8490439aa0f3c91ffa2a42a8cf539d7306d9329cef7ca59f28317cee40253f402d19a18c196471fd39a05842d2974d92f1b131dc748074d91ac4ee + checksum: 10c0/2909f76ba408c9f60b61c479994c96200b0e1d3dbf524d5ae6dc5ca1e21d38caf974595e0d071c3900dbe3568376928085dd811aa24ea3e715bcd9de26fb0fa9 languageName: node linkType: hard -"@csstools/postcss-progressive-custom-properties@npm:^3.2.0": - version: 3.2.0 - resolution: "@csstools/postcss-progressive-custom-properties@npm:3.2.0" +"@csstools/postcss-progressive-custom-properties@npm:^3.3.0": + version: 3.3.0 + resolution: "@csstools/postcss-progressive-custom-properties@npm:3.3.0" dependencies: postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/829880844fbbeef1c67e0b380057e574659b4caed38c8414c17d7eb4a0cc727afa1cd74a889bc7ca79c819ecae757810356706901cf6bb677a36ca123915cbb7 + checksum: 10c0/6c9987d65049a70b5090dcfe42fde9ab2b3cb88911a81bb6651ed81c8baf99502ff2cbec0cb3e022426fa994b558b4bf33fd791ccdcdf683dde75b4865d34f39 languageName: node linkType: hard -"@csstools/postcss-relative-color-syntax@npm:^2.0.17": - version: 2.0.17 - resolution: "@csstools/postcss-relative-color-syntax@npm:2.0.17" +"@csstools/postcss-relative-color-syntax@npm:^2.0.19": + version: 2.0.19 + resolution: "@csstools/postcss-relative-color-syntax@npm:2.0.19" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/46226351b3825323e3496dcee44ff354cd3ccc9241d837659e1311f428f0b4dc878d9bb762cbb8f63243b7af346728ab7a46c311f9dc38bb609147523c698eab + checksum: 10c0/f0aff764f4889ff664b6fa94ddfa5a22daf39354aa2d2ac0eab893eb3ed841b7d2a72131393334d6a5379445fc80f92ab5bd63d4dc3b43746bc7c9055da46591 languageName: node linkType: hard @@ -1934,16 +1948,16 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-stepped-value-functions@npm:^3.0.9": - version: 3.0.9 - resolution: "@csstools/postcss-stepped-value-functions@npm:3.0.9" +"@csstools/postcss-stepped-value-functions@npm:^3.0.10": + version: 3.0.10 + resolution: "@csstools/postcss-stepped-value-functions@npm:3.0.10" dependencies: - "@csstools/css-calc": "npm:^1.2.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/css-calc": "npm:^1.2.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" peerDependencies: postcss: ^8.4 - checksum: 10c0/bafe80947abc8613903f1f3f1939ece9780696774f15960aef229733e40e483dc2830145426d49c4f6d0b1dabb35f812c8a2dda0d0dcddc930321e36b5c6ca0b + checksum: 10c0/f9ebe50fb884d002aa40070196a827816f635b891fd2147ae5ddf1ad6df5bddbb50783d6786897bb3dffa33052565e38289392040cf4454aaa179ab00353117d languageName: node linkType: hard @@ -1959,16 +1973,16 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-trigonometric-functions@npm:^3.0.9": - version: 3.0.9 - resolution: "@csstools/postcss-trigonometric-functions@npm:3.0.9" +"@csstools/postcss-trigonometric-functions@npm:^3.0.10": + version: 3.0.10 + resolution: "@csstools/postcss-trigonometric-functions@npm:3.0.10" dependencies: - "@csstools/css-calc": "npm:^1.2.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/css-calc": "npm:^1.2.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" peerDependencies: postcss: ^8.4 - checksum: 10c0/7a439d31a63d35986dab634d9e415f7ce7c32a2d3d382052b5b730a259a12e44c5f1b14e318d79086253e3d5d4f7d942d0e7317d92eb3421dd08824eebec45fb + checksum: 10c0/31adcc66510d9788ccb0669d2761517a6135b13692007d8e4334bc0e8d3515dfecfbdcd04e060d0c09a0f5fc2f12db92221b9d53e92b65b044c89cde9a3424cb languageName: node linkType: hard @@ -3357,8 +3371,8 @@ __metadata: linkType: hard "@testing-library/dom@npm:^10.2.0": - version: 10.2.0 - resolution: "@testing-library/dom@npm:10.2.0" + version: 10.3.1 + resolution: "@testing-library/dom@npm:10.3.1" dependencies: "@babel/code-frame": "npm:^7.10.4" "@babel/runtime": "npm:^7.12.5" @@ -3368,7 +3382,7 @@ __metadata: dom-accessibility-api: "npm:^0.5.9" lz-string: "npm:^1.5.0" pretty-format: "npm:^27.0.2" - checksum: 10c0/de582dfbeb632436547a0ca5851b5a714a4a17f8e96ab3dc4fb4e454eef52c912b648b7cb6e9fdf477f3eeef97e698f3250f0ce50846f39d04677a44169209f2 + checksum: 10c0/e898475cd4932225c2962bf9f94353d7d88462c8912881af8e9866cee714c967b21badb0895ec8626123759cddc6663bc40300b1d1bf789957a603086eda6329 languageName: node linkType: hard @@ -6726,10 +6740,10 @@ __metadata: languageName: node linkType: hard -"cssdb@npm:^8.0.0": - version: 8.0.0 - resolution: "cssdb@npm:8.0.0" - checksum: 10c0/d9a31b760214624352000b16a8f7194c357f66b6c445e663ab58dd03b6f0f53efaaca6d6f96200d666e205894d2d1c346664ad993d9522ff9fc1c331804a8d62 +"cssdb@npm:^8.1.0": + version: 8.1.0 + resolution: "cssdb@npm:8.1.0" + checksum: 10c0/1fa1f1566c7e9964f5c71e443583eaba16a90933a3ef6803815c4281d084b75da948c415bade33d7085894fe0929c082fcb3135bf4400048cfff40d227ebd5dd languageName: node linkType: hard @@ -6742,16 +6756,16 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-default@npm:^7.0.3": - version: 7.0.3 - resolution: "cssnano-preset-default@npm:7.0.3" +"cssnano-preset-default@npm:^7.0.4": + version: 7.0.4 + resolution: "cssnano-preset-default@npm:7.0.4" dependencies: browserslist: "npm:^4.23.1" css-declaration-sorter: "npm:^7.2.0" cssnano-utils: "npm:^5.0.0" postcss-calc: "npm:^10.0.0" postcss-colormin: "npm:^7.0.1" - postcss-convert-values: "npm:^7.0.1" + postcss-convert-values: "npm:^7.0.2" postcss-discard-comments: "npm:^7.0.1" postcss-discard-duplicates: "npm:^7.0.0" postcss-discard-empty: "npm:^7.0.0" @@ -6778,7 +6792,7 @@ __metadata: postcss-unique-selectors: "npm:^7.0.1" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/ab3e51003efed6542a12d43c10ca693ab26138a1d035697b9be8f07e084e37a78617cbb8028b0a7e7841302ec151f4ecf35cbd763efe291846b62c35ea4c0bb4 + checksum: 10c0/0083821e778bdf7b8aa9589408a01a717be730f73584e7b81756a6fcf87af05b8f17342025e666572a8d573cc30783f2d817b0f7ad63670398bc3135b017ccad languageName: node linkType: hard @@ -6792,14 +6806,14 @@ __metadata: linkType: hard "cssnano@npm:^7.0.0": - version: 7.0.3 - resolution: "cssnano@npm:7.0.3" + version: 7.0.4 + resolution: "cssnano@npm:7.0.4" dependencies: - cssnano-preset-default: "npm:^7.0.3" + cssnano-preset-default: "npm:^7.0.4" lilconfig: "npm:^3.1.2" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/4cbcd1e0ebe0bd83196cc5b16b3a60d3ebc98326c79b2f71df597bb73c8e3ee1f42b89159d7a038acc398251184d648d9dd516f4194e46746f3af6fa74b4aec7 + checksum: 10c0/3939a0b37b11cb4bae92f7916517c7ba21257551f92517b49a640d5df32e855fb7e73321f4be44d2c2de578309c05d711cdcb1976e95607b1b7f92bd4cbd1350 languageName: node linkType: hard @@ -8995,8 +9009,8 @@ __metadata: linkType: hard "glob@npm:^10.2.2, glob@npm:^10.2.6, glob@npm:^10.3.10": - version: 10.4.2 - resolution: "glob@npm:10.4.2" + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: "npm:^3.1.0" jackspeak: "npm:^3.1.2" @@ -9006,7 +9020,7 @@ __metadata: path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10c0/2c7296695fa75a935f3ad17dc62e4e170a8bb8752cf64d328be8992dd6ad40777939003754e10e9741ff8fbe43aa52fba32d6930d0ffa0e3b74bc3fb5eebaa2f + checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e languageName: node linkType: hard @@ -13286,18 +13300,18 @@ __metadata: languageName: node linkType: hard -"postcss-color-functional-notation@npm:^6.0.12": - version: 6.0.12 - resolution: "postcss-color-functional-notation@npm:6.0.12" +"postcss-color-functional-notation@npm:^6.0.14": + version: 6.0.14 + resolution: "postcss-color-functional-notation@npm:6.0.14" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/2e8faecd2609e1b4eb8c1cab21ecca5e746916795df20e6997d66eb61c29fbb01d3e75fef3e0b3e1c181918a2186570441b81779b1fc429d6d8823fbfa164231 + checksum: 10c0/fdc5188e19c3923da32fe08d50e55d0b3ca1cedf99f46331baa0a4bbd73a1fc6b4447b0346ab16049032b56ab84b98b4758a0ede7c237637e35a4cc60caac141 languageName: node linkType: hard @@ -13339,58 +13353,58 @@ __metadata: languageName: node linkType: hard -"postcss-convert-values@npm:^7.0.1": - version: 7.0.1 - resolution: "postcss-convert-values@npm:7.0.1" +"postcss-convert-values@npm:^7.0.2": + version: 7.0.2 + resolution: "postcss-convert-values@npm:7.0.2" dependencies: browserslist: "npm:^4.23.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 10c0/612f025f179f0f2ad7365db8c0b423614dcb8e1e4061875a4691a39dede0bca758d1a8f9f5c8b08e12af053e9e884f65ca5626ccc723d5b3f420650d67fe3046 + checksum: 10c0/beb59faf6aae97e6d3c233c5e6ed06cc60d65c49eec576036e3d0da1a831a1e827e3d41f5e81d016440b4f0bdf1406268ae069c4d5b38a6667b310c3da079d22 languageName: node linkType: hard -"postcss-custom-media@npm:^10.0.7": - version: 10.0.7 - resolution: "postcss-custom-media@npm:10.0.7" +"postcss-custom-media@npm:^10.0.8": + version: 10.0.8 + resolution: "postcss-custom-media@npm:10.0.8" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^1.0.12" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/media-query-list-parser": "npm:^2.1.12" + "@csstools/cascade-layer-name-parser": "npm:^1.0.13" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/media-query-list-parser": "npm:^2.1.13" peerDependencies: postcss: ^8.4 - checksum: 10c0/4171385ab9370806861dcf7597e53fd6aa1862e77b475c9c565c95bfcc2b950f920f8da26a6dbec42e257388bca97c274635662b5e81fe3905b5e37babe06569 + checksum: 10c0/673ca0058a2f2357a83b33ce00bbeee7cda92621c08472fa55d7ac7ae56f5f8f979132528d537f2dedf715d35a8f9b14b2f0ab6b45423d49e2554c19aab3c827 languageName: node linkType: hard -"postcss-custom-properties@npm:^13.3.11": - version: 13.3.11 - resolution: "postcss-custom-properties@npm:13.3.11" +"postcss-custom-properties@npm:^13.3.12": + version: 13.3.12 + resolution: "postcss-custom-properties@npm:13.3.12" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^1.0.12" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/cascade-layer-name-parser": "npm:^1.0.13" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" "@csstools/utilities": "npm:^1.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/4aa95628aa5d5b6df4dfeedbc3891b9666db88d75930cadc14d2fbba0a1b72f4e3cc3d83b5a0c0b8ce44f85b4fda6ebd7fe7792a1abc0a14d7d63b9f170d299c + checksum: 10c0/6af9f6ac94a6ac887749cd38d4586349f6aca29269ebfdb837019a3ba0130032f0ff4899b431b5c348f4ac79a7b16fb7300a256514a6a68e32a63489c18a70e7 languageName: node linkType: hard -"postcss-custom-selectors@npm:^7.1.11": - version: 7.1.11 - resolution: "postcss-custom-selectors@npm:7.1.11" +"postcss-custom-selectors@npm:^7.1.12": + version: 7.1.12 + resolution: "postcss-custom-selectors@npm:7.1.12" dependencies: - "@csstools/cascade-layer-name-parser": "npm:^1.0.12" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" + "@csstools/cascade-layer-name-parser": "npm:^1.0.13" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" postcss-selector-parser: "npm:^6.1.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/f37d2e34239e868b35b7970ec97a7a8f657a9f92ed2b221af44f19949f7c3aedcecd0abb5fa1acb120c5ceffdf7a20869338956a37d7bfc37a83d8088f5d3dd2 + checksum: 10c0/78a7930e4f97c42b544f00c06272264432d47f9df777684b57673bb971b7ab49d5d6fb9289a5a869125e7e50dcd0cad65cf8846501253084b73a42ffab41b2c5 languageName: node linkType: hard @@ -13443,16 +13457,16 @@ __metadata: languageName: node linkType: hard -"postcss-double-position-gradients@npm:^5.0.6": - version: 5.0.6 - resolution: "postcss-double-position-gradients@npm:5.0.6" +"postcss-double-position-gradients@npm:^5.0.7": + version: 5.0.7 + resolution: "postcss-double-position-gradients@npm:5.0.7" dependencies: - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/9b24b13043fe506c0ddd94e707fe4f21f4f9a6c05ca49a4f45e23412951fd6a4cfa0095002d10b322ca8be60df0badae3715a27eefdeb7bf8da4fdd1ecd5d7a2 + checksum: 10c0/52d96a34aa3e2e251edeaa2d4c2dd106c687f7910ec18266693656c0edd003384b927c855cecac07f52b5c7bdccd140abdc7e27082ce4c3755e3a966206a2cb9 languageName: node linkType: hard @@ -13508,18 +13522,18 @@ __metadata: languageName: node linkType: hard -"postcss-lab-function@npm:^6.0.17": - version: 6.0.17 - resolution: "postcss-lab-function@npm:6.0.17" +"postcss-lab-function@npm:^6.0.19": + version: 6.0.19 + resolution: "postcss-lab-function@npm:6.0.19" dependencies: - "@csstools/css-color-parser": "npm:^2.0.3" - "@csstools/css-parser-algorithms": "npm:^2.7.0" - "@csstools/css-tokenizer": "npm:^2.3.2" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" + "@csstools/css-color-parser": "npm:^2.0.4" + "@csstools/css-parser-algorithms": "npm:^2.7.1" + "@csstools/css-tokenizer": "npm:^2.4.1" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" "@csstools/utilities": "npm:^1.0.0" peerDependencies: postcss: ^8.4 - checksum: 10c0/a331f188b02cc8beb315150232b6b58bc5793e8d61585973d352a9b4d370b908ff354ccf9ea1ba20a956fd37ea4ada918ea975c8d4f69e850d26edf0106436e8 + checksum: 10c0/d9a91fb57dcbe967260df86e22ca335a5444f1f34d128fa7b5dbf2522772f2138ad708f1f20f0a59035d66ed736e82972ca7f1b669a157534a17ee8898af1921 languageName: node linkType: hard @@ -13840,60 +13854,61 @@ __metadata: linkType: hard "postcss-preset-env@npm:^9.5.2": - version: 9.5.15 - resolution: "postcss-preset-env@npm:9.5.15" + version: 9.6.0 + resolution: "postcss-preset-env@npm:9.6.0" dependencies: "@csstools/postcss-cascade-layers": "npm:^4.0.6" - "@csstools/postcss-color-function": "npm:^3.0.17" - "@csstools/postcss-color-mix-function": "npm:^2.0.17" - "@csstools/postcss-exponential-functions": "npm:^1.0.8" + "@csstools/postcss-color-function": "npm:^3.0.19" + "@csstools/postcss-color-mix-function": "npm:^2.0.19" + "@csstools/postcss-content-alt-text": "npm:^1.0.0" + "@csstools/postcss-exponential-functions": "npm:^1.0.9" "@csstools/postcss-font-format-keywords": "npm:^3.0.2" - "@csstools/postcss-gamut-mapping": "npm:^1.0.10" - "@csstools/postcss-gradients-interpolation-method": "npm:^4.0.18" - "@csstools/postcss-hwb-function": "npm:^3.0.16" - "@csstools/postcss-ic-unit": "npm:^3.0.6" + "@csstools/postcss-gamut-mapping": "npm:^1.0.11" + "@csstools/postcss-gradients-interpolation-method": "npm:^4.0.20" + "@csstools/postcss-hwb-function": "npm:^3.0.18" + "@csstools/postcss-ic-unit": "npm:^3.0.7" "@csstools/postcss-initial": "npm:^1.0.1" "@csstools/postcss-is-pseudo-class": "npm:^4.0.8" - "@csstools/postcss-light-dark-function": "npm:^1.0.6" + "@csstools/postcss-light-dark-function": "npm:^1.0.8" "@csstools/postcss-logical-float-and-clear": "npm:^2.0.1" "@csstools/postcss-logical-overflow": "npm:^1.0.1" "@csstools/postcss-logical-overscroll-behavior": "npm:^1.0.1" "@csstools/postcss-logical-resize": "npm:^2.0.1" - "@csstools/postcss-logical-viewport-units": "npm:^2.0.10" - "@csstools/postcss-media-minmax": "npm:^1.1.7" - "@csstools/postcss-media-queries-aspect-ratio-number-values": "npm:^2.0.10" + "@csstools/postcss-logical-viewport-units": "npm:^2.0.11" + "@csstools/postcss-media-minmax": "npm:^1.1.8" + "@csstools/postcss-media-queries-aspect-ratio-number-values": "npm:^2.0.11" "@csstools/postcss-nested-calc": "npm:^3.0.2" "@csstools/postcss-normalize-display-values": "npm:^3.0.2" - "@csstools/postcss-oklab-function": "npm:^3.0.17" - "@csstools/postcss-progressive-custom-properties": "npm:^3.2.0" - "@csstools/postcss-relative-color-syntax": "npm:^2.0.17" + "@csstools/postcss-oklab-function": "npm:^3.0.19" + "@csstools/postcss-progressive-custom-properties": "npm:^3.3.0" + "@csstools/postcss-relative-color-syntax": "npm:^2.0.19" "@csstools/postcss-scope-pseudo-class": "npm:^3.0.1" - "@csstools/postcss-stepped-value-functions": "npm:^3.0.9" + "@csstools/postcss-stepped-value-functions": "npm:^3.0.10" "@csstools/postcss-text-decoration-shorthand": "npm:^3.0.7" - "@csstools/postcss-trigonometric-functions": "npm:^3.0.9" + "@csstools/postcss-trigonometric-functions": "npm:^3.0.10" "@csstools/postcss-unset-value": "npm:^3.0.1" autoprefixer: "npm:^10.4.19" browserslist: "npm:^4.23.1" css-blank-pseudo: "npm:^6.0.2" css-has-pseudo: "npm:^6.0.5" css-prefers-color-scheme: "npm:^9.0.1" - cssdb: "npm:^8.0.0" + cssdb: "npm:^8.1.0" postcss-attribute-case-insensitive: "npm:^6.0.3" postcss-clamp: "npm:^4.1.0" - postcss-color-functional-notation: "npm:^6.0.12" + postcss-color-functional-notation: "npm:^6.0.14" postcss-color-hex-alpha: "npm:^9.0.4" postcss-color-rebeccapurple: "npm:^9.0.3" - postcss-custom-media: "npm:^10.0.7" - postcss-custom-properties: "npm:^13.3.11" - postcss-custom-selectors: "npm:^7.1.11" + postcss-custom-media: "npm:^10.0.8" + postcss-custom-properties: "npm:^13.3.12" + postcss-custom-selectors: "npm:^7.1.12" postcss-dir-pseudo-class: "npm:^8.0.1" - postcss-double-position-gradients: "npm:^5.0.6" + postcss-double-position-gradients: "npm:^5.0.7" postcss-focus-visible: "npm:^9.0.1" postcss-focus-within: "npm:^8.0.1" postcss-font-variant: "npm:^5.0.0" postcss-gap-properties: "npm:^5.0.1" postcss-image-set-function: "npm:^6.0.3" - postcss-lab-function: "npm:^6.0.17" + postcss-lab-function: "npm:^6.0.19" postcss-logical: "npm:^7.0.1" postcss-nesting: "npm:^12.1.5" postcss-opacity-percentage: "npm:^2.0.0" @@ -13905,7 +13920,7 @@ __metadata: postcss-selector-not: "npm:^7.0.2" peerDependencies: postcss: ^8.4 - checksum: 10c0/e2ee0b5d7dbaddb82ff6d51b5882120862d6be184973ae3d55642923183ab441d421d5f9810fe02e680a70dbc85b20b1c2eb02c68f167dcaf3ef80a71dd40e78 + checksum: 10c0/caa91ba4d3b897d43ab2669b3edf40b24ef32c88e23b113be8956412e64b28deed6ba229c331848fcbc0d143bfde155173fb1e1ada9ccae5037b2ee8f7e554b7 languageName: node linkType: hard @@ -15447,15 +15462,15 @@ __metadata: linkType: hard "sass@npm:^1.62.1": - version: 1.77.6 - resolution: "sass@npm:1.77.6" + version: 1.77.7 + resolution: "sass@npm:1.77.7" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 10c0/fe5a393c0aa29eda9f83c06be9b94788b61fe8bad0616ee6e3a25d21ab504f430d40c0064fdca89b02b8e426411ae6dcd906c91f2e48c263575c3d392b6daeb1 + checksum: 10c0/6cacbf4b5165d30a9be0f09438aed85ff0617e5087442e65c23c8464750ff1b9988855a58f36b420b62f992d1e82403f99810aba7731519d3d026847e21a5635 languageName: node linkType: hard @@ -17275,22 +17290,22 @@ __metadata: linkType: hard "typescript@npm:5, typescript@npm:^5.0.4": - version: 5.5.2 - resolution: "typescript@npm:5.5.2" + version: 5.5.3 + resolution: "typescript@npm:5.5.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/8ca39b27b5f9bd7f32db795045933ab5247897660627251e8254180b792a395bf061ea7231947d5d7ffa5cb4cc771970fd4ef543275f9b559f08c9325cccfce3 + checksum: 10c0/f52c71ccbc7080b034b9d3b72051d563601a4815bf3e39ded188e6ce60813f75dbedf11ad15dd4d32a12996a9ed8c7155b46c93a9b9c9bad1049766fe614bbdd languageName: node linkType: hard "typescript@patch:typescript@npm%3A5#optional!builtin, typescript@patch:typescript@npm%3A^5.0.4#optional!builtin": - version: 5.5.2 - resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=379a07" + version: 5.5.3 + resolution: "typescript@patch:typescript@npm%3A5.5.3#optional!builtin::version=5.5.3&hash=379a07" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/a7b7ede75dc7fc32a76d0d0af6b91f5fbd8620890d84c906f663d8783bf3de6d7bd50f0430b8bb55eac88a38934af847ff709e7156e5138b95ae94cbd5f73e5b + checksum: 10c0/911c7811d61f57f07df79c4a35f56a0f426a65426a020e5fcd792f66559f399017205f5f10255329ab5a3d8c2d1f1d19530aeceffda70758a521fae1d469432e languageName: node linkType: hard