From 8fbfa3653203c5d275febaa996e57b85115ebd03 Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 06:10:26 +0000 Subject: [PATCH 01/61] Update all Yarn dependencies (2025-10-22) --- package.json | 12 ++++---- yarn.lock | 84 +++++++++++++++++++++++++++------------------------- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index 206786bf6c..d72ca7c14a 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "classnames": "^2.5.1", "common-tags": "^1.8.2", "copy-to-clipboard": "^3.3.3", - "core-js": "^3.45.1", + "core-js": "^3.46.0", "escape-string-regexp": "^4.0.0", "gecko-profiler-demangle": "^0.4.0", "idb": "^8.0.3", @@ -114,7 +114,7 @@ "@babel/preset-env": "^7.28.3", "@babel/preset-react": "^7.27.1", "@babel/preset-typescript": "^7.27.1", - "@eslint/js": "^9.36.0", + "@eslint/js": "^9.37.0", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", @@ -122,7 +122,7 @@ "@types/common-tags": "^1.8.4", "@types/jest": "^30.0.0", "@types/minimist": "^1.2.5", - "@types/node": "^22.18.10", + "@types/node": "^22.18.12", "@types/query-string": "^6.3.0", "@types/react": "^18.3.26", "@types/react-dom": "^18.3.1", @@ -146,7 +146,7 @@ "css-loader": "^7.1.2", "cssnano": "^7.1.1", "devtools-license-check": "^0.9.0", - "eslint": "^9.36.0", + "eslint": "^9.37.0", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.32.0", @@ -154,9 +154,9 @@ "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-jest-formatting": "^3.1.0", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-testing-library": "^7.6.8", + "eslint-plugin-testing-library": "^7.13.3", "espree": "^10.4.0", - "fake-indexeddb": "^6.2.2", + "fake-indexeddb": "^6.2.4", "fetch-mock": "^12.5.4", "file-loader": "^6.2.0", "glob": "^11.0.3", diff --git a/yarn.lock b/yarn.lock index 2cd6d7a71c..b5c89065d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1226,15 +1226,17 @@ debug "^4.3.1" minimatch "^3.1.2" -"@eslint/config-helpers@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.3.1.tgz#d316e47905bd0a1a931fa50e669b9af4104d1617" - integrity sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA== +"@eslint/config-helpers@^0.4.0": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.1.tgz#7d173a1a35fe256f0989a0fdd8d911ebbbf50037" + integrity sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw== + dependencies: + "@eslint/core" "^0.16.0" -"@eslint/core@^0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.15.2.tgz#59386327d7862cc3603ebc7c78159d2dcc4a868f" - integrity sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg== +"@eslint/core@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.16.0.tgz#490254f275ba9667ddbab344f4f0a6b7a7bd7209" + integrity sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q== dependencies: "@types/json-schema" "^7.0.15" @@ -1253,22 +1255,22 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.36.0", "@eslint/js@^9.36.0": - version "9.36.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.36.0.tgz#b1a3893dd6ce2defed5fd49de805ba40368e8fef" - integrity sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw== +"@eslint/js@9.37.0", "@eslint/js@^9.37.0": + version "9.37.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.37.0.tgz#0cfd5aa763fe5d1ee60bedf84cd14f54bcf9e21b" + integrity sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg== "@eslint/object-schema@^2.1.6": version "2.1.6" resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== -"@eslint/plugin-kit@^0.3.5": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz#fd8764f0ee79c8ddab4da65460c641cefee017c5" - integrity sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w== +"@eslint/plugin-kit@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz#f6a245b42886abf6fc9c7ab7744a932250335ab2" + integrity sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A== dependencies: - "@eslint/core" "^0.15.2" + "@eslint/core" "^0.16.0" levn "^0.4.1" "@firefox-devtools/react-contextmenu@^5.2.3": @@ -2316,10 +2318,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.18.10": - version "22.18.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.18.10.tgz#37f0ac8d2ec41af7bba06f162c85ff409e4e3420" - integrity sha512-anNG/V/Efn/YZY4pRzbACnKxNKoBng2VTFydVu8RRs5hQjikP8CQfaeAV59VFSCzKNp90mXiVXW2QzV56rwMrg== +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.18.12": + version "22.18.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.18.12.tgz#e165d87bc25d7bf6d3657035c914db7485de84fb" + integrity sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog== dependencies: undici-types "~6.21.0" @@ -4043,10 +4045,10 @@ core-js-compat@^3.43.0: dependencies: browserslist "^4.25.1" -core-js@^3.45.1: - version "3.45.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.45.1.tgz#5810e04a1b4e9bc5ddaa4dd12e702ff67300634d" - integrity sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg== +core-js@^3.46.0: + version "3.46.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.46.0.tgz#323a092b96381a9184d0cd49ee9083b2f93373bb" + integrity sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA== core-util-is@~1.0.0: version "1.0.3" @@ -5002,10 +5004,10 @@ eslint-plugin-react@^7.37.5: string.prototype.matchall "^4.0.12" string.prototype.repeat "^1.0.0" -eslint-plugin-testing-library@^7.6.8: - version "7.6.8" - resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.6.8.tgz#679757295d753fb4a96649d1cd2147aa5dda5de6" - integrity sha512-8qvVtc9gzYsBWJd2bMJByAlOdr/GBBH2RZygvp70OTivsJkLkYRxSZFtHq1XQK8k+zNi8DcV7aiSx3avE0rf2w== +eslint-plugin-testing-library@^7.13.3: + version "7.13.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.13.3.tgz#6edaca5609098e8869fd75afc48d7aa5ebfd0bc4" + integrity sha512-STwyXN7GnHulgsfdXVd5iC8fFCJVRQj2AcKtMmQOsA8G4oMnSCOX1p3MjbrDQ9fmwVf5wZy6vboTOTFobWuxOA== dependencies: "@typescript-eslint/scope-manager" "^8.15.0" "@typescript-eslint/utils" "^8.15.0" @@ -5046,19 +5048,19 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@^9.36.0: - version "9.36.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.36.0.tgz#9cc5cbbfb9c01070425d9bfed81b4e79a1c09088" - integrity sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ== +eslint@^9.37.0: + version "9.37.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.37.0.tgz#ac0222127f76b09c0db63036f4fe289562072d74" + integrity sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig== dependencies: "@eslint-community/eslint-utils" "^4.8.0" "@eslint-community/regexpp" "^4.12.1" "@eslint/config-array" "^0.21.0" - "@eslint/config-helpers" "^0.3.1" - "@eslint/core" "^0.15.2" + "@eslint/config-helpers" "^0.4.0" + "@eslint/core" "^0.16.0" "@eslint/eslintrc" "^3.3.1" - "@eslint/js" "9.36.0" - "@eslint/plugin-kit" "^0.3.5" + "@eslint/js" "9.37.0" + "@eslint/plugin-kit" "^0.4.0" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" @@ -5255,10 +5257,10 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fake-indexeddb@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-6.2.2.tgz#6e2448cf9e0fcd2f752bf024ba84b1ce47517d90" - integrity sha512-SGbf7fzjeHz3+12NO1dYigcYn4ivviaeULV5yY5rdGihBvvgwMds4r4UBbNIUMwkze57KTDm32rq3j1Az8mzEw== +fake-indexeddb@^6.2.4: + version "6.2.4" + resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-6.2.4.tgz#cf3860b6b37ddc3b33e7840be00a61ed094486a5" + integrity sha512-INKeIKEtSViN4yVtEWEUqbsqmaIy7Ls+MfU0yxQVXg67pOJ/sH1ZxcVrP8XrKULUFohcPD9gnmym+qBfEybACw== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" From 2e5c3e8c5cb68da7929f398f981565af98af807d Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 08:41:53 +0000 Subject: [PATCH 02/61] Pontoon/Firefox Profiler: Update French (fr), Russian (ru) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Théo Chevalier (fr) Co-authored-by: Valery Ledovskoy (ru) --- locales/fr/app.ftl | 10 ++++++++++ locales/ru/app.ftl | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/locales/fr/app.ftl b/locales/fr/app.ftl index 84068f8ab7..73d9d41378 100644 --- a/locales/fr/app.ftl +++ b/locales/fr/app.ftl @@ -368,6 +368,16 @@ MarkerTable--duration = Durée MarkerTable--name = Nom MarkerTable--details = Détails +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Afficher uniquement les marqueurs correspondant à « { $filter } » + .aria-label = Afficher uniquement les marqueurs correspondant à « { $filter } » + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. diff --git a/locales/ru/app.ftl b/locales/ru/app.ftl index d1fbb57896..d42c3596a0 100644 --- a/locales/ru/app.ftl +++ b/locales/ru/app.ftl @@ -449,6 +449,16 @@ MarkerTable--duration = Длительность MarkerTable--name = Имя MarkerTable--details = Подробности +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Показать только подходящие маркеры: «{ $filter }» + .aria-label = Показать только подходящие маркеры: «{ $filter }» + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 6682223b1879baf556de496908493135d4535115 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 09:21:58 +0000 Subject: [PATCH 03/61] Pontoon/Firefox Profiler: Update Italian (it) Co-authored-by: Francesco Lodolo [:flod] (it) --- locales/it/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/it/app.ftl b/locales/it/app.ftl index 8cf025594a..0e00a2c4c6 100644 --- a/locales/it/app.ftl +++ b/locales/it/app.ftl @@ -367,6 +367,16 @@ MarkerTable--duration = Durata MarkerTable--name = Nome MarkerTable--details = Dettagli +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Mostra solo i marker corrispondenti a: “{ $filter }” + .aria-label = Mostra solo i marker corrispondenti a: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From f2b9d1d96d4910217065b874c7dc27cfa1f50dd1 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 09:41:45 +0000 Subject: [PATCH 04/61] Pontoon/Firefox Profiler: Update Chinese (Taiwan) (zh-TW) Co-authored-by: Pin-guang Chen (zh-TW) --- locales/zh-TW/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/zh-TW/app.ftl b/locales/zh-TW/app.ftl index ca75bd3d5e..4358a6e6a0 100644 --- a/locales/zh-TW/app.ftl +++ b/locales/zh-TW/app.ftl @@ -363,6 +363,16 @@ MarkerTable--duration = 持續時間 MarkerTable--name = 名稱 MarkerTable--details = 詳細資訊 +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = 只顯示符合「{ $filter }」的標記 + .aria-label = 只顯示符合「{ $filter }」的標記 + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From f654f602ce5a9cc0b720aeba536243d8a945455f Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 10:32:06 +0000 Subject: [PATCH 05/61] Pontoon/Firefox Profiler: Update Dutch (nl) Co-authored-by: Mark Heijl (nl) --- locales/nl/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/nl/app.ftl b/locales/nl/app.ftl index c8c53ff0c8..39e1029626 100644 --- a/locales/nl/app.ftl +++ b/locales/nl/app.ftl @@ -451,6 +451,16 @@ MarkerTable--duration = Duur MarkerTable--name = Naam MarkerTable--details = Details +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Alleen markeringen tonen die overeenkomen met: ‘{ $filter }’ + .aria-label = Alleen markeringen tonen die overeenkomen met: ‘{ $filter }’ + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From a66a017501c3573763f6bcab7f428d8c8a3182f6 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 15:02:46 +0000 Subject: [PATCH 06/61] Pontoon/Firefox Profiler: Update Swedish (sv-SE) Co-authored-by: Andreas Pettersson (sv-SE) --- locales/sv-SE/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/sv-SE/app.ftl b/locales/sv-SE/app.ftl index 882fa9d3a6..1419fec85b 100644 --- a/locales/sv-SE/app.ftl +++ b/locales/sv-SE/app.ftl @@ -446,6 +446,16 @@ MarkerTable--duration = Längd MarkerTable--name = Namn MarkerTable--details = Detaljer +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Visa endast markörer som matchar: "{ $filter }" + .aria-label = Visa endast markörer som matchar: "{ $filter }" + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 689c162c08c8cca96d3fb146d0f718f2f17075f9 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 15:12:01 +0000 Subject: [PATCH 07/61] Pontoon/Firefox Profiler: Update German (de) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Köhler (de) --- locales/de/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/de/app.ftl b/locales/de/app.ftl index a7733a46a0..96b76cc3a2 100644 --- a/locales/de/app.ftl +++ b/locales/de/app.ftl @@ -427,6 +427,16 @@ MarkerTable--duration = Dauer MarkerTable--name = Name MarkerTable--details = Details +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Nur passende Markierungen anzeigen: „{ $filter }“ + .aria-label = Nur passende Markierungen anzeigen: „{ $filter }“ + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From f53d20c3561bbb94146a21ab40a9f8f48265363b Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 18:11:59 +0000 Subject: [PATCH 08/61] Pontoon/Firefox Profiler: Update English (Great Britain) (en-GB) Co-authored-by: Ian Neal (en-GB) --- locales/en-GB/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/en-GB/app.ftl b/locales/en-GB/app.ftl index 0be816d28d..33a6577884 100644 --- a/locales/en-GB/app.ftl +++ b/locales/en-GB/app.ftl @@ -451,6 +451,16 @@ MarkerTable--duration = Duration MarkerTable--name = Name MarkerTable--details = Details +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Only show markers matching: “{ $filter }” + .aria-label = Only show markers matching: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 061708a882a83120b49ae70642fbb463fc8f39f7 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Wed, 22 Oct 2025 20:02:29 +0000 Subject: [PATCH 09/61] Pontoon/Firefox Profiler: Update Frisian (fy-NL) Co-authored-by: Fjoerfoks (fy-NL) --- locales/fy-NL/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/fy-NL/app.ftl b/locales/fy-NL/app.ftl index f0a484c98f..817a69019a 100644 --- a/locales/fy-NL/app.ftl +++ b/locales/fy-NL/app.ftl @@ -451,6 +451,16 @@ MarkerTable--duration = Doer MarkerTable--name = Namme MarkerTable--details = Details +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Allinnich markearringen toane dy’t oerienkomme mei: ‘{ $filter }’ + .aria-label = Allinnich markearringen toane dy’t oerienkomme mei: ‘{ $filter }’ + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 3c4907923bc0f8a197c78d177d87767f11f0ea85 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Thu, 23 Oct 2025 01:21:57 +0000 Subject: [PATCH 10/61] Pontoon/Firefox Profiler: Update Chinese (China) (zh-CN) Co-authored-by: Olvcpr423 (zh-CN) --- locales/zh-CN/app.ftl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/locales/zh-CN/app.ftl b/locales/zh-CN/app.ftl index 29646aed80..9e07d68e78 100644 --- a/locales/zh-CN/app.ftl +++ b/locales/zh-CN/app.ftl @@ -39,6 +39,14 @@ AppViewRouter--error-from-localhost-url-safari = 由于 Safari 浏览器的 AppViewRouter--route-not-found--home = .specialMessage = 无法识别您尝试访问的 URL。 +## Backtrace +## This is used to display a backtrace (call stack) for a marker or sample. + +# Variables: +# $function (String) - Name of the function that was inlined. +Backtrace--inlining-badge = (已内联) + .title = 编译器已将 { $function } 内联至其调用方。 + ## CallNodeContextMenu ## This is used as a context menu for the Call Tree, Flame Graph and Stack Chart ## panels. From 4c609cb54d9d5bd35c9839b66b2594ac0efd7161 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Thu, 23 Oct 2025 03:02:25 +0000 Subject: [PATCH 11/61] Pontoon/Firefox Profiler: Update Interlingua (ia) Co-authored-by: Melo46 (ia) --- locales/ia/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/ia/app.ftl b/locales/ia/app.ftl index fe7749914d..84538dfe33 100644 --- a/locales/ia/app.ftl +++ b/locales/ia/app.ftl @@ -436,6 +436,16 @@ MarkerTable--duration = Duration MarkerTable--name = Nomine MarkerTable--details = Detalios +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Monstrar solo marcatores concordante: “{ $filter }” + .aria-label = Monstrar solo marcatores concordante: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From a21f1fee7f227a42701284639c9e080cd36157b9 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Mon, 27 Oct 2025 10:11:59 +0000 Subject: [PATCH 12/61] Pontoon/Firefox Profiler: Update Portuguese (Brazil) (pt-BR) Co-authored-by: Marcelo Ghelman (pt-BR) --- locales/pt-BR/app.ftl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/locales/pt-BR/app.ftl b/locales/pt-BR/app.ftl index 01dc2a81ea..de6ce28540 100644 --- a/locales/pt-BR/app.ftl +++ b/locales/pt-BR/app.ftl @@ -39,6 +39,14 @@ AppViewRouter--error-from-localhost-url-safari = Devido a uma limitação esp AppViewRouter--route-not-found--home = .specialMessage = A URL que você tentou acessar não foi reconhecida. +## Backtrace +## This is used to display a backtrace (call stack) for a marker or sample. + +# Variables: +# $function (String) - Name of the function that was inlined. +Backtrace--inlining-badge = (inlined) + .title = { $function } foi inlined no chamador pelo compilador. + ## CallNodeContextMenu ## This is used as a context menu for the Call Tree, Flame Graph and Stack Chart ## panels. @@ -366,6 +374,16 @@ MarkerTable--duration = Duração MarkerTable--name = Nome MarkerTable--details = Detalhes +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Mostrar apenas marcadores correspondentes a: “{ $filter }” + .aria-label = Mostrar apenas marcadores correspondentes a: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 74863e31cbdfc687ed8abd43e5b7125b6889cfb9 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Mon, 27 Oct 2025 12:02:13 +0000 Subject: [PATCH 13/61] Pontoon/Firefox Profiler: Update Turkish (tr) Co-authored-by: Grk (tr) --- locales/tr/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/tr/app.ftl b/locales/tr/app.ftl index 17a95499ea..65e99ff693 100644 --- a/locales/tr/app.ftl +++ b/locales/tr/app.ftl @@ -357,6 +357,16 @@ MarkerTable--duration = Süre MarkerTable--name = Ad MarkerTable--details = Ayrıntılar +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Yalnızca şununla eşleşen işaretleri göster: “{ $filter }” + .aria-label = Yalnızca şununla eşleşen işaretleri göster: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 26904094839504de2b8f9193971a37086e305c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Mon, 27 Oct 2025 15:24:10 +0100 Subject: [PATCH 14/61] Use getEmptySourceTable instead of constructing the table manually (#5641) --- src/profile-logic/global-data-collector.ts | 4 +++- src/profile-logic/merge-compare.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/profile-logic/global-data-collector.ts b/src/profile-logic/global-data-collector.ts index 8f9899529c..c23f0af7c9 100644 --- a/src/profile-logic/global-data-collector.ts +++ b/src/profile-logic/global-data-collector.ts @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { StringTable } from '../utils/string-table'; +import { getEmptySourceTable } from './data-structures'; + import type { Lib, LibMapping, @@ -26,7 +28,7 @@ export class GlobalDataCollector { _libKeyToLibIndex: Map = new Map(); _stringArray: string[] = []; _stringTable: StringTable = StringTable.withBackingArray(this._stringArray); - _sources: SourceTable = { length: 0, uuid: [], filename: [] }; + _sources: SourceTable = getEmptySourceTable(); _uuidToSourceIndex: Map = new Map(); _filenameToSourceIndex: Map = new Map(); diff --git a/src/profile-logic/merge-compare.ts b/src/profile-logic/merge-compare.ts index be1bdaabdd..4cdfe05f76 100644 --- a/src/profile-logic/merge-compare.ts +++ b/src/profile-logic/merge-compare.ts @@ -19,6 +19,7 @@ import { getEmptyRawMarkerTable, getEmptySamplesTableWithEventDelay, shallowCloneRawMarkerTable, + getEmptySourceTable, } from './data-structures'; import { filterRawThreadSamplesToRange, @@ -499,7 +500,7 @@ function mergeSources( sources: SourceTable; translationMaps: TranslationMapForSources[]; } { - const newSources: SourceTable = { length: 0, uuid: [], filename: [] }; + const newSources = getEmptySourceTable(); const mapOfInsertedSources: Map = new Map(); const translationMaps = sourcesPerProfile.map((sources, profileIndex) => { From 511065e45b45971a135afb3b429f05064571e74f Mon Sep 17 00:00:00 2001 From: Pontoon Date: Tue, 28 Oct 2025 23:12:04 +0000 Subject: [PATCH 15/61] Pontoon/Firefox Profiler: Update Spanish (Chile) (es-CL) Co-authored-by: ravmn (es-CL) --- locales/es-CL/app.ftl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/locales/es-CL/app.ftl b/locales/es-CL/app.ftl index b1ecf4ba4d..4c2f7f4543 100644 --- a/locales/es-CL/app.ftl +++ b/locales/es-CL/app.ftl @@ -39,6 +39,14 @@ AppViewRouter--error-from-localhost-url-safari = Debido a una limitación esp AppViewRouter--route-not-found--home = .specialMessage = La URL a la que intentaste acceder no fue reconocida. +## Backtrace +## This is used to display a backtrace (call stack) for a marker or sample. + +# Variables: +# $function (String) - Name of the function that was inlined. +Backtrace--inlining-badge = (incorporadas) + .title = { $function } fue incorporada en la función que lo llamó por el compilador. + ## CallNodeContextMenu ## This is used as a context menu for the Call Tree, Flame Graph and Stack Chart ## panels. @@ -374,6 +382,16 @@ MarkerTable--duration = Duración MarkerTable--name = Nombre MarkerTable--details = Detalles +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Mostrar solo marcadores que coincidan con: “{ $filter }” + .aria-label = Mostrar solo marcadores que coincidan con: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From 3ec0bc990d8d0a52dd7d8f50fe9ad91d8c766773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 9 Oct 2025 11:00:53 +0200 Subject: [PATCH 16/61] Show the source code when clicking a marker stack frame in the marker table sidebar. --- src/components/shared/Backtrace.css | 10 ++ src/components/shared/Backtrace.tsx | 164 +++++++++++++++-------- src/components/sidebar/MarkerSidebar.tsx | 39 +++++- src/components/tooltip/Marker.tsx | 5 + src/profile-logic/profile-data.ts | 47 +++++++ src/profile-logic/transforms.ts | 12 +- 6 files changed, 214 insertions(+), 63 deletions(-) diff --git a/src/components/shared/Backtrace.css b/src/components/shared/Backtrace.css index b38ab0bad2..2cb6cf9b76 100644 --- a/src/components/shared/Backtrace.css +++ b/src/components/shared/Backtrace.css @@ -30,3 +30,13 @@ .backtraceStackFrame_isFrameLabel { color: rgb(0 0 0 / 0.6); } + +.backtraceStackFrame_link { + display: block; + color: inherit; + text-decoration: none; +} + +.backtraceStackFrame_link:hover { + background-color: rgb(0 0 0 / 0.05); +} diff --git a/src/components/shared/Backtrace.tsx b/src/components/shared/Backtrace.tsx index 7fce17be26..661eb8fd4d 100644 --- a/src/components/shared/Backtrace.tsx +++ b/src/components/shared/Backtrace.tsx @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import * as React from 'react'; import classNames from 'classnames'; import { Localized } from '@fluent/react'; import { getBacktraceItemsForStack } from 'firefox-profiler/profile-logic/transforms'; @@ -24,68 +25,115 @@ type Props = { readonly stackIndex: IndexIntoStackTable; readonly implementationFilter: ImplementationFilter; readonly categories: CategoryList; + readonly onStackFrameClick?: (stackIndex: IndexIntoStackTable) => void; }; -export function Backtrace(props: Props) { - const { stackIndex, thread, implementationFilter, maxStacks, categories } = - props; - const funcNamesAndOrigins = getBacktraceItemsForStack( - stackIndex, - implementationFilter, - thread - ); +export class Backtrace extends React.PureComponent { + _handleStackFrameClick = (event: React.MouseEvent) => { + event.preventDefault(); + const stackIdx = event.currentTarget.getAttribute('data-stackindex'); + this.props.onStackFrameClick!(Number(stackIdx)); + }; - if (funcNamesAndOrigins.length) { - return ( -
    - {funcNamesAndOrigins - // Truncate the stacks - .slice(0, maxStacks) - .map( - ({ funcName, origin, isFrameLabel, category, inlineDepth }, i) => ( -
  • - - {inlineDepth > 0 ? ( - + {backtraceItems + // Truncate the stacks + .slice(0, maxStacks) + .map( + ( + { + funcName, + origin, + isFrameLabel, + category, + inlineDepth, + stackIndex, + }, + i + ) => { + const frameContent = ( + <> + + {inlineDepth > 0 ? ( + + + (inlined) + + + ) : null} + {funcName} + {origin} + + ); + + return ( +
  • - - (inlined) - - - ) : null} - {funcName} - {origin} -
  • - ) - )} - {funcNamesAndOrigins.length > maxStacks - ? [ - , - '…', - ] - : null} -
+ {onStackFrameClick && stackIndex !== null ? ( +
+ {frameContent} + + ) : ( + frameContent + )} + + ); + } + )} + {backtraceItems.length > maxStacks + ? [ + , + '…', + ] + : null} + + ); + } + return ( +
+ (The stack is empty because all of its frames are filtered out by the + implementation filter. Switch the implementation filter in the call tree + to see more frames.) +
); } - return ( -
- (The stack is empty because all of its frames are filtered out by the - implementation filter. Switch the implementation filter in the call tree - to see more frames.) -
- ); } diff --git a/src/components/sidebar/MarkerSidebar.tsx b/src/components/sidebar/MarkerSidebar.tsx index ca661dab3c..0ffbd9db69 100644 --- a/src/components/sidebar/MarkerSidebar.tsx +++ b/src/components/sidebar/MarkerSidebar.tsx @@ -7,21 +7,46 @@ import { Localized } from '@fluent/react'; import explicitConnect from 'firefox-profiler/utils/connect'; import { selectedThreadSelectors } from 'firefox-profiler/selectors/per-thread'; -import { getSelectedThreadsKey } from 'firefox-profiler/selectors/url-state'; +import { + getSelectedThreadsKey, + getSelectedTab, +} from 'firefox-profiler/selectors/url-state'; import { TooltipMarker } from 'firefox-profiler/components/tooltip/Marker'; +import { updateBottomBoxContentsAndMaybeOpen } from 'firefox-profiler/actions/profile-view'; +import { getBottomBoxInfoForStackFrame } from 'firefox-profiler/profile-logic/profile-data'; import type { ConnectedProps } from 'firefox-profiler/utils/connect'; -import type { ThreadsKey, Marker, MarkerIndex } from 'firefox-profiler/types'; +import type { + ThreadsKey, + Marker, + MarkerIndex, + IndexIntoStackTable, + Thread, +} from 'firefox-profiler/types'; +import type { TabSlug } from 'firefox-profiler/app-logic/tabs-handling'; type StateProps = { readonly selectedThreadsKey: ThreadsKey; readonly marker: Marker | null; readonly markerIndex: MarkerIndex | null; + readonly thread: Thread; + readonly selectedTab: TabSlug; }; -type Props = ConnectedProps<{}, StateProps, {}>; +type DispatchProps = { + readonly updateBottomBoxContentsAndMaybeOpen: typeof updateBottomBoxContentsAndMaybeOpen; +}; + +type Props = ConnectedProps<{}, StateProps, DispatchProps>; class MarkerSidebarImpl extends React.PureComponent { + _onStackFrameClick = (stackIndex: IndexIntoStackTable) => { + const { thread, selectedTab, updateBottomBoxContentsAndMaybeOpen } = + this.props; + const bottomBoxInfo = getBottomBoxInfoForStackFrame(stackIndex, thread); + updateBottomBoxContentsAndMaybeOpen(selectedTab, bottomBoxInfo); + }; + override render() { const { marker, markerIndex, selectedThreadsKey } = this.props; @@ -45,6 +70,7 @@ class MarkerSidebarImpl extends React.PureComponent { marker={marker} threadsKey={selectedThreadsKey} restrictHeightWidth={false} + onStackFrameClick={this._onStackFrameClick} /> @@ -52,11 +78,16 @@ class MarkerSidebarImpl extends React.PureComponent { } } -export const MarkerSidebar = explicitConnect<{}, StateProps, {}>({ +export const MarkerSidebar = explicitConnect<{}, StateProps, DispatchProps>({ mapStateToProps: (state) => ({ marker: selectedThreadSelectors.getSelectedMarker(state), markerIndex: selectedThreadSelectors.getSelectedMarkerIndex(state), selectedThreadsKey: getSelectedThreadsKey(state), + thread: selectedThreadSelectors.getThread(state), + selectedTab: getSelectedTab(state), }), + mapDispatchToProps: { + updateBottomBoxContentsAndMaybeOpen, + }, component: MarkerSidebarImpl, }); diff --git a/src/components/tooltip/Marker.tsx b/src/components/tooltip/Marker.tsx index 2e8fd4af55..0955b108e0 100644 --- a/src/components/tooltip/Marker.tsx +++ b/src/components/tooltip/Marker.tsx @@ -55,6 +55,7 @@ import type { Page, Pid, Tid, + IndexIntoStackTable, } from 'firefox-profiler/types'; import type { ConnectedProps } from 'firefox-profiler/utils/connect'; @@ -85,6 +86,8 @@ type OwnProps = { // the layout to be huge. This option when set to true will restrict the // height of things like stacks, and the width of long things like URLs. readonly restrictHeightWidth: boolean; + // Optional callback for when a stack frame is clicked in the backtrace. + readonly onStackFrameClick?: (stackIndex: IndexIntoStackTable) => void; }; type StateProps = { @@ -428,6 +431,7 @@ class MarkerTooltipContents extends React.PureComponent { implementationFilter, restrictHeightWidth, categories, + onStackFrameClick, } = this.props; const { data, start } = marker; if (!data || !('cause' in data) || !data.cause) { @@ -463,6 +467,7 @@ class MarkerTooltipContents extends React.PureComponent { thread={thread} implementationFilter={implementationFilter} categories={categories} + onStackFrameClick={onStackFrameClick} /> , diff --git a/src/profile-logic/profile-data.ts b/src/profile-logic/profile-data.ts index 7c9b4911ae..9ded1a824f 100644 --- a/src/profile-logic/profile-data.ts +++ b/src/profile-logic/profile-data.ts @@ -4005,6 +4005,53 @@ export function getBottomBoxInfoForCallNode( }; } +/** + * Get bottom box info for a stack frame. This is similar to + * getBottomBoxInfoForCallNode but works directly with stack indexes. + */ +export function getBottomBoxInfoForStackFrame( + stackIndex: IndexIntoStackTable, + thread: Thread +): BottomBoxInfo { + const { + stackTable, + frameTable, + funcTable, + resourceTable, + nativeSymbols, + stringTable, + } = thread; + + const frameIndex = stackTable.frame[stackIndex]; + const funcIndex = frameTable.func[frameIndex]; + const sourceIndex = funcTable.source[funcIndex]; + const resource = funcTable.resource[funcIndex]; + const libIndex = + resource !== -1 && resourceTable.type[resource] === resourceTypes.library + ? resourceTable.lib[resource] + : null; + + // Get native symbol for this frame + const nativeSymbol = frameTable.nativeSymbol[frameIndex]; + const nativeSymbolInfos = + nativeSymbol !== null + ? [ + getNativeSymbolInfo( + nativeSymbol, + nativeSymbols, + frameTable, + stringTable + ), + ] + : []; + + return { + libIndex, + sourceIndex, + nativeSymbols: nativeSymbolInfos, + }; +} + /** * Determines the timeline type by looking at the profile data. * diff --git a/src/profile-logic/transforms.ts b/src/profile-logic/transforms.ts index 0e52d6429b..47f6001661 100644 --- a/src/profile-logic/transforms.ts +++ b/src/profile-logic/transforms.ts @@ -1591,6 +1591,7 @@ export type BacktraceItem = { origin: string; // The inline depth of this frame. Frames with inline depth > 0 are inlined. inlineDepth: number; + stackIndex: IndexIntoStackTable; }; /** @@ -1619,6 +1620,7 @@ export function getBacktraceItemsForStack( frameLine: frameTable.line[frameIndex], frameColumn: frameTable.column[frameIndex], inlineDepth: frameTable.inlineDepth[frameIndex], + stackIndex, }); } @@ -1627,7 +1629,14 @@ export function getBacktraceItemsForStack( funcMatchesImplementation(thread, funcIndex) ); return path.map( - ({ category, funcIndex, frameLine, frameColumn, inlineDepth }) => { + ({ + category, + funcIndex, + frameLine, + frameColumn, + inlineDepth, + stackIndex, + }) => { return { funcName: stringTable.getString(funcTable.name[funcIndex]), category, @@ -1642,6 +1651,7 @@ export function getBacktraceItemsForStack( frameColumn ), inlineDepth, + stackIndex, }; } ); From 2bf617c883fa5b514f40b083df21f7ce1e16c456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 9 Oct 2025 11:57:40 +0200 Subject: [PATCH 17/61] Scroll to the line of the clicked frame of the marker stack rather than to the hotspot. --- src/actions/profile-view.ts | 3 ++- src/components/app/BottomBox.tsx | 5 +++++ src/components/shared/SourceView.tsx | 15 +++++++++++++-- src/profile-logic/profile-data.ts | 4 ++++ src/reducers/url-state.ts | 1 + src/selectors/url-state.ts | 2 ++ src/types/actions.ts | 1 + src/types/profile-derived.ts | 3 +++ src/types/state.ts | 3 +++ 9 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/actions/profile-view.ts b/src/actions/profile-view.ts index 9ca988d8cc..e518623d26 100644 --- a/src/actions/profile-view.ts +++ b/src/actions/profile-view.ts @@ -1917,7 +1917,7 @@ export function changeTableViewOptions( export function updateBottomBoxContentsAndMaybeOpen( currentTab: TabSlug, - { libIndex, sourceIndex, nativeSymbols }: BottomBoxInfo + { libIndex, sourceIndex, nativeSymbols, lineNumber }: BottomBoxInfo ): Action { // TODO: If the set has more than one element, pick the native symbol with // the highest total sample count @@ -1932,6 +1932,7 @@ export function updateBottomBoxContentsAndMaybeOpen( currentTab, shouldOpenBottomBox: sourceIndex !== null || nativeSymbol !== null, shouldOpenAssemblyView: sourceIndex === null && nativeSymbol !== null, + lineNumber, }; } diff --git a/src/components/app/BottomBox.tsx b/src/components/app/BottomBox.tsx index 4f5d8d2434..d8589ae4e8 100644 --- a/src/components/app/BottomBox.tsx +++ b/src/components/app/BottomBox.tsx @@ -14,6 +14,7 @@ import { CodeLoadingOverlay } from './CodeLoadingOverlay'; import { CodeErrorOverlay } from './CodeErrorOverlay'; import { getSourceViewScrollGeneration, + getSourceViewLineNumber, getAssemblyViewIsOpen, getAssemblyViewNativeSymbol, getAssemblyViewScrollGeneration, @@ -54,6 +55,7 @@ type StateProps = { readonly sourceViewFile: string | null; readonly sourceViewCode: SourceCodeStatus | void; readonly sourceViewScrollGeneration: number; + readonly sourceViewLineNumber?: number; readonly globalLineTimings: LineTimings; readonly selectedCallNodeLineTimings: LineTimings; readonly assemblyViewIsOpen: boolean; @@ -160,6 +162,7 @@ class BottomBoxImpl extends React.PureComponent { globalLineTimings, disableOverscan, sourceViewScrollGeneration, + sourceViewLineNumber, selectedCallNodeLineTimings, assemblyViewIsOpen, assemblyViewScrollGeneration, @@ -231,6 +234,7 @@ class BottomBoxImpl extends React.PureComponent { sourceCode={sourceCode} filePath={path} scrollToHotSpotGeneration={sourceViewScrollGeneration} + scrollToLineNumber={sourceViewLineNumber} hotSpotTimings={selectedCallNodeLineTimings} ref={this._sourceView} /> @@ -300,6 +304,7 @@ export const BottomBox = explicitConnect<{}, StateProps, DispatchProps>({ selectedCallNodeLineTimings: selectedNodeSelectors.getSourceViewLineTimings(state), sourceViewScrollGeneration: getSourceViewScrollGeneration(state), + sourceViewLineNumber: getSourceViewLineNumber(state), assemblyViewNativeSymbol: getAssemblyViewNativeSymbol(state), assemblyViewCode: getAssemblyViewCode(state), globalAddressTimings: diff --git a/src/components/shared/SourceView.tsx b/src/components/shared/SourceView.tsx index 7add445b0c..2a720d227e 100644 --- a/src/components/shared/SourceView.tsx +++ b/src/components/shared/SourceView.tsx @@ -43,6 +43,7 @@ type SourceViewProps = { readonly disableOverscan: boolean; readonly filePath: string | null; readonly scrollToHotSpotGeneration: number; + readonly scrollToLineNumber?: number; readonly hotSpotTimings: LineTimings; }; @@ -143,7 +144,12 @@ export class SourceView extends React.PureComponent { domParent ); this._editor = editor; - this._scrollToHotSpot(this.props.hotSpotTimings); + // If an explicit line number is provided, scroll to it. Otherwise, scroll to the hotspot. + if (this.props.scrollToLineNumber !== undefined) { + this._scrollToLine(Math.max(1, this.props.scrollToLineNumber - 5)); + } else { + this._scrollToHotSpot(this.props.hotSpotTimings); + } })(); } @@ -174,7 +180,12 @@ export class SourceView extends React.PureComponent { this.props.scrollToHotSpotGeneration !== prevProps.scrollToHotSpotGeneration ) { - this._scrollToHotSpot(this.props.hotSpotTimings); + // If an explicit line number is provided, scroll to it. Otherwise, scroll to the hotspot. + if (this.props.scrollToLineNumber !== undefined) { + this._scrollToLine(Math.max(1, this.props.scrollToLineNumber - 5)); + } else { + this._scrollToHotSpot(this.props.hotSpotTimings); + } } if (this.props.timings !== prevProps.timings) { diff --git a/src/profile-logic/profile-data.ts b/src/profile-logic/profile-data.ts index 9ded1a824f..51a54457e1 100644 --- a/src/profile-logic/profile-data.ts +++ b/src/profile-logic/profile-data.ts @@ -4045,10 +4045,14 @@ export function getBottomBoxInfoForStackFrame( ] : []; + // Extract line number from the frame + const lineNumber = frameTable.line[frameIndex] ?? undefined; + return { libIndex, sourceIndex, nativeSymbols: nativeSymbolInfos, + lineNumber, }; } diff --git a/src/reducers/url-state.ts b/src/reducers/url-state.ts index 9469e9a90e..2813575b15 100644 --- a/src/reducers/url-state.ts +++ b/src/reducers/url-state.ts @@ -570,6 +570,7 @@ const sourceView: Reducer = ( scrollGeneration: state.scrollGeneration + 1, libIndex: action.libIndex, sourceIndex: action.sourceIndex, + lineNumber: action.lineNumber, }; } default: diff --git a/src/selectors/url-state.ts b/src/selectors/url-state.ts index ecb21e6103..48b7e17146 100644 --- a/src/selectors/url-state.ts +++ b/src/selectors/url-state.ts @@ -75,6 +75,8 @@ export const getSourceViewSourceIndex: Selector = ( ) => getProfileSpecificState(state).sourceView.sourceIndex; export const getSourceViewScrollGeneration: Selector = (state) => getProfileSpecificState(state).sourceView.scrollGeneration; +export const getSourceViewLineNumber: Selector = (state) => + getProfileSpecificState(state).sourceView.lineNumber; export const getAssemblyViewIsOpen: Selector = (state) => getProfileSpecificState(state).assemblyView.isOpen; export const getAssemblyViewNativeSymbol: Selector = ( diff --git a/src/types/actions.ts b/src/types/actions.ts index 9f6768b75d..cf2465ee78 100644 --- a/src/types/actions.ts +++ b/src/types/actions.ts @@ -343,6 +343,7 @@ type ProfileAction = readonly currentTab: TabSlug; readonly shouldOpenBottomBox: boolean; readonly shouldOpenAssemblyView: boolean; + readonly lineNumber?: number; } | { readonly type: 'OPEN_ASSEMBLY_VIEW'; diff --git a/src/types/profile-derived.ts b/src/types/profile-derived.ts index af23ef1028..3ee00c355b 100644 --- a/src/types/profile-derived.ts +++ b/src/types/profile-derived.ts @@ -775,6 +775,9 @@ export type BottomBoxInfo = { libIndex: IndexIntoLibs | null; sourceIndex: IndexIntoSourceTable | null; nativeSymbols: NativeSymbolInfo[]; + // Optional line number to scroll to in the source view. + // If not specified, the source view will scroll to the hottest line. + lineNumber?: number; }; /** diff --git a/src/types/state.ts b/src/types/state.ts index 08df9b8213..54c83a32bd 100644 --- a/src/types/state.ts +++ b/src/types/state.ts @@ -247,6 +247,9 @@ export type SourceViewState = { // Index into source table. Contains information (filename and uuid) about the // source. Null if a function without a file path was double clicked. sourceIndex: IndexIntoSourceTable | null; + // Optional line number to scroll to in the source view. + // If not specified, the source view will scroll to the hottest line. + lineNumber?: number; }; export type AssemblyViewState = { From 5b1adf10212f86aa6233cfa4656d891411fce5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 9 Oct 2025 12:56:00 +0200 Subject: [PATCH 18/61] Show the source code when clicking a marker stack frame in the marker chart tooltip. --- src/components/marker-chart/Canvas.tsx | 16 ++++++++++++++++ src/components/marker-chart/index.tsx | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/components/marker-chart/Canvas.tsx b/src/components/marker-chart/Canvas.tsx index d1051b4c4d..3e41d94b75 100644 --- a/src/components/marker-chart/Canvas.tsx +++ b/src/components/marker-chart/Canvas.tsx @@ -17,6 +17,7 @@ import type { changeRightClickedMarker, changeMouseTimePosition, changeSelectedMarker, + updateBottomBoxContentsAndMaybeOpen, } from 'firefox-profiler/actions/profile-view'; type UpdatePreviewSelection = typeof updatePreviewSelection; @@ -35,7 +36,10 @@ import type { MarkerIndex, MarkerSchemaByName, GraphColor, + Thread, + IndexIntoStackTable, } from 'firefox-profiler/types'; +import type { TabSlug } from 'firefox-profiler/app-logic/tabs-handling'; import { getStartEndRangeForMarker } from 'firefox-profiler/utils'; import { getStrokeColor, @@ -45,6 +49,7 @@ import { isValidGraphColor, } from 'firefox-profiler/profile-logic/graph-color'; import { getSchemaFromMarker } from 'firefox-profiler/profile-logic/marker-schema'; +import { getBottomBoxInfoForStackFrame } from 'firefox-profiler/profile-logic/profile-data'; import type { ChartCanvasScale, @@ -81,6 +86,9 @@ type OwnProps = { readonly selectedMarkerIndex: MarkerIndex | null; readonly rightClickedMarkerIndex: MarkerIndex | null; readonly shouldDisplayTooltips: () => boolean; + readonly thread: Thread; + readonly updateBottomBoxContentsAndMaybeOpen: typeof updateBottomBoxContentsAndMaybeOpen; + readonly selectedTab: TabSlug; }; type Props = OwnProps & { @@ -869,6 +877,13 @@ class MarkerChartCanvasImpl extends React.PureComponent { changeRightClickedMarker(threadsKey, markerIndex); }; + _onStackFrameClick = (stackIndex: IndexIntoStackTable) => { + const { thread, selectedTab, updateBottomBoxContentsAndMaybeOpen } = + this.props; + const bottomBoxInfo = getBottomBoxInfoForStackFrame(stackIndex, thread); + updateBottomBoxContentsAndMaybeOpen(selectedTab, bottomBoxInfo); + }; + getHoveredMarkerInfo = (markerIndex: MarkerIndex): React.ReactNode => { if (!this.props.shouldDisplayTooltips() || markerIndex === null) { return null; @@ -881,6 +896,7 @@ class MarkerChartCanvasImpl extends React.PureComponent { marker={marker} threadsKey={this.props.threadsKey} restrictHeightWidth={true} + onStackFrameClick={this._onStackFrameClick} /> ); }; diff --git a/src/components/marker-chart/index.tsx b/src/components/marker-chart/index.tsx index 68a12c1dc6..93bb9a1e96 100644 --- a/src/components/marker-chart/index.tsx +++ b/src/components/marker-chart/index.tsx @@ -17,12 +17,16 @@ import { getMarkerSchemaByName, } from 'firefox-profiler/selectors/profile'; import { selectedThreadSelectors } from 'firefox-profiler/selectors/per-thread'; -import { getSelectedThreadsKey } from 'firefox-profiler/selectors/url-state'; +import { + getSelectedThreadsKey, + getSelectedTab, +} from 'firefox-profiler/selectors/url-state'; import { updatePreviewSelection, changeRightClickedMarker, changeMouseTimePosition, changeSelectedMarker, + updateBottomBoxContentsAndMaybeOpen, } from 'firefox-profiler/actions/profile-view'; import { ContextMenuTrigger } from 'firefox-profiler/components/shared/ContextMenuTrigger'; @@ -35,7 +39,9 @@ import type { StartEndRange, PreviewSelection, ThreadsKey, + Thread, } from 'firefox-profiler/types'; +import type { TabSlug } from 'firefox-profiler/app-logic/tabs-handling'; import type { ConnectedProps } from 'firefox-profiler/utils/connect'; @@ -48,6 +54,7 @@ type DispatchProps = { readonly changeRightClickedMarker: typeof changeRightClickedMarker; readonly changeMouseTimePosition: typeof changeMouseTimePosition; readonly changeSelectedMarker: typeof changeSelectedMarker; + readonly updateBottomBoxContentsAndMaybeOpen: typeof updateBottomBoxContentsAndMaybeOpen; }; type StateProps = { @@ -62,6 +69,8 @@ type StateProps = { readonly previewSelection: PreviewSelection | null; readonly rightClickedMarkerIndex: MarkerIndex | null; readonly selectedMarkerIndex: MarkerIndex | null; + readonly thread: Thread; + readonly selectedTab: TabSlug; }; type Props = ConnectedProps<{}, StateProps, DispatchProps>; @@ -171,6 +180,10 @@ class MarkerChartImpl extends React.PureComponent { selectedMarkerIndex, rightClickedMarkerIndex, shouldDisplayTooltips: this._shouldDisplayTooltips, + thread: this.props.thread, + updateBottomBoxContentsAndMaybeOpen: + this.props.updateBottomBoxContentsAndMaybeOpen, + selectedTab: this.props.selectedTab, }} /> @@ -206,6 +219,8 @@ export const MarkerChart = explicitConnect<{}, StateProps, DispatchProps>({ selectedThreadSelectors.getRightClickedMarkerIndex(state), selectedMarkerIndex: selectedThreadSelectors.getSelectedMarkerIndex(state), + thread: selectedThreadSelectors.getThread(state), + selectedTab: getSelectedTab(state), }; }, mapDispatchToProps: { @@ -213,6 +228,7 @@ export const MarkerChart = explicitConnect<{}, StateProps, DispatchProps>({ changeMouseTimePosition, changeRightClickedMarker, changeSelectedMarker, + updateBottomBoxContentsAndMaybeOpen, }, component: MarkerChartImpl, }); From 5e887fa8469c51e5ff253aed1c62f1ca9b238a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 9 Oct 2025 13:36:16 +0200 Subject: [PATCH 19/61] Keep the selected marker tooltip visible when the marker chart is updated without hiding the selected marker (symbolication, showing the source code for a frame). --- src/components/marker-chart/Canvas.tsx | 19 +++++++++++++++++++ src/components/shared/chart/Canvas.tsx | 14 +++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/components/marker-chart/Canvas.tsx b/src/components/marker-chart/Canvas.tsx index 3e41d94b75..ec6544ad32 100644 --- a/src/components/marker-chart/Canvas.tsx +++ b/src/components/marker-chart/Canvas.tsx @@ -884,11 +884,30 @@ class MarkerChartCanvasImpl extends React.PureComponent { updateBottomBoxContentsAndMaybeOpen(selectedTab, bottomBoxInfo); }; + isMarkerVisible = (markerIndex: MarkerIndex): boolean => { + const { markerTimingAndBuckets } = this.props; + // Check if the marker appears in the visible marker timing data + for (const markerTiming of markerTimingAndBuckets) { + if (typeof markerTiming === 'string') { + continue; + } + if (markerTiming.index.includes(markerIndex)) { + return true; + } + } + return false; + }; + getHoveredMarkerInfo = (markerIndex: MarkerIndex): React.ReactNode => { if (!this.props.shouldDisplayTooltips() || markerIndex === null) { return null; } + // Check if the marker is visible (not filtered out) + if (!this.isMarkerVisible(markerIndex)) { + return null; + } + const marker = this.props.getMarker(markerIndex); return ( extends React.Component< this.state.selectedItem !== null && prevState.selectedItem === this.state.selectedItem ) { - // The props have changed but not the selectedItem. This mean that the - // selected item can get out of sync. Invalidate it to make sure that - // it's always fresh. This setState will cause a rerender, but we have - // to do it to prevent any crashes or incorrect tooltip positions. - // This is okay to do it because the main `prevProps !== this.props` - // check above will return false and will not schedule additional drawing. - this.setState({ selectedItem: null }); + // The props have changed but not the selectedItem. Check if it's still valid + // by attempting to get its info. If it returns null, the item is no longer + // valid (e.g., filtered out). + const info = this.props.getHoveredItemInfo(this.state.selectedItem); + if (info === null) { + this.setState({ selectedItem: null }); + } } this._scheduleDraw(); } else if ( From 1c88882f8c556c0763580e5cdceb05f97e9fa365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 9 Oct 2025 13:53:28 +0200 Subject: [PATCH 20/61] Highlight the line we scroll to in the code viewer. --- src/components/app/BottomBox.tsx | 1 + src/components/shared/CodeView.css | 4 ++ .../shared/SourceView-codemirror.ts | 15 ++++++++ src/components/shared/SourceView.tsx | 6 +++ src/utils/codemirror-shared.ts | 37 +++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/src/components/app/BottomBox.tsx b/src/components/app/BottomBox.tsx index d8589ae4e8..c2631c42fb 100644 --- a/src/components/app/BottomBox.tsx +++ b/src/components/app/BottomBox.tsx @@ -236,6 +236,7 @@ class BottomBoxImpl extends React.PureComponent { scrollToHotSpotGeneration={sourceViewScrollGeneration} scrollToLineNumber={sourceViewLineNumber} hotSpotTimings={selectedCallNodeLineTimings} + highlightedLine={sourceViewLineNumber} ref={this._sourceView} /> ) : null} diff --git a/src/components/shared/CodeView.css b/src/components/shared/CodeView.css index 4d47ab4139..0798eb14ad 100644 --- a/src/components/shared/CodeView.css +++ b/src/components/shared/CodeView.css @@ -125,6 +125,10 @@ background-color: #edf6ff; } +.cm-highlightedLine { + background-color: #fffbcc; +} + .cm-content { font-family: ui-monospace, 'Roboto Mono', monospace; hyphens: none; diff --git a/src/components/shared/SourceView-codemirror.ts b/src/components/shared/SourceView-codemirror.ts index 446d78b745..dfed4e60fa 100644 --- a/src/components/shared/SourceView-codemirror.ts +++ b/src/components/shared/SourceView-codemirror.ts @@ -31,12 +31,16 @@ import type { LineTimings } from 'firefox-profiler/types'; import { timingsExtension, updateTimingsEffect, + createHighlightedLineExtension, } from 'firefox-profiler/utils/codemirror-shared'; // This "compartment" allows us to swap the syntax highlighting language when // the file path changes. const languageConf = new Compartment(); +// This "compartment" allows us to swap the highlighted line when it changes. +const highlightedLineConf = new Compartment(); + // Detect the right language based on the file extension. function _languageExtForPath( path: string | null @@ -89,6 +93,7 @@ export class SourceViewEditor { initialText: string, path: string, timings: LineTimings, + highlightedLine: number | null, domParent: Element ) { let state = EditorState.create({ @@ -97,6 +102,7 @@ export class SourceViewEditor { timingsExtension, lineNumbers(), languageConf.of(_languageExtForPath(path)), + highlightedLineConf.of(createHighlightedLineExtension(highlightedLine)), syntaxHighlighting(classHighlighter), codeViewerExtension, ], @@ -137,6 +143,15 @@ export class SourceViewEditor { }); } + setHighlightedLine(lineNumber: number | null) { + // Update the highlighted line by reconfiguring the compartment. + this._view.dispatch({ + effects: highlightedLineConf.reconfigure( + createHighlightedLineExtension(lineNumber) + ), + }); + } + scrollToLine(lineNumber: number) { // Clamp the line number to the document's line count. lineNumber = clamp(lineNumber, 1, this._view.state.doc.lines); diff --git a/src/components/shared/SourceView.tsx b/src/components/shared/SourceView.tsx index 2a720d227e..7563e42d79 100644 --- a/src/components/shared/SourceView.tsx +++ b/src/components/shared/SourceView.tsx @@ -45,6 +45,7 @@ type SourceViewProps = { readonly scrollToHotSpotGeneration: number; readonly scrollToLineNumber?: number; readonly hotSpotTimings: LineTimings; + readonly highlightedLine?: number; }; let editorModulePromise: Promise | null = null; @@ -141,6 +142,7 @@ export class SourceView extends React.PureComponent { this._getSourceCodeOrFallback(), this.props.filePath, this.props.timings, + this.props.highlightedLine ?? null, domParent ); this._editor = editor; @@ -191,5 +193,9 @@ export class SourceView extends React.PureComponent { if (this.props.timings !== prevProps.timings) { this._editor.setTimings(this.props.timings); } + + if (this.props.highlightedLine !== prevProps.highlightedLine) { + this._editor.setHighlightedLine(this.props.highlightedLine ?? null); + } } } diff --git a/src/utils/codemirror-shared.ts b/src/utils/codemirror-shared.ts index 16c04454e8..b19b24b15a 100644 --- a/src/utils/codemirror-shared.ts +++ b/src/utils/codemirror-shared.ts @@ -29,6 +29,16 @@ const nonZeroLineDecoration = Decoration.line({ class: 'cm-nonZeroLine' }); // of the timingsField state field. export const updateTimingsEffect = StateEffect.define(); +// Gutter marker for highlighting a specific line. +const highlightedLineGutterMarker = new (class extends GutterMarker { + override elementClass = 'cm-highlightedLine'; +})(); + +// Decoration for highlighting a specific line. +const highlightedLineDecoration = Decoration.line({ + class: 'cm-highlightedLine', +}); + // A "state field" for the timings. const timingsField = StateField.define({ create() { @@ -95,6 +105,31 @@ const nonZeroLineDecorationHighlighter = EditorView.decorations.compute( } ); +// Creates extensions for highlighting a specific line number. +function createHighlightedLineExtension(lineNumber: number | null) { + if (lineNumber === null) { + return []; + } + const gutterHighlighter = gutterLineClass.compute(['doc'], (state) => { + if (lineNumber < 1 || lineNumber > state.doc.lines) { + return RangeSet.empty; + } + const pos = state.doc.line(lineNumber).from; + return RangeSet.of([highlightedLineGutterMarker.range(pos)]); + }); + const decorationHighlighter = EditorView.decorations.compute( + ['doc'], + (state) => { + if (lineNumber < 1 || lineNumber > state.doc.lines) { + return RangeSet.empty; + } + const pos = state.doc.line(lineNumber).from; + return RangeSet.of([highlightedLineDecoration.range(pos)]); + } + ); + return [gutterHighlighter, decorationHighlighter]; +} + // This is a "gutter marker" which renders just a string and nothing else. // It is used for the AddressTimings annotations, i.e. for the numbers in the // gutter. @@ -157,3 +192,5 @@ export const timingsExtension = [ nonZeroLineGutterHighlighter, nonZeroLineDecorationHighlighter, ]; + +export { createHighlightedLineExtension }; From 10bd60e300394fa3f9674a9aa370261afe2f5c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 9 Oct 2025 14:01:05 +0200 Subject: [PATCH 21/61] Disable the 'asm' button in the bottom panel when there is no library information in the profile. --- src/components/app/AssemblyViewToggleButton.tsx | 7 ++++++- src/selectors/code.tsx | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/components/app/AssemblyViewToggleButton.tsx b/src/components/app/AssemblyViewToggleButton.tsx index d65bb7e5bb..dd45b51de7 100644 --- a/src/components/app/AssemblyViewToggleButton.tsx +++ b/src/components/app/AssemblyViewToggleButton.tsx @@ -6,6 +6,7 @@ import React from 'react'; import classNames from 'classnames'; import { getAssemblyViewIsOpen } from 'firefox-profiler/selectors/url-state'; +import { getIsAssemblyViewAvailable } from 'firefox-profiler/selectors/code'; import { openAssemblyView, closeAssemblyView, @@ -18,6 +19,7 @@ import { Localized } from '@fluent/react'; type StateProps = { readonly assemblyViewIsOpen: boolean; + readonly isAssemblyViewAvailable: boolean; }; type DispatchProps = { @@ -37,7 +39,7 @@ class AssemblyViewToggleButtonImpl extends React.PureComponent { }; override render() { - const { assemblyViewIsOpen } = this.props; + const { assemblyViewIsOpen, isAssemblyViewAvailable } = this.props; return assemblyViewIsOpen ? ( @@ -51,6 +53,7 @@ class AssemblyViewToggleButtonImpl extends React.PureComponent { title="Hide the assembly view" type="button" onClick={this._onClick} + disabled={!isAssemblyViewAvailable} /> ) : ( @@ -64,6 +67,7 @@ class AssemblyViewToggleButtonImpl extends React.PureComponent { title="Show the assembly view" type="button" onClick={this._onClick} + disabled={!isAssemblyViewAvailable} /> ); @@ -77,6 +81,7 @@ export const AssemblyViewToggleButton = explicitConnect< >({ mapStateToProps: (state) => ({ assemblyViewIsOpen: getAssemblyViewIsOpen(state), + isAssemblyViewAvailable: getIsAssemblyViewAvailable(state), }), mapDispatchToProps: { openAssemblyView, diff --git a/src/selectors/code.tsx b/src/selectors/code.tsx index 210d102046..adb5a46152 100644 --- a/src/selectors/code.tsx +++ b/src/selectors/code.tsx @@ -35,13 +35,23 @@ const getAssemblyViewNativeSymbolLib: Selector = createSelector( getAssemblyViewNativeSymbol, getProfileOrNull, (nativeSymbol, profile) => { - if (profile === null || nativeSymbol === null) { + if ( + profile === null || + nativeSymbol === null || + profile.libs.length === 0 + ) { return null; } return profile.libs[nativeSymbol.libIndex]; } ); +export const getIsAssemblyViewAvailable: Selector = createSelector( + getAssemblyViewNativeSymbol, + getAssemblyViewNativeSymbolLib, + (nativeSymbol, lib) => nativeSymbol !== null && lib !== null +); + export const getAssemblyViewCode: Selector = createSelector( getAssemblyCodeCache, From c1767445783a3cc394f6e9b38e8acb15e50d41de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 29 Oct 2025 20:08:08 +0100 Subject: [PATCH 22/61] Add fallback to funcTable.lineNumber when computing line timings (#5644) When computing line timings for source view, we now fall back to using funcTable.lineNumber (the function's start line) when frameTable.line (the frame's execution line) is null. This is particularly useful for JS JIT'ed functions where frame line information might be missing. --- src/profile-logic/line-timings.ts | 21 +++++++++- src/selectors/per-thread/index.ts | 1 + src/test/unit/line-timings.test.ts | 64 ++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/profile-logic/line-timings.ts b/src/profile-logic/line-timings.ts index b806654c24..68c0a679b5 100644 --- a/src/profile-logic/line-timings.ts +++ b/src/profile-logic/line-timings.ts @@ -82,6 +82,10 @@ export function getStackLineInfo( if (sourceIndexOfThisStack === sourceViewSourceIndex) { selfLine = frameTable.line[frame]; + // Fallback to func line info if frame line info is not available + if (selfLine === null) { + selfLine = funcTable.lineNumber[func]; + } if (selfLine !== null) { // Add this stack's line to this stack's totalLines. The rest of this stack's // totalLines is the same as for the parent stack. @@ -120,6 +124,7 @@ export function getStackLineInfo( export function getStackLineInfoForCallNode( stackTable: StackTable, frameTable: FrameTable, + funcTable: FuncTable, callNodeIndex: IndexIntoCallNodeTable, callNodeInfo: CallNodeInfo ): StackLineInfo { @@ -128,12 +133,14 @@ export function getStackLineInfoForCallNode( ? getStackLineInfoForCallNodeInverted( stackTable, frameTable, + funcTable, callNodeIndex, callNodeInfoInverted ) : getStackLineInfoForCallNodeNonInverted( stackTable, frameTable, + funcTable, callNodeIndex, callNodeInfo ); @@ -205,6 +212,7 @@ export function getStackLineInfoForCallNode( export function getStackLineInfoForCallNodeNonInverted( stackTable: StackTable, frameTable: FrameTable, + funcTable: FuncTable, callNodeIndex: IndexIntoCallNodeTable, callNodeInfo: CallNodeInfo ): StackLineInfo { @@ -229,6 +237,11 @@ export function getStackLineInfoForCallNodeNonInverted( // the same as the given call node's func and file. const frame = stackTable.frame[stackIndex]; selfLine = frameTable.line[frame]; + // Fallback to func line info if frame line info is not available + if (selfLine === null) { + const func = frameTable.func[frame]; + selfLine = funcTable.lineNumber[func]; + } if (selfLine !== null) { totalLines = new Set([selfLine]); } @@ -280,6 +293,7 @@ export function getStackLineInfoForCallNodeNonInverted( export function getStackLineInfoForCallNodeInverted( stackTable: StackTable, frameTable: FrameTable, + funcTable: FuncTable, callNodeIndex: IndexIntoCallNodeTable, callNodeInfo: CallNodeInfoInverted ): StackLineInfo { @@ -318,7 +332,12 @@ export function getStackLineInfoForCallNodeInverted( // This stack contributes to the call node's total time. // We don't need to check the stack's func or file because it'll be // the same as the given call node's func and file. - const line = frameTable.line[frameForCallNode]; + let line = frameTable.line[frameForCallNode]; + // Fallback to func line info if frame line info is not available + if (line === null) { + const func = frameTable.func[frameForCallNode]; + line = funcTable.lineNumber[func]; + } if (line !== null) { totalLines = new Set([line]); if (callNodeIsRootOfInvertedTree) { diff --git a/src/selectors/per-thread/index.ts b/src/selectors/per-thread/index.ts index 3fe4e3917e..df364eccb4 100644 --- a/src/selectors/per-thread/index.ts +++ b/src/selectors/per-thread/index.ts @@ -294,6 +294,7 @@ export const selectedNodeSelectors: NodeSelectors = (() => { return getStackLineInfoForCallNode( stackTable, frameTable, + funcTable, selectedCallNodeIndex, callNodeInfo ); diff --git a/src/test/unit/line-timings.test.ts b/src/test/unit/line-timings.test.ts index e6d096ea77..2c3f68ca30 100644 --- a/src/test/unit/line-timings.test.ts +++ b/src/test/unit/line-timings.test.ts @@ -112,6 +112,40 @@ describe('getLineTimings for getStackLineInfo', function () { expect(lineTimingsTwo.selfLineHits.get(40)).toBe(1); expect(lineTimingsTwo.selfLineHits.size).toBe(2); // no other hits }); + + it('falls back to funcTable.lineNumber when frameTable.line is null', function () { + // Create a profile with frames that have null line numbers + const { derivedThreads } = getProfileFromTextSamples(` + A[file:file.js][line:20] + B[file:file.js][line:30] + `); + const [thread] = derivedThreads; + const { stackTable, frameTable, funcTable, samples, stringTable } = thread; + + // Manually set frameTable.line to null for the leaf frame + // to simulate a case where frame line info is missing + const leafFrame = stackTable.frame[stackTable.length - 1]; + frameTable.line[leafFrame] = null; + + // Set funcTable.lineNumber to a value for the func of that frame + const func = frameTable.func[leafFrame]; + funcTable.lineNumber[func] = 35; + + const fileStringIndex = stringTable.indexForString('file.js'); + const fileSourceIndex = thread.sources.filename.indexOf(fileStringIndex); + const stackLineInfo = getStackLineInfo( + stackTable, + frameTable, + funcTable, + fileSourceIndex + ); + const lineTimings = getLineTimings(stackLineInfo, samples); + + // The fallback should use funcTable.lineNumber[func] = 35 + expect(lineTimings.selfLineHits.get(35)).toBe(1); + expect(lineTimings.totalLineHits.get(20)).toBe(1); + expect(lineTimings.totalLineHits.get(35)).toBe(1); + }); }); describe('getLineTimings for getStackLineInfoForCallNode', function () { @@ -141,6 +175,7 @@ describe('getLineTimings for getStackLineInfoForCallNode', function () { const stackLineInfo = getStackLineInfoForCallNode( stackTable, frameTable, + funcTable, callNodeIndex, callNodeInfo ); @@ -268,4 +303,33 @@ describe('getLineTimings for getStackLineInfoForCallNode', function () { expect(lineTimingsDBA.totalLineHits.size).toBe(1); // no other hits expect(lineTimingsDC.selfLineHits.size).toBe(0); // no self line hits }); + + it('falls back to funcTable.lineNumber when frameTable.line is null', function () { + const { derivedThreads, funcNamesDictPerThread, defaultCategory } = + getProfileFromTextSamples(` + A[file:file.js][line:20] + B[file:file.js][line:30] + `); + + const [{ A, B }] = funcNamesDictPerThread; + const [thread] = derivedThreads; + const { stackTable, frameTable, funcTable } = thread; + + // Manually set frameTable.line to null for the leaf frame + // to simulate a case where frame line info is missing + const leafFrame = stackTable.frame[stackTable.length - 1]; + frameTable.line[leafFrame] = null; + + // Set funcTable.lineNumber to a value for the func of that frame + const func = frameTable.func[leafFrame]; + funcTable.lineNumber[func] = 35; + + // Compute the line timings for the child call node. + // The fallback should use funcTable.lineNumber[func] = 35 + const lineTimingsChild = getTimings(thread, [A, B], defaultCategory, false); + expect(lineTimingsChild.totalLineHits.get(35)).toBe(1); + expect(lineTimingsChild.totalLineHits.size).toBe(1); // no other hits + expect(lineTimingsChild.selfLineHits.get(35)).toBe(1); + expect(lineTimingsChild.selfLineHits.size).toBe(1); // no other hits + }); }); From 191ff2e78d2d02f0b64d082b2def59fbf8f42226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Wed, 29 Oct 2025 20:40:10 +0100 Subject: [PATCH 23/61] Show the marker keys instead of the labels in marker tooltips when alt is pressed. (#5625) --- src/components/tooltip/Marker.tsx | 14 ++++++- src/hooks/useAltKey.ts | 64 +++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/hooks/useAltKey.ts diff --git a/src/components/tooltip/Marker.tsx b/src/components/tooltip/Marker.tsx index 0955b108e0..6e4f824bb1 100644 --- a/src/components/tooltip/Marker.tsx +++ b/src/components/tooltip/Marker.tsx @@ -10,6 +10,7 @@ import { formatTimestamp, } from 'firefox-profiler/utils/format-numbers'; import explicitConnect from 'firefox-profiler/utils/connect'; +import { useAltKey } from 'firefox-profiler/hooks/useAltKey'; import { getCategories, getMarkerSchemaByName, @@ -88,6 +89,7 @@ type OwnProps = { readonly restrictHeightWidth: boolean; // Optional callback for when a stack frame is clicked in the backtrace. readonly onStackFrameClick?: (stackIndex: IndexIntoStackTable) => void; + readonly showKeys?: boolean; }; type StateProps = { @@ -275,8 +277,10 @@ class MarkerTooltipContents extends React.PureComponent { continue; } + // When Alt is pressed (showKeys is true), display the field key instead of label + const displayLabel = this.props.showKeys ? key : label || key; details.push( - + {formatMarkupFromMarkerSchema( schema.name, format, @@ -554,7 +558,7 @@ class MarkerTooltipContents extends React.PureComponent { } } -export const TooltipMarker = explicitConnect< +const ConnectedMarkerTooltipContents = explicitConnect< OwnProps, StateProps, DispatchProps @@ -579,3 +583,9 @@ export const TooltipMarker = explicitConnect< mapDispatchToProps: { changeMarkersSearchString }, component: MarkerTooltipContents, }); + +// Wrapper component that provides the Alt key state +export function TooltipMarker(props: OwnProps) { + const showKeys = useAltKey(); + return ; +} diff --git a/src/hooks/useAltKey.ts b/src/hooks/useAltKey.ts new file mode 100644 index 0000000000..acde68a190 --- /dev/null +++ b/src/hooks/useAltKey.ts @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react'; + +// Global state for Alt key tracking +let isAltPressed = false; +const listeners = new Set<(pressed: boolean) => void>(); + +// Initialize global event listeners once +if (typeof window !== 'undefined') { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.altKey && !isAltPressed) { + isAltPressed = true; + listeners.forEach((listener) => listener(true)); + } + }; + + const handleKeyUp = (event: KeyboardEvent) => { + if (!event.altKey && isAltPressed) { + isAltPressed = false; + listeners.forEach((listener) => listener(false)); + } + }; + + const handleBlur = () => { + // Reset Alt state when window loses focus + if (isAltPressed) { + isAltPressed = false; + listeners.forEach((listener) => listener(false)); + } + }; + + window.addEventListener('keydown', handleKeyDown); + window.addEventListener('keyup', handleKeyUp); + window.addEventListener('blur', handleBlur); +} + +/** + * Custom hook that tracks whether the Alt key is currently pressed. + * Returns true when Alt is pressed, false otherwise. + * The state is global and shared across all component instances. + */ +export function useAltKey(): boolean { + const [altPressed, setAltPressed] = React.useState(isAltPressed); + + React.useEffect(() => { + // Set initial state + setAltPressed(isAltPressed); + + // Subscribe to changes + const listener = (pressed: boolean) => { + setAltPressed(pressed); + }; + listeners.add(listener); + + return () => { + listeners.delete(listener); + }; + }, []); + + return altPressed; +} From 89a761d93dfbd663f8619e707fdd6adb1d78ce1b Mon Sep 17 00:00:00 2001 From: Pontoon Date: Fri, 31 Oct 2025 13:02:30 +0000 Subject: [PATCH 24/61] Pontoon/Firefox Profiler: Update Greek (el) Co-authored-by: Jim Spentzos (el) --- locales/el/app.ftl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/locales/el/app.ftl b/locales/el/app.ftl index 78a6a1cf4c..cab1c85005 100644 --- a/locales/el/app.ftl +++ b/locales/el/app.ftl @@ -42,6 +42,14 @@ AppViewRouter--error-from-localhost-url-safari = AppViewRouter--route-not-found--home = .specialMessage = Δεν αναγνωρίστηκε το URL που προσπαθήσατε να μεταβείτε. +## Backtrace +## This is used to display a backtrace (call stack) for a marker or sample. + +# Variables: +# $function (String) - Name of the function that was inlined. +Backtrace--inlining-badge = (ενσωματωμένη) + .title = Η συνάρτηση «{ $function }» ενσωματώθηκε στο καλούν στοιχείο από τον μεταγλωττιστή. + ## CallNodeContextMenu ## This is used as a context menu for the Call Tree, Flame Graph and Stack Chart ## panels. @@ -438,6 +446,16 @@ MarkerTable--duration = Διάρκεια MarkerTable--name = Όνομα MarkerTable--details = Λεπτομέρειες +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Εμφάνιση μόνο των αντίστοιχων δεικτών: «{ $filter }» + .aria-label = Εμφάνιση μόνο των αντίστοιχων δεικτών: «{ $filter }» + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From bf4806f01a682b6e36687ed7adf5fdc4069ada8d Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sun, 2 Nov 2025 20:21:49 +0000 Subject: [PATCH 25/61] Pontoon/Firefox Profiler: Update Belarusian (be) Co-authored-by: Mikalai Udodau (be) --- locales/be/app.ftl | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/locales/be/app.ftl b/locales/be/app.ftl index 4b47948d6c..d5700daa2c 100644 --- a/locales/be/app.ftl +++ b/locales/be/app.ftl @@ -42,6 +42,14 @@ AppViewRouter--error-from-localhost-url-safari = AppViewRouter--route-not-found--home = .specialMessage = URL-адрас, да якога вы намагаецеся атрымаць доступ, не распазнаны. +## Backtrace +## This is used to display a backtrace (call stack) for a marker or sample. + +# Variables: +# $function (String) - Name of the function that was inlined. +Backtrace--inlining-badge = (убудаваны) + .title = { $function } была ўбудавана ў месца выкліку кампілятарам. + ## CallNodeContextMenu ## This is used as a context menu for the Call Tree, Flame Graph and Stack Chart ## panels. @@ -421,6 +429,16 @@ MarkerTable--duration = Працягласць MarkerTable--name = Назва MarkerTable--details = Падрабязнасці +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = Паказваць толькі маркёры, якія адпавядаюць: “{ $filter }” + .aria-label = Паказваць толькі маркёры, якія адпавядаюць: “{ $filter }” + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. @@ -1123,6 +1141,13 @@ SourceView--not-in-archive-error-when-obtaining-source = Файл { $pathInArchi # $url (String) - The URL from which the "archive" file was downloaded. # $parsingErrorMessage (String) - The raw internal error message during parsing, not localized SourceView--archive-parsing-error-when-obtaining-source = Не ўдалося прааналізаваць архіў па адрасе { $url }: { $parsingErrorMessage } +# Displayed below SourceView--cannot-obtain-source, if a JS file could not be found in +# the browser. +# Variables: +# $url (String) - The URL of the JS source file. +# $sourceUuid (number) - The UUID of the JS source file. +# $errorMessage (String) - The raw internal error message, not localized +SourceView--not-in-browser-error-when-obtaining-js-source = Браўзеру не ўдалося атрымаць зыходны файл для { $url } з sourceUuid { $sourceUuid }: { $errorMessage }. ## Toggle buttons in the top right corner of the bottom box From 9e4beb7e31e2b461d4a5a168a979c0ee56042c10 Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 13:29:45 +0100 Subject: [PATCH 26/61] Update all Yarn dependencies (2025-11-04) (#5648) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- package.json | 28 +-- yarn.lock | 536 ++++++++++++++++++++++++++------------------------- 2 files changed, 287 insertions(+), 277 deletions(-) diff --git a/package.json b/package.json index d72ca7c14a..d725667c95 100644 --- a/package.json +++ b/package.json @@ -63,12 +63,12 @@ "@codemirror/lang-rust": "^6.0.2", "@codemirror/language": "^6.11.3", "@codemirror/state": "^6.5.2", - "@codemirror/view": "^6.38.4", + "@codemirror/view": "^6.38.6", "@firefox-devtools/react-contextmenu": "^5.2.3", "@fluent/bundle": "^0.19.1", "@fluent/langneg": "^0.7.0", "@fluent/react": "^0.15.2", - "@lezer/highlight": "^1.2.1", + "@lezer/highlight": "^1.2.2", "@tgwf/co2": "^0.16.9", "array-move": "^3.0.1", "array-range": "^1.0.1", @@ -107,13 +107,13 @@ }, "devDependencies": { "@babel/cli": "^7.28.3", - "@babel/core": "^7.28.4", - "@babel/eslint-parser": "^7.28.4", + "@babel/core": "^7.28.5", + "@babel/eslint-parser": "^7.28.5", "@babel/eslint-plugin": "^7.27.1", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/preset-env": "^7.28.3", - "@babel/preset-react": "^7.27.1", - "@babel/preset-typescript": "^7.27.1", + "@babel/preset-env": "^7.28.5", + "@babel/preset-react": "^7.28.5", + "@babel/preset-typescript": "^7.28.5", "@eslint/js": "^9.37.0", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -122,7 +122,7 @@ "@types/common-tags": "^1.8.4", "@types/jest": "^30.0.0", "@types/minimist": "^1.2.5", - "@types/node": "^22.18.12", + "@types/node": "^22.19.0", "@types/query-string": "^6.3.0", "@types/react": "^18.3.26", "@types/react-dom": "^18.3.1", @@ -130,15 +130,15 @@ "@types/react-transition-group": "^4.4.5", "@types/redux-logger": "^3.0.6", "@types/tgwf__co2": "^0.14.2", - "@typescript-eslint/eslint-plugin": "^8.45.0", - "@typescript-eslint/parser": "^8.45.0", + "@typescript-eslint/eslint-plugin": "^8.46.2", + "@typescript-eslint/parser": "^8.46.2", "alex": "^11.0.1", "autoprefixer": "^10.4.21", "babel-jest": "^30.2.0", "babel-loader": "^10.0.0", "babel-plugin-module-resolver": "^5.0.2", - "browserslist": "^4.26.3", - "caniuse-lite": "^1.0.30001743", + "browserslist": "^4.27.0", + "caniuse-lite": "^1.0.30001751", "circular-dependency-plugin": "^5.2.1", "codecov": "^3.8.3", "copy-webpack-plugin": "^13.0.1", @@ -157,7 +157,7 @@ "eslint-plugin-testing-library": "^7.13.3", "espree": "^10.4.0", "fake-indexeddb": "^6.2.4", - "fetch-mock": "^12.5.4", + "fetch-mock": "^12.5.5", "file-loader": "^6.2.0", "glob": "^11.0.3", "globals": "^16.4.0", @@ -184,7 +184,7 @@ "stylelint-config-idiomatic-order": "^10.0.0", "stylelint-config-standard": "^39.0.1", "typescript": "^5.9.3", - "webpack": "^5.102.0", + "webpack": "^5.102.1", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.2", "workbox-webpack-plugin": "^7.3.0", diff --git a/yarn.lock b/yarn.lock index b5c89065d6..3d2ba8f218 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,25 +65,25 @@ js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790" - integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== +"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" + integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== -"@babel/core@^7.23.9", "@babel/core@^7.24.4", "@babel/core@^7.27.4", "@babel/core@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.4.tgz#12a550b8794452df4c8b084f95003bce1742d496" - integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== +"@babel/core@^7.23.9", "@babel/core@^7.24.4", "@babel/core@^7.27.4", "@babel/core@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" + integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" + "@babel/generator" "^7.28.5" "@babel/helper-compilation-targets" "^7.27.2" "@babel/helper-module-transforms" "^7.28.3" "@babel/helpers" "^7.28.4" - "@babel/parser" "^7.28.4" + "@babel/parser" "^7.28.5" "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.4" - "@babel/types" "^7.28.4" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" @@ -91,10 +91,10 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.28.4.tgz#80dd86e0aeaae9704411a044db60e1ae6477d93f" - integrity sha512-Aa+yDiH87980jR6zvRfFuCR1+dLb00vBydhTL+zI992Rz/wQhSvuxjmOOuJOgO3XmakO6RykRGD2S1mq1AtgHA== +"@babel/eslint-parser@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.28.5.tgz#0b8883a4a1c2cbed7b3cd9d7765d80e8f480b9ae" + integrity sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" @@ -107,13 +107,13 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.27.5", "@babel/generator@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e" - integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== +"@babel/generator@^7.27.5", "@babel/generator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" + integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== dependencies: - "@babel/parser" "^7.28.3" - "@babel/types" "^7.28.2" + "@babel/parser" "^7.28.5" + "@babel/types" "^7.28.5" "@jridgewell/gen-mapping" "^0.3.12" "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" @@ -136,17 +136,17 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz#3e747434ea007910c320c4d39a6b46f20f371d46" - integrity sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3", "@babel/helper-create-class-features-plugin@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz#472d0c28028850968979ad89f173594a6995da46" + integrity sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" - "@babel/helper-member-expression-to-functions" "^7.27.1" + "@babel/helper-member-expression-to-functions" "^7.28.5" "@babel/helper-optimise-call-expression" "^7.27.1" "@babel/helper-replace-supers" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - "@babel/traverse" "^7.28.3" + "@babel/traverse" "^7.28.5" semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1": @@ -174,13 +174,13 @@ resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== -"@babel/helper-member-expression-to-functions@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz#ea1211276be93e798ce19037da6f06fbb994fa44" - integrity sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA== +"@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" + integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.27.1": version "7.27.1" @@ -242,10 +242,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" - integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== +"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== "@babel/helper-validator-option@^7.27.1": version "7.27.1" @@ -269,20 +269,20 @@ "@babel/template" "^7.27.2" "@babel/types" "^7.28.4" -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3", "@babel/parser@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.4.tgz#da25d4643532890932cc03f7705fe19637e03fa8" - integrity sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg== +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" + integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== dependencies: - "@babel/types" "^7.28.4" + "@babel/types" "^7.28.5" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9" - integrity sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" + integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/traverse" "^7.28.5" "@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": version "7.27.1" @@ -494,10 +494,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-block-scoping@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz#e7c50cbacc18034f210b93defa89638666099451" - integrity sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q== +"@babel/plugin-transform-block-scoping@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6" + integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -517,17 +517,17 @@ "@babel/helper-create-class-features-plugin" "^7.28.3" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-classes@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.3.tgz#598297260343d0edbd51cb5f5075e07dee91963a" - integrity sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg== +"@babel/plugin-transform-classes@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" + integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" "@babel/helper-compilation-targets" "^7.27.2" "@babel/helper-globals" "^7.28.0" "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-replace-supers" "^7.27.1" - "@babel/traverse" "^7.28.3" + "@babel/traverse" "^7.28.4" "@babel/plugin-transform-computed-properties@^7.27.1": version "7.27.1" @@ -537,13 +537,13 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/template" "^7.27.1" -"@babel/plugin-transform-destructuring@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz#0f156588f69c596089b7d5b06f5af83d9aa7f97a" - integrity sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A== +"@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" + integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.28.0" + "@babel/traverse" "^7.28.5" "@babel/plugin-transform-dotall-regex@^7.27.1": version "7.27.1" @@ -583,10 +583,10 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-destructuring" "^7.28.0" -"@babel/plugin-transform-exponentiation-operator@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz#fc497b12d8277e559747f5a3ed868dd8064f83e1" - integrity sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ== +"@babel/plugin-transform-exponentiation-operator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe" + integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -628,10 +628,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-logical-assignment-operators@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz#890cb20e0270e0e5bebe3f025b434841c32d5baa" - integrity sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw== +"@babel/plugin-transform-logical-assignment-operators@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" + integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -658,15 +658,15 @@ "@babel/helper-module-transforms" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-systemjs@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz#00e05b61863070d0f3292a00126c16c0e024c4ed" - integrity sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA== +"@babel/plugin-transform-modules-systemjs@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" + integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== dependencies: - "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-module-transforms" "^7.28.3" "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.5" "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" @@ -705,16 +705,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-rest-spread@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz#d23021857ffd7cd809f54d624299b8086402ed8d" - integrity sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA== +"@babel/plugin-transform-object-rest-spread@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" + integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== dependencies: "@babel/helper-compilation-targets" "^7.27.2" "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-destructuring" "^7.28.0" "@babel/plugin-transform-parameters" "^7.27.7" - "@babel/traverse" "^7.28.0" + "@babel/traverse" "^7.28.4" "@babel/plugin-transform-object-super@^7.27.1": version "7.27.1" @@ -731,10 +731,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-optional-chaining@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz#874ce3c4f06b7780592e946026eb76a32830454f" - integrity sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg== +"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" + integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" @@ -770,10 +770,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-react-display-name@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.27.1.tgz#43af31362d71f7848cfac0cbc212882b1a16e80f" - integrity sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ== +"@babel/plugin-transform-react-display-name@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" + integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -803,10 +803,10 @@ "@babel/helper-annotate-as-pure" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-regenerator@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.3.tgz#b8eee0f8aed37704bbcc932fd0b1a0a34d0b7344" - integrity sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A== +"@babel/plugin-transform-regenerator@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51" + integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -861,13 +861,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-typescript@^7.27.1": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz#796cbd249ab56c18168b49e3e1d341b72af04a6b" - integrity sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg== +"@babel/plugin-transform-typescript@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" + integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" - "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-create-class-features-plugin" "^7.28.5" "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" "@babel/plugin-syntax-typescript" "^7.27.1" @@ -903,16 +903,16 @@ "@babel/helper-create-regexp-features-plugin" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.3.tgz#2b18d9aff9e69643789057ae4b942b1654f88187" - integrity sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg== +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0" + integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg== dependencies: - "@babel/compat-data" "^7.28.0" + "@babel/compat-data" "^7.28.5" "@babel/helper-compilation-targets" "^7.27.2" "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-validator-option" "^7.27.1" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5" "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1" @@ -925,42 +925,42 @@ "@babel/plugin-transform-async-generator-functions" "^7.28.0" "@babel/plugin-transform-async-to-generator" "^7.27.1" "@babel/plugin-transform-block-scoped-functions" "^7.27.1" - "@babel/plugin-transform-block-scoping" "^7.28.0" + "@babel/plugin-transform-block-scoping" "^7.28.5" "@babel/plugin-transform-class-properties" "^7.27.1" "@babel/plugin-transform-class-static-block" "^7.28.3" - "@babel/plugin-transform-classes" "^7.28.3" + "@babel/plugin-transform-classes" "^7.28.4" "@babel/plugin-transform-computed-properties" "^7.27.1" - "@babel/plugin-transform-destructuring" "^7.28.0" + "@babel/plugin-transform-destructuring" "^7.28.5" "@babel/plugin-transform-dotall-regex" "^7.27.1" "@babel/plugin-transform-duplicate-keys" "^7.27.1" "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1" "@babel/plugin-transform-dynamic-import" "^7.27.1" "@babel/plugin-transform-explicit-resource-management" "^7.28.0" - "@babel/plugin-transform-exponentiation-operator" "^7.27.1" + "@babel/plugin-transform-exponentiation-operator" "^7.28.5" "@babel/plugin-transform-export-namespace-from" "^7.27.1" "@babel/plugin-transform-for-of" "^7.27.1" "@babel/plugin-transform-function-name" "^7.27.1" "@babel/plugin-transform-json-strings" "^7.27.1" "@babel/plugin-transform-literals" "^7.27.1" - "@babel/plugin-transform-logical-assignment-operators" "^7.27.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.28.5" "@babel/plugin-transform-member-expression-literals" "^7.27.1" "@babel/plugin-transform-modules-amd" "^7.27.1" "@babel/plugin-transform-modules-commonjs" "^7.27.1" - "@babel/plugin-transform-modules-systemjs" "^7.27.1" + "@babel/plugin-transform-modules-systemjs" "^7.28.5" "@babel/plugin-transform-modules-umd" "^7.27.1" "@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1" "@babel/plugin-transform-new-target" "^7.27.1" "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1" "@babel/plugin-transform-numeric-separator" "^7.27.1" - "@babel/plugin-transform-object-rest-spread" "^7.28.0" + "@babel/plugin-transform-object-rest-spread" "^7.28.4" "@babel/plugin-transform-object-super" "^7.27.1" "@babel/plugin-transform-optional-catch-binding" "^7.27.1" - "@babel/plugin-transform-optional-chaining" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.28.5" "@babel/plugin-transform-parameters" "^7.27.7" "@babel/plugin-transform-private-methods" "^7.27.1" "@babel/plugin-transform-private-property-in-object" "^7.27.1" "@babel/plugin-transform-property-literals" "^7.27.1" - "@babel/plugin-transform-regenerator" "^7.28.3" + "@babel/plugin-transform-regenerator" "^7.28.4" "@babel/plugin-transform-regexp-modifiers" "^7.27.1" "@babel/plugin-transform-reserved-words" "^7.27.1" "@babel/plugin-transform-shorthand-properties" "^7.27.1" @@ -988,28 +988,28 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.27.1.tgz#86ea0a5ca3984663f744be2fd26cb6747c3fd0ec" - integrity sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA== +"@babel/preset-react@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.28.5.tgz#6fcc0400fa79698433d653092c3919bb4b0878d9" + integrity sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-validator-option" "^7.27.1" - "@babel/plugin-transform-react-display-name" "^7.27.1" + "@babel/plugin-transform-react-display-name" "^7.28.0" "@babel/plugin-transform-react-jsx" "^7.27.1" "@babel/plugin-transform-react-jsx-development" "^7.27.1" "@babel/plugin-transform-react-pure-annotations" "^7.27.1" -"@babel/preset-typescript@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz#190742a6428d282306648a55b0529b561484f912" - integrity sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ== +"@babel/preset-typescript@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-validator-option" "^7.27.1" "@babel/plugin-syntax-jsx" "^7.27.1" "@babel/plugin-transform-modules-commonjs" "^7.27.1" - "@babel/plugin-transform-typescript" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.28.5" "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": version "7.26.10" @@ -1027,26 +1027,26 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.4.tgz#8d456101b96ab175d487249f60680221692b958b" - integrity sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ== +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" + integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" + "@babel/generator" "^7.28.5" "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.4" + "@babel/parser" "^7.28.5" "@babel/template" "^7.27.2" - "@babel/types" "^7.28.4" + "@babel/types" "^7.28.5" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.3.0", "@babel/types@^7.4.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.4.tgz#0a4e618f4c60a7cd6c11cb2d48060e4dbe38ac3a" - integrity sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.3.0", "@babel/types@^7.4.4": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" + integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== dependencies: "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" @@ -1120,10 +1120,10 @@ dependencies: "@marijn/find-cluster-break" "^1.0.0" -"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.38.4": - version "6.38.4" - resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.38.4.tgz#1ce72056fa8bdde99c1513fead6951167897d6e5" - integrity sha512-hduz0suCcUSC/kM8Fq3A9iLwInJDl8fD1xLpTIk+5xkNm8z/FT7UsIa9sOXrkpChh+XXc18RzswE8QqELsVl+g== +"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.38.6": + version "6.38.6" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.38.6.tgz#25d9df071393801196c311025d2caa7a5523c26c" + integrity sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw== dependencies: "@codemirror/state" "^6.5.0" crelt "^1.0.6" @@ -1670,10 +1670,10 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@lezer/common@^1.0.0", "@lezer/common@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.1.0.tgz#2e5bfe01d7a2ada6056d93c677bba4f1495e098a" - integrity sha512-XPIN3cYDXsoJI/oDWoR2tD++juVrhgIago9xyKhZ7IhGlzdDM9QgC8D8saKNCz5pindGcznFr2HBSsEQSWnSjw== +"@lezer/common@^1.0.0", "@lezer/common@^1.1.0", "@lezer/common@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.3.0.tgz#123427ec4c53c2c8367415b4441e555b4f85c696" + integrity sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ== "@lezer/cpp@^1.0.0": version "1.0.0" @@ -1683,12 +1683,12 @@ "@lezer/highlight" "^1.0.0" "@lezer/lr" "^1.0.0" -"@lezer/highlight@^1.0.0", "@lezer/highlight@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.1.tgz#596fa8f9aeb58a608be0a563e960c373cbf23f8b" - integrity sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA== +"@lezer/highlight@^1.0.0", "@lezer/highlight@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.2.tgz#f0fcfaf0e87fd1037930964ad62b8dee45d66e97" + integrity sha512-z8TQwaBXXQIvG6i2g3e9cgMwUUXu9Ib7jo2qRRggdhwKpM56Dw3PM3wmexn+EGaaOZ7az0K7sjc3/gcGW7sz7A== dependencies: - "@lezer/common" "^1.0.0" + "@lezer/common" "^1.3.0" "@lezer/javascript@^1.0.0": version "1.0.0" @@ -2318,10 +2318,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.18.12": - version "22.18.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.18.12.tgz#e165d87bc25d7bf6d3657035c914db7485de84fb" - integrity sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog== +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.19.0": + version "22.19.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.0.tgz#849606ef3920850583a4e7ee0930987c35ad80be" + integrity sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA== dependencies: undici-types "~6.21.0" @@ -2494,79 +2494,89 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz#9f251d4e85ec5089e7cccb09257ce93dbf0d7744" - integrity sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg== +"@typescript-eslint/eslint-plugin@^8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz#dc4ab93ee3d7e6c8e38820a0d6c7c93c7183e2dc" + integrity sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.45.0" - "@typescript-eslint/type-utils" "8.45.0" - "@typescript-eslint/utils" "8.45.0" - "@typescript-eslint/visitor-keys" "8.45.0" + "@typescript-eslint/scope-manager" "8.46.2" + "@typescript-eslint/type-utils" "8.46.2" + "@typescript-eslint/utils" "8.46.2" + "@typescript-eslint/visitor-keys" "8.46.2" graphemer "^1.4.0" ignore "^7.0.0" natural-compare "^1.4.0" ts-api-utils "^2.1.0" -"@typescript-eslint/parser@^8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.45.0.tgz#571660c98824aefb4a6ec3b3766655d1348520a4" - integrity sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ== +"@typescript-eslint/parser@^8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.46.2.tgz#dd938d45d581ac8ffa9d8a418a50282b306f7ebf" + integrity sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g== dependencies: - "@typescript-eslint/scope-manager" "8.45.0" - "@typescript-eslint/types" "8.45.0" - "@typescript-eslint/typescript-estree" "8.45.0" - "@typescript-eslint/visitor-keys" "8.45.0" + "@typescript-eslint/scope-manager" "8.46.2" + "@typescript-eslint/types" "8.46.2" + "@typescript-eslint/typescript-estree" "8.46.2" + "@typescript-eslint/visitor-keys" "8.46.2" debug "^4.3.4" -"@typescript-eslint/project-service@8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.45.0.tgz#f83dda1bca31dae2fd6821f9131daf1edebfd46c" - integrity sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg== +"@typescript-eslint/project-service@8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.46.2.tgz#ab2f02a0de4da6a7eeb885af5e059be57819d608" + integrity sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.45.0" - "@typescript-eslint/types" "^8.45.0" + "@typescript-eslint/tsconfig-utils" "^8.46.2" + "@typescript-eslint/types" "^8.46.2" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.45.0", "@typescript-eslint/scope-manager@^8.15.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz#59615ba506a9e3479d1efb0d09d6ab52f2a19142" - integrity sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA== +"@typescript-eslint/scope-manager@8.46.2", "@typescript-eslint/scope-manager@^8.15.0": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz#7d37df2493c404450589acb3b5d0c69cc0670a88" + integrity sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA== dependencies: - "@typescript-eslint/types" "8.45.0" - "@typescript-eslint/visitor-keys" "8.45.0" + "@typescript-eslint/types" "8.46.2" + "@typescript-eslint/visitor-keys" "8.46.2" -"@typescript-eslint/tsconfig-utils@8.45.0", "@typescript-eslint/tsconfig-utils@^8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz#63d38282790a2566c571bad423e7c1cad1f3d64c" - integrity sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w== +"@typescript-eslint/tsconfig-utils@8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz#d110451cb93bbd189865206ea37ef677c196828c" + integrity sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag== -"@typescript-eslint/type-utils@8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz#04004bdf2598844faa29fb936fb6b0ee10d6d3f3" - integrity sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A== +"@typescript-eslint/tsconfig-utils@^8.46.2": + version "8.46.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz#cad33398c762c97fe56a8defda00c16505abefa3" + integrity sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA== + +"@typescript-eslint/type-utils@8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz#802d027864e6fb752e65425ed09f3e089fb4d384" + integrity sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA== dependencies: - "@typescript-eslint/types" "8.45.0" - "@typescript-eslint/typescript-estree" "8.45.0" - "@typescript-eslint/utils" "8.45.0" + "@typescript-eslint/types" "8.46.2" + "@typescript-eslint/typescript-estree" "8.46.2" + "@typescript-eslint/utils" "8.46.2" debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@8.45.0", "@typescript-eslint/types@^8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.45.0.tgz#fc01cd2a4690b9713b02f895e82fb43f7d960684" - integrity sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA== - -"@typescript-eslint/typescript-estree@8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz#3498500f109a89b104d2770497c707e56dfe062d" - integrity sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA== - dependencies: - "@typescript-eslint/project-service" "8.45.0" - "@typescript-eslint/tsconfig-utils" "8.45.0" - "@typescript-eslint/types" "8.45.0" - "@typescript-eslint/visitor-keys" "8.45.0" +"@typescript-eslint/types@8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.46.2.tgz#2bad7348511b31e6e42579820e62b73145635763" + integrity sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ== + +"@typescript-eslint/types@^8.46.2": + version "8.46.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.46.3.tgz#da05ea40e91359b4275dbb3a489f2f7907a02245" + integrity sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA== + +"@typescript-eslint/typescript-estree@8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz#ab547a27e4222bb6a3281cb7e98705272e2c7d08" + integrity sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ== + dependencies: + "@typescript-eslint/project-service" "8.46.2" + "@typescript-eslint/tsconfig-utils" "8.46.2" + "@typescript-eslint/types" "8.46.2" + "@typescript-eslint/visitor-keys" "8.46.2" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -2574,22 +2584,22 @@ semver "^7.6.0" ts-api-utils "^2.1.0" -"@typescript-eslint/utils@8.45.0", "@typescript-eslint/utils@^8.0.0", "@typescript-eslint/utils@^8.15.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.45.0.tgz#6e68e92d99019fdf56018d0e6664c76a70470c95" - integrity sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg== +"@typescript-eslint/utils@8.46.2", "@typescript-eslint/utils@^8.0.0", "@typescript-eslint/utils@^8.15.0": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.46.2.tgz#b313d33d67f9918583af205bd7bcebf20f231732" + integrity sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg== dependencies: "@eslint-community/eslint-utils" "^4.7.0" - "@typescript-eslint/scope-manager" "8.45.0" - "@typescript-eslint/types" "8.45.0" - "@typescript-eslint/typescript-estree" "8.45.0" + "@typescript-eslint/scope-manager" "8.46.2" + "@typescript-eslint/types" "8.46.2" + "@typescript-eslint/typescript-estree" "8.46.2" -"@typescript-eslint/visitor-keys@8.45.0": - version "8.45.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz#4e3bcc55da64ac61069ebfe62ca240567ac7d784" - integrity sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag== +"@typescript-eslint/visitor-keys@8.46.2": + version "8.46.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz#803fa298948c39acf810af21bdce6f8babfa9738" + integrity sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w== dependencies: - "@typescript-eslint/types" "8.45.0" + "@typescript-eslint/types" "8.46.2" eslint-visitor-keys "^4.2.1" "@ungap/structured-clone@^1.3.0": @@ -3356,10 +3366,10 @@ balanced-match@^2.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9" integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA== -baseline-browser-mapping@^2.8.9: - version "2.8.16" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz#e17789673e7f4b7654f81ab2ef25e96ab6a895f9" - integrity sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw== +baseline-browser-mapping@^2.8.19: + version "2.8.23" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz#cd43e17eff5cbfb67c92153e7fe856cf6d426421" + integrity sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ== basic-auth@^2.0.1, basic-auth@~2.0.1: version "2.0.1" @@ -3450,16 +3460,16 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.24.5, browserslist@^4.25.1, browserslist@^4.26.3: - version "4.26.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.26.3.tgz#40fbfe2d1cd420281ce5b1caa8840049c79afb56" - integrity sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w== +browserslist@^4.0.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.24.5, browserslist@^4.25.1, browserslist@^4.26.3, browserslist@^4.27.0: + version "4.27.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.27.0.tgz#755654744feae978fbb123718b2f139bc0fa6697" + integrity sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw== dependencies: - baseline-browser-mapping "^2.8.9" - caniuse-lite "^1.0.30001746" - electron-to-chromium "^1.5.227" - node-releases "^2.0.21" - update-browserslist-db "^1.1.3" + baseline-browser-mapping "^2.8.19" + caniuse-lite "^1.0.30001751" + electron-to-chromium "^1.5.238" + node-releases "^2.0.26" + update-browserslist-db "^1.1.4" bser@2.1.1: version "2.1.1" @@ -3631,10 +3641,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001743, caniuse-lite@^1.0.30001746: - version "1.0.30001750" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001750.tgz#c229f82930033abd1502c6f73035356cf528bfbc" - integrity sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001751: + version "1.0.30001751" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz#dacd5d9f4baeea841641640139d2b2a4df4226ad" + integrity sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw== ccount@^2.0.0: version "2.0.1" @@ -4657,10 +4667,10 @@ ejs@^3.1.6: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.227: - version "1.5.237" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.237.tgz#eacf61cef3f6345d0069ab427585c5a04d7084f0" - integrity sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg== +electron-to-chromium@^1.5.238: + version "1.5.244" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz#b9b61e3d24ef4203489951468614f2a360763820" + integrity sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw== emittery@^0.13.1: version "0.13.1" @@ -5338,10 +5348,10 @@ fdir@^6.4.3: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== -fetch-mock@^12.5.4: - version "12.5.4" - resolved "https://registry.yarnpkg.com/fetch-mock/-/fetch-mock-12.5.4.tgz#1d14f46667d4b81053484a20f3e3b84aea34292c" - integrity sha512-zeECXue5losbXbbnHYzLDl0ZKLnuyRmLZ3auSJISoCnKiOGXNJA6nRiRa4qxI9pyQqeTgHL5d0Ryz+3CUliLOw== +fetch-mock@^12.5.5: + version "12.5.5" + resolved "https://registry.yarnpkg.com/fetch-mock/-/fetch-mock-12.5.5.tgz#8c43bccf4b2ad08ae5cefc69e96964758369737f" + integrity sha512-yeziyj/AsbpaQJ91Z+FvQW3h02JK4VS5FHDCz+xiihgMUsXIuhgg/XjC9UEPNtOruucfTSR2uQWcjevDmSXSUQ== dependencies: "@types/glob-to-regexp" "^0.4.4" dequal "^2.0.3" @@ -9018,10 +9028,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -node-releases@^2.0.21: - version "2.0.21" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c" - integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw== +node-releases@^2.0.26: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== nopt@^2.2.0: version "2.2.1" @@ -10812,10 +10822,10 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" - integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== +schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== dependencies: "@types/json-schema" "^7.0.9" ajv "^8.9.0" @@ -11686,7 +11696,7 @@ table@^6.9.0: string-width "^4.2.3" strip-ansi "^6.0.1" -tapable@^2.0.0, tapable@^2.2.0, tapable@^2.2.3: +tapable@^2.0.0, tapable@^2.2.0, tapable@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== @@ -12271,10 +12281,10 @@ upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== +update-browserslist-db@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz#7802aa2ae91477f255b86e0e46dbc787a206ad4a" + integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -12600,10 +12610,10 @@ webpack-sources@^3.3.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== -webpack@^5.102.0: - version "5.102.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.102.0.tgz#7a2416e6da356c35f1fb35333d2f5cee0133e953" - integrity sha512-hUtqAR3ZLVEYDEABdBioQCIqSoguHbFn1K7WlPPWSuXmx0031BD73PSE35jKyftdSh4YLDoQNgK4pqBt5Q82MA== +webpack@^5.102.1: + version "5.102.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.102.1.tgz#1003a3024741a96ba99c37431938bf61aad3d988" + integrity sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ== dependencies: "@types/eslint-scope" "^3.7.7" "@types/estree" "^1.0.8" @@ -12613,7 +12623,7 @@ webpack@^5.102.0: "@webassemblyjs/wasm-parser" "^1.14.1" acorn "^8.15.0" acorn-import-phases "^1.0.3" - browserslist "^4.24.5" + browserslist "^4.26.3" chrome-trace-event "^1.0.2" enhanced-resolve "^5.17.3" es-module-lexer "^1.2.1" @@ -12625,8 +12635,8 @@ webpack@^5.102.0: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^4.3.2" - tapable "^2.2.3" + schema-utils "^4.3.3" + tapable "^2.3.0" terser-webpack-plugin "^5.3.11" watchpack "^2.4.4" webpack-sources "^3.3.3" From d44234898e7dce738f70e1337ffb2784f99011d4 Mon Sep 17 00:00:00 2001 From: Francesco Lodolo Date: Tue, 4 Nov 2025 15:44:41 +0100 Subject: [PATCH 27/61] Add GitHub workflow to check Fluent reference files (#5647) * Add workflow with Fluent linter * Fix linter error in CircleCI * Fix path to workflow in paths * Use explicit requirements.txt file See https://github.com/actions/setup-python/issues/807 The alternative (creating an empty file) seems worse than using an actual requirements file. * Reorganize files, address review comments * Fix pip cache --- .github/fluent/linter_config.yml | 24 ++++++++++++++++++++ .github/fluent/requirements.txt | 1 + .github/workflows/fluent_linter.yml | 35 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 .github/fluent/linter_config.yml create mode 100644 .github/fluent/requirements.txt create mode 100644 .github/workflows/fluent_linter.yml diff --git a/.github/fluent/linter_config.yml b/.github/fluent/linter_config.yml new file mode 100644 index 0000000000..6ef41ea839 --- /dev/null +++ b/.github/fluent/linter_config.yml @@ -0,0 +1,24 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# See https://github.com/mozilla-l10n/moz-fluent-linter/blob/main/src/fluent_linter/config.yml +# for details + +--- +# Check brand names +CO01: + enabled: true + brands: + - Firefox + - Mozilla + - Profiler + exclusions: + files: [] + messages: [] +# Enforce variable comments +VC: + disabled: false +# Enforce placeholder style, e.g. { $variable } +PS01: + disabled: false diff --git a/.github/fluent/requirements.txt b/.github/fluent/requirements.txt new file mode 100644 index 0000000000..4b9da3204d --- /dev/null +++ b/.github/fluent/requirements.txt @@ -0,0 +1 @@ +moz-fluent-linter~=0.4.9 diff --git a/.github/workflows/fluent_linter.yml b/.github/workflows/fluent_linter.yml new file mode 100644 index 0000000000..664221d1bb --- /dev/null +++ b/.github/workflows/fluent_linter.yml @@ -0,0 +1,35 @@ +name: Lint Reference Files +on: + push: + paths: + - 'locales/en-US/*.ftl' + - '.github/workflows/fluent_linter.yml' + - '.github/fluent/*' + branches: + - main + pull_request: + paths: + - 'locales/en-US/*.ftl' + - '.github/workflows/fluent_linter.yml' + - '.github/fluent/*' + branches: + - main + workflow_dispatch: +jobs: + linter: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v5 + - name: Set up Python 3 + uses: actions/setup-python@v6 + with: + python-version: '3.11' + cache: 'pip' + cache-dependency-path: '.github/fluent/requirements.txt' + - name: Install Python dependencies + run: | + pip install -r .github/fluent/requirements.txt + - name: Lint reference + run: | + moz-fluent-lint ./locales/en-US --config .github/fluent/linter_config.yml From 8322a34f3cf2b559a7b49b3c9c5792df1bcdcbaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 5 Nov 2025 12:18:10 +0100 Subject: [PATCH 28/61] Switch from Gitpod to GitHub Codespaces --- .devcontainer/devcontainer.json | 31 ++++++++++++++++ .gitpod.yml | 8 ----- CONTRIBUTING.md | 8 ++--- README.md | 22 ++++++------ docs-developer/codespaces.md | 64 +++++++++++++++++++++++++++++++++ docs-user/gitpod.md | 34 ------------------ res/photon/server.js | 2 +- server.js | 2 +- 8 files changed, 110 insertions(+), 61 deletions(-) create mode 100644 .devcontainer/devcontainer.json delete mode 100644 .gitpod.yml create mode 100644 docs-developer/codespaces.md delete mode 100644 docs-user/gitpod.md diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..5257f37474 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,31 @@ +{ + "name": "Firefox Profiler", + "image": "mcr.microsoft.com/devcontainers/javascript-node:22", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "22" + } + }, + "forwardPorts": [4242], + "portsAttributes": { + "4242": { + "label": "Firefox Profiler", + "onAutoForward": "openBrowser" + } + }, + "postCreateCommand": "yarn install", + "postStartCommand": "FX_PROFILER_HOST=\"0.0.0.0\" yarn start", + "customizations": { + "vscode": { + "extensions": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "stylelint.vscode-stylelint" + ], + "settings": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" + } + } + } +} diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 732a10cc35..0000000000 --- a/.gitpod.yml +++ /dev/null @@ -1,8 +0,0 @@ -ports: - - port: 4242 -tasks: - - before: nvm install 22 - init: yarn install - command: FX_PROFILER_HOST="0.0.0.0" yarn start - - openMode: split-right - command: printf "\nFirefox Profiler ❤ Gitpod\nWelcome to this virtual environment.\nYou can type your commands in this terminal.\n\n" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4f2fadf68..afcf18d677 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,13 +52,11 @@ module.exports = function (config, serverConfig) { This project uses [TypeScript](https://www.typescriptlang.org/). -## Using Gitpod +## Using GitHub Codespaces -Alternatively, you can also develop the Firefox Profiler online in a pre-configured development environment: +Alternatively, you can also develop the Firefox Profiler online in a pre-configured development environment using [GitHub Codespaces](https://github.com/features/codespaces). -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/firefox-devtools/profiler) - -Gitpod will automatically install all dependencies; start the webpack server for you; and open the web app in a new browser tab. Please look at our [gitpod documentation](./docs-user/gitpod.md) for more information. +GitHub Codespaces will automatically install all dependencies, start the webpack server for you, and forward port 4242 so you can access the web app. Please look at our [GitHub Codespaces documentation](./docs-developer/codespaces.md) for more information. ## Loading in profiles for development diff --git a/README.md b/README.md index 8aabced865..32898ce4b8 100644 --- a/README.md +++ b/README.md @@ -43,22 +43,20 @@ yarn start This project uses [TypeScript](https://www.typescriptlang.org/). -You can also develop the Firefox Profiler online in a pre-configured development environment. +You can also develop the Firefox Profiler online in a pre-configured development environment using [GitHub Codespaces](https://github.com/features/codespaces). -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/firefox-devtools/profiler) - -Please look at our [gitpod documentation](./docs-user/gitpod.md) for more information. +Please look at our [GitHub Codespaces documentation](./docs-developer/codespaces.md) for more information. For more detailed information on getting started contributing. We have plenty of docs available to get you started. -| | | -| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -| [Contributing](./CONTRIBUTING.md) | Find out in detail how to get started and get your local development environment configured. | -| [Code of Conduct](./CODE_OF_CONDUCT.md) | We want to create an open and inclusive community, we have a few guidelines to help us out. | -| [Developer Documentation](./docs-developer) | Want to know how this whole thing works? Get started here. | -| [Source Files](./src) | Dive into the inner workings of the code. Most folders have a `README.md` providing more information. | -| [End-User Documentation](https://profiler.firefox.com/docs/#/) | These docs are customized for actual users of the profiler, not just folks contributing. | -| [Gitpod documentatation](./docs-user/gitpod.md) | Start here if you want to set up a work space on gitpod. | +| | | +| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| [Contributing](./CONTRIBUTING.md) | Find out in detail how to get started and get your local development environment configured. | +| [Code of Conduct](./CODE_OF_CONDUCT.md) | We want to create an open and inclusive community, we have a few guidelines to help us out. | +| [Developer Documentation](./docs-developer) | Want to know how this whole thing works? Get started here. | +| [Source Files](./src) | Dive into the inner workings of the code. Most folders have a `README.md` providing more information. | +| [End-User Documentation](https://profiler.firefox.com/docs/#/) | These docs are customized for actual users of the profiler, not just folks contributing. | +| [GitHub Codespaces documentation](./docs-developer/codespaces.md) | Start here if you want to set up a workspace on GitHub Codespaces. | ### Discussion diff --git a/docs-developer/codespaces.md b/docs-developer/codespaces.md new file mode 100644 index 0000000000..79d87c4159 --- /dev/null +++ b/docs-developer/codespaces.md @@ -0,0 +1,64 @@ +# Setting up profiler on GitHub Codespaces + +Instead of configuring a local setup, you can also use [GitHub Codespaces](https://github.com/features/codespaces), a cloud-based development environment with minimal setup. + +## Getting Started + +You can create a new Codespace directly from the repository: + +1. Navigate to the [Firefox Profiler repository](https://github.com/firefox-devtools/profiler) +2. Click the green `Code` button +3. Click on the `Codespaces` tab +4. Click `Create codespace on main` (or on your branch) + +GitHub will automatically: + +- Create a new development environment +- Install all dependencies using `yarn install` +- Start the development server on port 4242 + +## Open the profiler UI in your web browser + +Once the Codespace is ready, GitHub will automatically forward port 4242. You'll see a notification that a service is available on this port. + +- Click `Open in Browser` to open the profiler UI in a new tab +- Alternatively, you can access forwarded ports from the `PORTS` tab at the bottom of the VS Code interface + +## Load custom profiles + +If you want to load profiles for development, you can follow the steps described in [Loading in profiles for development](../CONTRIBUTING.md#loading-in-profiles-for-development) section. + +## Advanced usage + +### Opening a specific branch or pull request + +You can create a Codespace for any branch or pull request: + +1. Navigate to the branch or pull request you want to work on +2. Click the `Code` button +3. Select the `Codespaces` tab +4. Click `Create codespace on [branch-name]` + +### Using the GitHub CLI + +You can also create and manage Codespaces using the [GitHub CLI](https://cli.github.com/): + +```bash +# Create a new codespace +gh codespace create --repo firefox-devtools/profiler + +# List your codespaces +gh codespace list + +# Connect to a codespace +gh codespace code +``` + +### Configuration + +The Codespace is configured using the `.devcontainer/devcontainer.json` file in the repository. This includes: + +- Node.js environment +- Automatic port forwarding for port 4242 +- Pre-installed VS Code extensions (ESLint, Prettier, Stylelint) +- Automatic dependency installation and server startup diff --git a/docs-user/gitpod.md b/docs-user/gitpod.md deleted file mode 100644 index a4ffb9fcd6..0000000000 --- a/docs-user/gitpod.md +++ /dev/null @@ -1,34 +0,0 @@ -# Setting up profiler on gitpod - -Instead of configuring a local setup, you can also use [gitpod](https://www.gitpod.io/), an online continuous development environment with minimum setup. -Click the link below. An automatic workspace will be created. - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/firefox-devtools/profiler) - -## Authorize with github - -If you are using gitpod for the first time, you will have to authorize access to your GitHub account.This is necessary so you can access your data from within Gitpod. - -To authorize access, click your avatar/profile picture at the top right hand section of the setup. A dropdown menu will be displayed. In the dropdown menu, click `Open Access Control`. It will open Access Control page from where you can check the checkboxes and click update. - -## Open the profiler UI in your web browser - -A popup box, `Open Ports View`, also appears at the bottom right hand section of the setup with the message `A service is available on port 4242`. You can click `Open Browser` which will open profiler UI, [profiler.firefox.com](https://profiler.firefox.com/), for your setup in a separate tab. If you have closed `Open Ports View`, you can display it by clicking `PORTS` at the right hand section of the bottom bar. - -## Load custom profiles - -If you want to load profiles for development, you can follow the steps described in [Loading in profiles for development](../CONTRIBUTING.md#loading-in-profiles-for-development) section. - -## Advanced usage - -As an alternative to following the link above, you can also login using your gitHub account and then follow the sets below. - -- Change the URL of your browser to the respository, pull request or issue you want to open on gitpod e.g. for the [profiler project](https://github.com/firefox-devtools/profiler), URL of the upstream repository is `https://github.com/firefox-devtools/profiler`. You can also use the forked repository if you wish to start contributing to the project. -- Prefix the URL in the address bar of your browser with `gitpod.io/#` e.g. `https://github.com/firefox-devtools/profiler` becomes `https://gitpod.io/#https://github.com/firefox-devtools/profiler`. -- Gitpod will then launch a workspace for you and clone the repository, branch, commit or pull request depending on the URL in the first step. - -## Using the gitpod browser extension (optional) - -You can also install the [gitpod browser extension](https://addons.mozilla.org/en-GB/firefox/addon/gitpod/) if you wish instead of prefixing the URL of your browser with `gitpod.io/#` as described in the first step of **Advanced usage** section. - -The browser extension, if you choose to install, will add a button on each repository on Github. Clicking the button will trigger creation of an automatic gitpod setup. diff --git a/res/photon/server.js b/res/photon/server.js index 7fa2178f74..dc08bc121a 100644 --- a/res/photon/server.js +++ b/res/photon/server.js @@ -6,7 +6,7 @@ const port = process.env.FX_PROFILER_PHOTON_PORT || 4243; const host = process.env.FX_PROFILER_PHOTON_HOST || 'localhost'; const serverConfig = { - allowedHosts: ['localhost', '.gitpod.io'], + allowedHosts: ['localhost', '.app.github.dev'], host, port, static: false, diff --git a/server.js b/server.js index 8a270193a6..d2071b82b7 100644 --- a/server.js +++ b/server.js @@ -29,7 +29,7 @@ config.cache = { type: 'filesystem', }; const serverConfig = { - allowedHosts: ['localhost', '.gitpod.io'], + allowedHosts: ['localhost', '.app.github.dev'], host, port, // We disable hot reloading because this takes lot of CPU and memory in the From a10d1fbca2945d8d5c15e437d569e251b5e7d113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 5 Nov 2025 12:31:57 +0100 Subject: [PATCH 29/61] Fix a typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32898ce4b8..1b425401a2 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Say hello on Matrix in the [_Firefox Profiler_ channel (_#profiler:mozilla.org_) [MPL v2](./LICENSE) is designed to encourage contributors to share modifications they make to the code, while still allowing them to combine the code with code under other licenses (open or proprietary) with minimal restrictions. -We are very grateful to the the **zlib compression library (Jean-loup Gailly, Mark Adler and team)** for their contribution to the project. +We are very grateful to the **zlib compression library (Jean-loup Gailly, Mark Adler and team)** for their contribution to the project. [matrix]: https://chat.mozilla.org/#/room/#profiler:mozilla.org From 5006cd5bcc067f51d3aade63eb4e280567d98fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 5 Nov 2025 12:59:48 +0100 Subject: [PATCH 30/61] Migrate from CircleCI to GitHub Actions --- .circleci/config.yml | 132 ------------------ .../actions/setup-node-and-install/action.yml | 14 ++ .github/workflows/ci.yml | 115 +++++++++++++++ .github/workflows/l10n-sync.yml | 44 ++++++ 4 files changed, 173 insertions(+), 132 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/actions/setup-node-and-install/action.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/l10n-sync.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 3656a3a659..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,132 +0,0 @@ -version: 2.1 - -executors: - node: - docker: - - image: cimg/node:22.14 - base: - docker: - - image: cimg/base:stable - -orbs: - shellcheck: circleci/shellcheck@2.0.0 - -commands: - checkout-and-dependencies: - description: 'Checkout and install dependencies, managing a cache' - steps: - - checkout - - restore_cache: - keys: - - v2-dependencies-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }} - - v2-dependencies-{{ checksum "package.json" }} - - v2-dependencies- - # With --frozen-lockfile, the installation will fail if the lockfile is - # outdated compared to package.json. - - run: yarn install --frozen-lockfile - - save_cache: - paths: - - node_modules - key: v2-dependencies-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }} - -# Important: if you add a job here, don't forget to add it to the workflow below too. -jobs: - lint: - executor: node - resource_class: large - steps: - - checkout-and-dependencies - - run: yarn lint - - tests: - executor: node - resource_class: large - steps: - - checkout-and-dependencies - # We use workerIdleMemoryLimit to work around a memory issue with node. - # See https://github.com/facebook/jest/issues/11956 - - run: yarn test --coverage --logHeapUsage -w=4 --workerIdleMemoryLimit=1.5G - - run: yarn codecov - - build-prod: - executor: node - resource_class: large - steps: - - checkout-and-dependencies - - run: yarn build-prod:quiet - - run: yarn build-symbolicator-cli:quiet - - licence-check: - executor: node - steps: - - checkout-and-dependencies - - run: yarn license-check - - typecheck: - executor: node - resource_class: large - steps: - - checkout-and-dependencies - - run: yarn ts - - alex: - executor: node - steps: - - checkout-and-dependencies - - run: yarn test-alex - - yarn_lock: - executor: node - steps: - - checkout-and-dependencies - - run: yarn test-lockfile - - # This is implemented as a separate job instead of using the orb's predefined - # job so that we can have a more descriptive name when reported to github. - # See also https://github.com/CircleCI-Public/shellcheck-orb/issues/29 - shellcheck: - executor: base - steps: - - checkout - - shellcheck/install - - shellcheck/check: - dir: ./bin - - l10n-sync: - executor: node - steps: - - add_ssh_keys: - fingerprints: - - '92:e1:5d:84:70:96:c5:19:76:55:1c:b1:7a:12:9e:53' - - checkout - - run: git config user.email "perf-html@mozilla.com" - - run: git config user.name "Firefox Profiler [bot]" - - run: node ./bin/l10n-sync.js -y - -workflows: - version: 2 - main: - jobs: - - tests - - lint - - build-prod - - typecheck - - licence-check - - alex - - yarn_lock - - shellcheck - - l10n-sync: - triggers: - - schedule: - # CircleCI is using UTC timezone. So, this will be triggered at 8 AM UTC every day. - cron: '0 8 * * *' - filters: - branches: - only: - - main - jobs: - - tests - - l10n-sync: - requires: - - tests diff --git a/.github/actions/setup-node-and-install/action.yml b/.github/actions/setup-node-and-install/action.yml new file mode 100644 index 0000000000..85a3a8ea8e --- /dev/null +++ b/.github/actions/setup-node-and-install/action.yml @@ -0,0 +1,14 @@ +name: 'Setup Node.js and Install Dependencies' +description: 'Setup Node.js with caching and install dependencies' +runs: + using: 'composite' + steps: + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22.14' + cache: 'yarn' + + - name: Install dependencies + shell: bash + run: yarn install --frozen-lockfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..1421c56181 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,115 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Run lint + run: yarn lint + + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Run tests + # We use workerIdleMemoryLimit to work around a memory issue with node. + # See https://github.com/facebook/jest/issues/11956 + run: yarn test --coverage --logHeapUsage -w=4 --workerIdleMemoryLimit=1.5G + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + fail_ci_if_error: false + + build-prod: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Build production + run: yarn build-prod:quiet + + - name: Build symbolicator CLI + run: yarn build-symbolicator-cli:quiet + + licence-check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Run license check + run: yarn license-check + + typecheck: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Run TypeScript check + run: yarn ts + + alex: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Run alex + run: yarn test-alex + + yarn-lock: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Check yarn.lock + run: yarn test-lockfile + + shellcheck: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@master + with: + scandir: './bin' diff --git a/.github/workflows/l10n-sync.yml b/.github/workflows/l10n-sync.yml new file mode 100644 index 0000000000..76a942e8f0 --- /dev/null +++ b/.github/workflows/l10n-sync.yml @@ -0,0 +1,44 @@ +name: L10n Sync + +on: + schedule: + # Runs at 8 AM UTC every day + - cron: '0 8 * * *' + workflow_dispatch: + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Node.js and install dependencies + uses: ./.github/actions/setup-node-and-install + + - name: Run tests + run: yarn test --logHeapUsage -w=4 + + l10n-sync: + runs-on: ubuntu-latest + needs: tests + if: github.ref == 'refs/heads/main' + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ssh-key: ${{ secrets.L10N_SYNC_SSH_KEY }} + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22.14' + cache: 'yarn' + + - name: Configure git + run: | + git config user.email "perf-html@mozilla.com" + git config user.name "Firefox Profiler [bot]" + + - name: Run l10n sync + run: node ./bin/l10n-sync.js -y From a88e4558c1ec196d8c512ff6249856ddcc5fe6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 5 Nov 2025 13:22:04 +0100 Subject: [PATCH 31/61] Change the other CircleCI references --- CONTRIBUTING.md | 2 +- bin/l10n-sync.js | 2 +- bin/pre-install.js | 15 +++++++++------ res/contribute.json | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index afcf18d677..b7389c64cc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,7 +91,7 @@ When working on a new feature and code changes, it's important that things work - We have [husky](https://www.npmjs.com/package/husky) installed to run automated checks when committing and pushing. - Run git commands with `--no-verify` to skip this step. This is useful for submitting broken PRs for feedback. - Continuous integration for pull requests - - We use CircleCI to run our tests for every PR that is submitted. This gives reviewers a great way to know if things are still working as expected. + - We use GitHub Actions to run our tests for every PR that is submitted. This gives reviewers a great way to know if things are still working as expected. ### Updating snapshots diff --git a/bin/l10n-sync.js b/bin/l10n-sync.js index 58d59d2c57..2a6264e136 100644 --- a/bin/l10n-sync.js +++ b/bin/l10n-sync.js @@ -89,7 +89,7 @@ function logAndPipeExec(...commands /*: string[][] */) /*: string */ { /** * Pause with a message and wait for the enter as a confirmation. * The prompt will not be displayed if the `-y` argument is given to the script. - * This is mainly used by the CircleCI automation. + * This is mainly used by the GitHub Actions automation. */ async function pauseWithMessageIfNecessary( message /*: string */ = '' diff --git a/bin/pre-install.js b/bin/pre-install.js index 2395c2a303..10cf9c7920 100644 --- a/bin/pre-install.js +++ b/bin/pre-install.js @@ -98,15 +98,18 @@ function checkYarn(agents /*: AgentsVersion */) { } function parseExpectedNodeVersion() { - // Let's fetch our minimal version from circleci's file + // Let's fetch our minimal version from GitHub Actions composite action file const fs = require('fs'); - const circleConfig = fs.readFileSync('.circleci/config.yml', { - encoding: 'utf8', - }); - const expectedNodeVersion = /image: cimg\/node:([\d.]+)/.exec(circleConfig); + const actionConfig = fs.readFileSync( + '.github/actions/setup-node-and-install/action.yml', + { + encoding: 'utf8', + } + ); + const expectedNodeVersion = /node-version:\s*'([\d.]+)'/.exec(actionConfig); if (!expectedNodeVersion) { throw new Error( - `Couldn't extract the node version from .circleci/config.yml.` + `Couldn't extract the node version from .github/actions/setup-node-and-install/action.yml.` ); } return expectedNodeVersion[1]; diff --git a/res/contribute.json b/res/contribute.json index 6e01e88f6d..940804eef7 100644 --- a/res/contribute.json +++ b/res/contribute.json @@ -4,7 +4,7 @@ "repository": { "url": "https://github.com/firefox-devtools/profiler", "license": "MPL2", - "tests": "https://circleci.com/gh/firefox-devtools/profiler" + "tests": "https://github.com/firefox-devtools/profiler/actions" }, "participate": { "home": "https://github.com/firefox-devtools/profiler/blob/main/CONTRIBUTING.md", From 5e52397d37b32a0e5473ab2ac2a170c4a5d8ef36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 5 Nov 2025 13:23:27 +0100 Subject: [PATCH 32/61] Make the file names consistent with the other workflows --- .github/fluent/{linter_config.yml => linter-config.yml} | 0 .github/workflows/{fluent_linter.yml => fluent-linter.yml} | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/fluent/{linter_config.yml => linter-config.yml} (100%) rename .github/workflows/{fluent_linter.yml => fluent-linter.yml} (92%) diff --git a/.github/fluent/linter_config.yml b/.github/fluent/linter-config.yml similarity index 100% rename from .github/fluent/linter_config.yml rename to .github/fluent/linter-config.yml diff --git a/.github/workflows/fluent_linter.yml b/.github/workflows/fluent-linter.yml similarity index 92% rename from .github/workflows/fluent_linter.yml rename to .github/workflows/fluent-linter.yml index 664221d1bb..e9c53fc9d6 100644 --- a/.github/workflows/fluent_linter.yml +++ b/.github/workflows/fluent-linter.yml @@ -3,7 +3,7 @@ on: push: paths: - 'locales/en-US/*.ftl' - - '.github/workflows/fluent_linter.yml' + - '.github/workflows/fluent-linter.yml' - '.github/fluent/*' branches: - main @@ -32,4 +32,4 @@ jobs: pip install -r .github/fluent/requirements.txt - name: Lint reference run: | - moz-fluent-lint ./locales/en-US --config .github/fluent/linter_config.yml + moz-fluent-lint ./locales/en-US --config .github/fluent/linter-config.yml From 051e6277d35c77f28f7166dcfde7bd0ae2498146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 5 Nov 2025 14:10:05 +0100 Subject: [PATCH 33/61] Remove the unused codecov dependency This dependency was only used inside the CircleCI task for uploading the code coverage results with `yarn codecov`. Since we use the official codecov action in GitHub Actions now, we don't really need it anymore. Note that running `yarn codecov` locally is not possible as it will error out since we are not in a CI environment. --- package.json | 1 - yarn.lock | 139 ++++++++++++--------------------------------------- 2 files changed, 32 insertions(+), 108 deletions(-) diff --git a/package.json b/package.json index d725667c95..0c070b2d35 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,6 @@ "browserslist": "^4.27.0", "caniuse-lite": "^1.0.30001751", "circular-dependency-plugin": "^5.2.1", - "codecov": "^3.8.3", "copy-webpack-plugin": "^13.0.1", "cross-env": "^10.1.0", "css-loader": "^7.1.2", diff --git a/yarn.lock b/yarn.lock index 3d2ba8f218..19562f3188 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2011,11 +2011,6 @@ resolved "https://registry.yarnpkg.com/@tgwf/co2/-/co2-0.16.9.tgz#629dfcc7bc3b5980047793932d9254b9b9578371" integrity sha512-+nuT7HS5r22lbW4MdgSPHhirYBjHR6Q8sz5kX6dKdK+yIkRukLAGaH6L/toZwVEOuEeeIRfWYJuaJIoxEGDMXg== -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -3067,11 +3062,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -argv@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" - integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas= - aria-query@5.3.0, aria-query@^5.0.0: version "5.3.0" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" @@ -3821,17 +3811,6 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -codecov@^3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.3.tgz#9c3e364b8a700c597346ae98418d09880a3fdbe7" - integrity sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA== - dependencies: - argv "0.0.2" - ignore-walk "3.0.4" - js-yaml "3.14.1" - teeny-request "7.1.1" - urlgrey "1.0.0" - collect-v8-coverage@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" @@ -5303,13 +5282,6 @@ fast-uri@^3.0.1: resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748" integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== -fast-url-parser@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" - integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0= - dependencies: - punycode "^1.3.2" - fastest-levenshtein@^1.0.12, fastest-levenshtein@^1.0.16: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -6193,15 +6165,6 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== -http-proxy-agent@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -6247,7 +6210,7 @@ http2-wrapper@^2.1.10: quick-lru "^5.1.1" resolve-alpn "^1.2.0" -https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: +https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -6313,13 +6276,6 @@ idb@^8.0.3: resolved "https://registry.yarnpkg.com/idb/-/idb-8.0.3.tgz#c91e558f15a8d53f1d7f53a094d226fc3ad71fd9" integrity sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg== -ignore-walk@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" - integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== - dependencies: - minimatch "^3.0.4" - ignore@^5.0.0, ignore@^5.2.0: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" @@ -7331,7 +7287,7 @@ jiti@^2.5.1: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.14.1, js-yaml@^3.10.0, js-yaml@^3.13.1: +js-yaml@^3.10.0, js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -9011,13 +8967,6 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-fetch@^2.6.1: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== - dependencies: - whatwg-url "^5.0.0" - node-forge@^1: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" @@ -10075,7 +10024,7 @@ pump@^1.0.1: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^1.3.2, punycode@^1.4.1: +punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== @@ -11270,13 +11219,6 @@ stream-combiner@~0.0.4: dependencies: duplexer "~0.1.1" -stream-events@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" - integrity sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg== - dependencies: - stubs "^3.0.0" - stream-log-stats@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/stream-log-stats/-/stream-log-stats-3.0.2.tgz#405872ca30ffa02966774c7eb0663a257b06bd76" @@ -11316,7 +11258,16 @@ string-length@^4.0.2: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -11438,7 +11389,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11452,6 +11403,13 @@ strip-ansi@^0.3.0: dependencies: ansi-regex "^0.2.1" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -11503,11 +11461,6 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -stubs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" - integrity sha1-6NK6H6nJBXAwPAMLaQD31fiavls= - style-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-4.0.0.tgz#0ea96e468f43c69600011e0589cb05c44f3b17a5" @@ -11701,17 +11654,6 @@ tapable@^2.0.0, tapable@^2.2.0, tapable@^2.3.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== -teeny-request@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.1.1.tgz#2b0d156f4a8ad81de44303302ba8d7f1f05e20e6" - integrity sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg== - dependencies: - http-proxy-agent "^4.0.0" - https-proxy-agent "^5.0.0" - node-fetch "^2.6.1" - stream-events "^1.0.5" - uuid "^8.0.0" - temp-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" @@ -11869,11 +11811,6 @@ tr46@^5.1.0: dependencies: punycode "^2.3.1" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - treeify@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" @@ -12324,13 +12261,6 @@ url@^0.11.4: punycode "^1.4.1" qs "^6.12.3" -urlgrey@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-1.0.0.tgz#72d2f904482d0b602e3c7fa599343d699bbe1017" - integrity sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w== - dependencies: - fast-url-parser "^1.1.3" - use-sync-external-store@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc" @@ -12356,7 +12286,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^8.0.0, uuid@^8.3.2: +uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -12508,11 +12438,6 @@ web-namespaces@^2.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.0.tgz#1f6a2d7b5823329abaedeb6bdf09ef2fed35db13" integrity sha512-dE7ELZRVWh0ceQsRgkjLgsAvwTuv3kcjSY/hLjqL0llleUlQBDjE9JkB9FCBY5F2mnFEwiyJoowl8+NVGHe8dw== -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -12675,14 +12600,6 @@ whatwg-url@^14.0.0, whatwg-url@^14.1.1: tr46 "^5.1.0" webidl-conversions "^7.0.0" -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" @@ -12965,8 +12882,16 @@ workbox-window@7.3.0, workbox-window@^7.3.0: "@types/trusted-types" "^2.0.2" workbox-core "7.3.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - name wrap-ansi-cjs +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From b78d35c4afb403650899f9ecdf0b37bdee407ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Thu, 6 Nov 2025 15:38:39 +0100 Subject: [PATCH 34/61] Run the CI in the production branch and on every pull request --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1421c56181..7a91be5dc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,9 +4,8 @@ on: push: branches: - main + - production pull_request: - branches: - - main jobs: lint: From f60e897acb378e23ecae11db0a40cc54e836b08a Mon Sep 17 00:00:00 2001 From: Pontoon Date: Thu, 6 Nov 2025 15:41:51 +0000 Subject: [PATCH 35/61] Pontoon/Firefox Profiler: Update Chinese (China) (zh-CN) Co-authored-by: wxie (zh-CN) --- locales/zh-CN/app.ftl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/locales/zh-CN/app.ftl b/locales/zh-CN/app.ftl index 9e07d68e78..18185466d4 100644 --- a/locales/zh-CN/app.ftl +++ b/locales/zh-CN/app.ftl @@ -364,6 +364,16 @@ MarkerTable--duration = 持续时间 MarkerTable--name = 名称 MarkerTable--details = 详情 +## MarkerTooltip +## This is the component for Marker Tooltip panel. + +# This is used as the tooltip for the filter button in marker tooltips. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerTooltip--filter-button-tooltip = + .title = 仅显示匹配“{ $filter }”的标记 + .aria-label = 仅显示匹配“{ $filter }”的标记 + ## MenuButtons ## These strings are used for the buttons at the top of the profile viewer. From f591fe5c26db71ab93fd4eda73dafe332dd97b68 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Thu, 6 Nov 2025 15:51:56 +0000 Subject: [PATCH 36/61] Pontoon/Firefox Profiler: Update Chinese (China) (zh-CN) --- locales/zh-CN/app.ftl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/locales/zh-CN/app.ftl b/locales/zh-CN/app.ftl index 18185466d4..1833e00e5d 100644 --- a/locales/zh-CN/app.ftl +++ b/locales/zh-CN/app.ftl @@ -333,15 +333,6 @@ MarkerContextMenu--select-the-receiver-thread = 选择 Receiver 线程“{ $threadName }” -## MarkerFiltersContextMenu -## This is the menu when filter icon is clicked in Marker Chart and Marker Table -## panels. - -# This string is used on the marker filters menu item when clicked on the filter icon. -# Variables: -# $filter (String) - Search string that will be used to filter the markers. -MarkerFiltersContextMenu--drop-samples-outside-of-markers-matching = 不用标记过滤器“{ $filter }”标记此样本 - ## MarkerSettings ## This is used in all panels related to markers. @@ -954,10 +945,6 @@ TransformNavigator--collapse-direct-recursion-only = 仅取消直接递归:{ $ # Variables: # $item (String) - Name of the function that transform applied to. TransformNavigator--collapse-function-subtree = 折叠子树:{ $item } -# "Drop samples outside of markers matching ..." transform. -# Variables: -# $item (String) - Search filter of the markers that transform will apply to. -TransformNavigator--drop-samples-outside-of-markers-matching = 不用过滤器 “{ $item }” 标记该样本 ## "Bottom box" - a view which contains the source view and the assembly view, ## at the bottom of the profiler UI From 2109601baa4be363721316a2f5cdbc3c20578131 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Thu, 6 Nov 2025 16:11:52 +0000 Subject: [PATCH 37/61] Pontoon/Firefox Profiler: Update Chinese (China) (zh-CN) Co-authored-by: Olvcpr423 (zh-CN) --- locales/zh-CN/app.ftl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/locales/zh-CN/app.ftl b/locales/zh-CN/app.ftl index 1833e00e5d..aaef8d3848 100644 --- a/locales/zh-CN/app.ftl +++ b/locales/zh-CN/app.ftl @@ -333,6 +333,15 @@ MarkerContextMenu--select-the-receiver-thread = 选择 Receiver 线程“{ $threadName }” +## MarkerFiltersContextMenu +## This is the menu when filter icon is clicked in Marker Chart and Marker Table +## panels. + +# This string is used on the marker filters menu item when clicked on the filter icon. +# Variables: +# $filter (String) - Search string that will be used to filter the markers. +MarkerFiltersContextMenu--drop-samples-outside-of-markers-matching = 丢弃与标记(匹配条件:“{ $filter }”)不相关的样本 + ## MarkerSettings ## This is used in all panels related to markers. @@ -945,6 +954,10 @@ TransformNavigator--collapse-direct-recursion-only = 仅取消直接递归:{ $ # Variables: # $item (String) - Name of the function that transform applied to. TransformNavigator--collapse-function-subtree = 折叠子树:{ $item } +# "Drop samples outside of markers matching ..." transform. +# Variables: +# $item (String) - Search filter of the markers that transform will apply to. +TransformNavigator--drop-samples-outside-of-markers-matching = 丢弃与标记(匹配条件:“{ $item }”)不相关的样本 ## "Bottom box" - a view which contains the source view and the assembly view, ## at the bottom of the profiler UI From fd1456dc5caf0bdba00d276b0e4abca18f6b0983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Thu, 6 Nov 2025 18:15:06 +0100 Subject: [PATCH 38/61] Convert l10n-sync.js from Flow comment types to JSDoc comments for Typescript (#5659) Previously we were using the Flow comment types to type check this file. But it looks like we forgot to switch them to JSDoc comments. --- bin/l10n-sync.js | 98 ++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/bin/l10n-sync.js b/bin/l10n-sync.js index 2a6264e136..3f88f5baeb 100644 --- a/bin/l10n-sync.js +++ b/bin/l10n-sync.js @@ -12,19 +12,16 @@ const cp = require('child_process'); const readline = require('readline'); const { promisify } = require('util'); -/*:: - type ExecFilePromiseResult = {| - stdout: string | Buffer, - stderr: string | Buffer - |}; - - type ExecFile = ( - command: string, - args?: string[] - ) => Promise; -*/ +/** + * @typeef {Object} ExecFilePromiseResult + * @property {string | Buffer} stdout + * @property {string | Buffer} stderr + */ -const execFile /*: ExecFile */ = promisify(cp.execFile); +/** + * @type {(command: string, args?: string[]) => Promise} + */ +const execFile = promisify(cp.execFile); const DATE_FORMAT = new Intl.DateTimeFormat('en-US', { month: 'long', @@ -39,12 +36,12 @@ const MERGE_COMMIT_MESSAGE = '🔃 Daily sync: main -> l10n'; * Logs the command to be executed first, and spawns a shell then executes the * command. Returns the stdout of the executed command. * + * @param {string} executable + * @param {...string} args + * @returns {Promise} * @throws Will throw an error if executed command fails. */ -async function logAndExec( - executable /*: string */, - ...args /*: string[] */ -) /*: Promise */ { +async function logAndExec(executable, ...args) { console.log('[exec]', executable, args.join(' ')); const result = await execFile(executable, args); @@ -64,9 +61,11 @@ async function logAndExec( * and pipes the stdout of them to the next one. In the end, returns the stdout * of the last piped command. * + * @param {...string[]} commands + * @returns {string} * @throws Will throw an error if one of the executed commands fails. */ -function logAndPipeExec(...commands /*: string[][] */) /*: string */ { +function logAndPipeExec(...commands) { console.log( '[exec]', commands.map((command) => command.join(' ')).join(' | ') @@ -90,10 +89,11 @@ function logAndPipeExec(...commands /*: string[][] */) /*: string */ { * Pause with a message and wait for the enter as a confirmation. * The prompt will not be displayed if the `-y` argument is given to the script. * This is mainly used by the GitHub Actions automation. + * + * @param {string} [message=''] + * @returns {Promise} */ -async function pauseWithMessageIfNecessary( - message /*: string */ = '' -) /*: Promise */ { +async function pauseWithMessageIfNecessary(message = '') { if (SKIP_PROMPTS) { return; } @@ -115,9 +115,10 @@ async function pauseWithMessageIfNecessary( /** * Check if Git workspace is clean. * + * @returns {Promise} * @throws Will throw an error if workspace is not clean. */ -async function checkIfWorkspaceClean() /*: Promise */ { +async function checkIfWorkspaceClean() { console.log('>>> Checking if the workspace is clean for the operations.'); // git status --porcelain --ignore-submodules -unormal const statusResult = await logAndExec( @@ -140,9 +141,10 @@ async function checkIfWorkspaceClean() /*: Promise */ { /** * Finds the Git upstream remote and returns it. * + * @returns {Promise} * @throws Will throw an error if it can't find an upstream remote. */ -async function findUpstream() /*: Promise */ { +async function findUpstream() { console.log('>>> Finding the upstream remote.'); try { const gitRemoteResult = await logAndExec('git', 'remote', '-v'); @@ -178,19 +180,21 @@ async function findUpstream() /*: Promise */ { * Fails if the `compareBranch` has changes from the files that doesn't match * the `allowedRegexp`. * + * @param {Object} options + * @param {string} options.upstream + * @param {string} options.compareBranch + * @param {string} options.baseBranch + * @param {RegExp} options.allowedRegexp + * @returns {Promise} * @throws Will throw an error if `compareBranch` has changes from the files * that doesn't match the `allowedRegexp`. */ -async function checkAllowedPaths( - { upstream, compareBranch, baseBranch, allowedRegexp } /*: - {| - upstream: string, - compareBranch: string, - baseBranch: string , - allowedRegexp: RegExp - |} - */ -) { +async function checkAllowedPaths({ + upstream, + compareBranch, + baseBranch, + allowedRegexp, +}) { console.log( `>>> Checking if ${compareBranch} branch has changes from the files that are not allowed.` ); @@ -224,8 +228,11 @@ async function checkAllowedPaths( * It's a pretty simple hack and would be good to have a more sophisticated * (localized?) API function. But it's not really worth for a deployment only * script. + * + * @param {number} count + * @returns {string} */ -function fewTimes(count /*: number */) /*: string */ { +function fewTimes(count) { switch (count) { case 1: return 'once'; @@ -239,9 +246,11 @@ function fewTimes(count /*: number */) /*: string */ { /** * Tries to sync the l10n branch and retries for 3 times if it fails to sync. * + * @param {string} upstream + * @returns {Promise} * @throws Will throw an error if it fails to sync for more than 3 times. */ -async function tryToSync(upstream /*: string */) /*: Promise */ { +async function tryToSync(upstream) { console.log('>>> Syncing the l10n branch with main.'); // RegExp for matching only the vendored locales. // It matches the files in `locales` directory but excludes `en-US` which is the @@ -268,7 +277,8 @@ async function tryToSync(upstream /*: string */) /*: Promise */ { // changes and try again. Nevertheless, we should have a hard cap on the try // count for safety. const totalTryCount = 3; - let error /*: Error | null */ = null; + /** @type {Error | null} */ + let error = null; let tryCount = 0; // Try to sync and retry for `totalTryCount` times if it fails. @@ -341,9 +351,10 @@ async function tryToSync(upstream /*: string */) /*: Promise */ { /** * Main function to be executed in the global scope. * + * @returns {Promise} * @throws Will throw an error if any of the functions it calls throw. */ -async function main() /*: Promise */ { +async function main() { const args = process.argv.slice(2); if (args.includes('-y')) { @@ -363,8 +374,13 @@ async function main() /*: Promise */ { console.log('>>> Done!'); } -main().catch((error /*: Error */) => { - // Print the error to the console and exit if an error is caught. - console.error(error); - process.exitCode = 1; -}); +main().catch( + /** + * @param {Error} error + */ + (error) => { + // Print the error to the console and exit if an error is caught. + console.error(error); + process.exitCode = 1; + } +); From c6894f2a016133ccc1cb5c043c89942004162235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 6 Nov 2025 21:19:30 +0100 Subject: [PATCH 39/61] Display correct unit in Stack Chart tooltips for size profiles. (#5658) --- src/components/stack-chart/Canvas.tsx | 12 ++++++++++-- src/components/stack-chart/index.tsx | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/stack-chart/Canvas.tsx b/src/components/stack-chart/Canvas.tsx index d158b1d7ff..0c113a3872 100644 --- a/src/components/stack-chart/Canvas.tsx +++ b/src/components/stack-chart/Canvas.tsx @@ -8,7 +8,7 @@ import { withChartViewport, type Viewport } from '../shared/chart/Viewport'; import { ChartCanvas } from '../shared/chart/Canvas'; import { FastFillStyle } from '../../utils'; import TextMeasurement from '../../utils/text-measurement'; -import { formatMilliseconds } from '../../utils/format-numbers'; +import { formatMilliseconds, formatBytes } from '../../utils/format-numbers'; import { bisectionLeft, bisectionRight } from '../../utils/bisect'; import type { updatePreviewSelection, @@ -36,6 +36,7 @@ import type { Marker, InnerWindowID, Page, + TimelineUnit, } from 'firefox-profiler/types'; import type { CallNodeInfo } from 'firefox-profiler/profile-logic/call-node-info'; @@ -77,6 +78,7 @@ type OwnProps = { readonly marginLeft: CssPixels; readonly displayStackType: boolean; readonly useStackChartSameWidths: boolean; + readonly timelineUnit: TimelineUnit; }; type Props = Readonly< @@ -617,6 +619,12 @@ class StackChartCanvasImpl extends React.PureComponent { const duration = timing.end[stackTimingIndex] - timing.start[stackTimingIndex]; + const { timelineUnit } = this.props; + const durationText = + timelineUnit === 'bytes' + ? formatBytes(duration) + : formatMilliseconds(duration); + return ( { categories={categories} // The stack chart doesn't support other call tree summary types. callTreeSummaryStrategy="timing" - durationText={formatMilliseconds(duration)} + durationText={durationText} displayStackType={displayStackType} /> ); diff --git a/src/components/stack-chart/index.tsx b/src/components/stack-chart/index.tsx index d2fdf4fa5e..ad706dd84c 100644 --- a/src/components/stack-chart/index.tsx +++ b/src/components/stack-chart/index.tsx @@ -17,6 +17,7 @@ import { getCategories, getInnerWindowIDToPageMap, getProfileUsesMultipleStackTypes, + getProfileTimelineUnit, } from '../../selectors/profile'; import { getStackChartSameWidths, @@ -55,6 +56,7 @@ import type { ThreadsKey, InnerWindowID, Page, + TimelineUnit, } from 'firefox-profiler/types'; import type { CallNodeInfo } from 'firefox-profiler/profile-logic/call-node-info'; @@ -84,6 +86,7 @@ type StateProps = { readonly displayStackType: boolean; readonly hasFilteredCtssSamples: boolean; readonly useStackChartSameWidths: boolean; + readonly timelineUnit: TimelineUnit; }; type DispatchProps = { @@ -223,6 +226,7 @@ class StackChartImpl extends React.PureComponent { displayStackType, hasFilteredCtssSamples, useStackChartSameWidths, + timelineUnit, } = this.props; const maxViewportHeight = combinedTimingRows.length * STACK_FRAME_HEIGHT; @@ -282,6 +286,7 @@ class StackChartImpl extends React.PureComponent { marginLeft: TIMELINE_MARGIN_LEFT, displayStackType: displayStackType, useStackChartSameWidths, + timelineUnit, }} /> @@ -324,6 +329,7 @@ export const StackChart = explicitConnect<{}, StateProps, DispatchProps>({ hasFilteredCtssSamples: selectedThreadSelectors.getHasFilteredCtssSamples(state), useStackChartSameWidths: getStackChartSameWidths(state), + timelineUnit: getProfileTimelineUnit(state), }; }, mapDispatchToProps: { From 9f99ec8976d7089327dfb70a00b66bb3aa617ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 6 Nov 2025 21:28:51 +0100 Subject: [PATCH 40/61] Hide track management UI in single track profiles. (#5656) --- src/components/timeline/FullTimeline.tsx | 14 ++++++---- src/components/timeline/GlobalTrack.tsx | 27 +++++++++++-------- src/components/timeline/index.css | 13 ++++++--- .../__snapshots__/GlobalTrack.test.tsx.snap | 10 ------- .../__snapshots__/Timeline.test.tsx.snap | 10 ------- 5 files changed, 34 insertions(+), 40 deletions(-) diff --git a/src/components/timeline/FullTimeline.tsx b/src/components/timeline/FullTimeline.tsx index 32fa0629b2..35b0c38db2 100644 --- a/src/components/timeline/FullTimeline.tsx +++ b/src/components/timeline/FullTimeline.tsx @@ -155,10 +155,14 @@ class FullTimelineImpl extends React.PureComponent { <>
- + {hiddenTrackCount.total > 1 ? ( + + ) : ( +
+ )} { - + {hiddenTrackCount.total > 1 ? : null} ); } diff --git a/src/components/timeline/GlobalTrack.tsx b/src/components/timeline/GlobalTrack.tsx index e560a1433d..a8046f1368 100644 --- a/src/components/timeline/GlobalTrack.tsx +++ b/src/components/timeline/GlobalTrack.tsx @@ -70,6 +70,7 @@ type StateProps = { readonly selectedTab: TabSlug; readonly processesWithMemoryTrack: Set; readonly progressGraphData: ProgressGraphData[] | null; + readonly totalTrackCount: number; }; type DispatchProps = { @@ -243,6 +244,7 @@ class GlobalTrackComponent extends PureComponent { localTracks, pid, globalTrack, + totalTrackCount, } = this.props; if (isHidden) { @@ -290,17 +292,19 @@ class GlobalTrackComponent extends PureComponent {
) : null} - -
Process 0 -
Process 0 -
Process 0 -
Process 0 -
Date: Thu, 6 Nov 2025 23:14:19 +0100 Subject: [PATCH 41/61] Rename hiddenTrackCount to trackCount. (#5665) --- src/components/timeline/FullTimeline.tsx | 28 ++++++++++++------------ src/selectors/profile.ts | 4 ++-- src/test/store/tracks.test.ts | 4 ++-- src/types/actions.ts | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/components/timeline/FullTimeline.tsx b/src/components/timeline/FullTimeline.tsx index 35b0c38db2..97eb3b65d3 100644 --- a/src/components/timeline/FullTimeline.tsx +++ b/src/components/timeline/FullTimeline.tsx @@ -19,7 +19,7 @@ import { getProfileTimelineUnit, getGlobalTracks, getGlobalTrackReferences, - getHiddenTrackCount, + getTrackCount, getGlobalTrackOrder, getPanelLayoutGeneration, } from 'firefox-profiler/selectors'; @@ -39,7 +39,7 @@ import type { GlobalTrack, InitialSelectedTrackReference, GlobalTrackReference, - HiddenTrackCount, + TrackCount, Milliseconds, StartEndRange, TimelineUnit, @@ -60,7 +60,7 @@ type StateProps = { readonly panelLayoutGeneration: number; readonly zeroAt: Milliseconds; readonly profileTimelineUnit: TimelineUnit; - readonly hiddenTrackCount: HiddenTrackCount; + readonly trackCount: TrackCount; }; type DispatchProps = { @@ -75,7 +75,7 @@ type State = { }; class TimelineSettingsHiddenTracks extends React.PureComponent<{ - readonly hiddenTrackCount: HiddenTrackCount; + readonly trackCount: TrackCount; readonly changeRightClickedTrack: typeof changeRightClickedTrack; }> { _showMenu = (event: React.MouseEvent) => { @@ -90,7 +90,7 @@ class TimelineSettingsHiddenTracks extends React.PureComponent<{ }; override render() { - const { hiddenTrackCount } = this.props; + const { trackCount } = this.props; return ( , }} vars={{ - visibleTrackCount: hiddenTrackCount.total - hiddenTrackCount.hidden, - totalTrackCount: hiddenTrackCount.total, + visibleTrackCount: trackCount.total - trackCount.hidden, + totalTrackCount: trackCount.total, }} > @@ -146,7 +146,7 @@ class FullTimelineImpl extends React.PureComponent { width, globalTrackReferences, panelLayoutGeneration, - hiddenTrackCount, + trackCount, changeRightClickedTrack, innerElementRef, } = this.props; @@ -155,9 +155,9 @@ class FullTimelineImpl extends React.PureComponent { <>
- {hiddenTrackCount.total > 1 ? ( + {trackCount.total > 1 ? ( ) : ( @@ -196,7 +196,7 @@ class FullTimelineImpl extends React.PureComponent { - {hiddenTrackCount.total > 1 ? : null} + {trackCount.total > 1 ? : null} ); } @@ -215,7 +215,7 @@ export const FullTimeline = explicitConnect< zeroAt: getZeroAt(state), profileTimelineUnit: getProfileTimelineUnit(state), panelLayoutGeneration: getPanelLayoutGeneration(state), - hiddenTrackCount: getHiddenTrackCount(state), + trackCount: getTrackCount(state), }), mapDispatchToProps: { changeGlobalTrackOrder, diff --git a/src/selectors/profile.ts b/src/selectors/profile.ts index 38d2e68e9e..a0fa0b175d 100644 --- a/src/selectors/profile.ts +++ b/src/selectors/profile.ts @@ -56,7 +56,7 @@ import type { TrackReference, LastNonShiftClickInformation, PreviewSelection, - HiddenTrackCount, + TrackCount, Selector, DangerousSelectorWithArguments, State, @@ -609,7 +609,7 @@ export const getLocalTrackName = ( * then all its children are as well. This function walks all of the data to determine * the correct hidden counts. */ -export const getHiddenTrackCount: Selector = createSelector( +export const getTrackCount: Selector = createSelector( getGlobalTracks, getLocalTracksByPid, UrlState.getHiddenLocalTracksByPid, diff --git a/src/test/store/tracks.test.ts b/src/test/store/tracks.test.ts index 8a664ef478..4a128f35be 100644 --- a/src/test/store/tracks.test.ts +++ b/src/test/store/tracks.test.ts @@ -624,7 +624,7 @@ describe('ordering and hiding', function () { it('can count hidden local tracks', function () { const { getState, dispatch, workerTrackIndex, tabPid } = init(); dispatch(hideLocalTrack(tabPid, workerTrackIndex)); - expect(ProfileViewSelectors.getHiddenTrackCount(getState())).toEqual({ + expect(ProfileViewSelectors.getTrackCount(getState())).toEqual({ hidden: 1, total: 4, }); @@ -633,7 +633,7 @@ describe('ordering and hiding', function () { it('can count hidden global tracks and their hidden local tracks', function () { const { getState, dispatch, tabTrackIndex } = init(); dispatch(hideGlobalTrack(tabTrackIndex)); - expect(ProfileViewSelectors.getHiddenTrackCount(getState())).toEqual({ + expect(ProfileViewSelectors.getTrackCount(getState())).toEqual({ hidden: 3, total: 4, }); diff --git a/src/types/actions.ts b/src/types/actions.ts index cf2465ee78..940b018500 100644 --- a/src/types/actions.ts +++ b/src/types/actions.ts @@ -95,7 +95,7 @@ export type PreviewSelection = { /** * The counts for how many tracks are hidden in the timeline. */ -export type HiddenTrackCount = { +export type TrackCount = { readonly hidden: number; readonly total: number; }; From c7066b0237bd955cdf08a4e21317cc68ce94b890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Qu=C3=A8ze?= Date: Thu, 6 Nov 2025 23:28:58 +0100 Subject: [PATCH 42/61] Cleanup the profile info panel for size profiles (show file size and name, hide empty sections). (#5657) --- locales/en-US/app.ftl | 2 + src/components/app/MenuButtons/MetaInfo.tsx | 396 +++++++++++------- .../__snapshots__/MenuButtons.test.tsx.snap | 24 -- src/types/profile.ts | 4 + 4 files changed, 249 insertions(+), 177 deletions(-) diff --git a/locales/en-US/app.ftl b/locales/en-US/app.ftl index 336411c89d..9eb89ea769 100644 --- a/locales/en-US/app.ftl +++ b/locales/en-US/app.ftl @@ -581,6 +581,8 @@ MenuButtons--metaInfo--profiling-started = Recording started: MenuButtons--metaInfo--profiling-session = Recording length: MenuButtons--metaInfo--main-process-started = Main process started: MenuButtons--metaInfo--main-process-ended = Main process ended: +MenuButtons--metaInfo--file-name = File name: +MenuButtons--metaInfo--file-size = File size: MenuButtons--metaInfo--interval = Interval: MenuButtons--metaInfo--buffer-capacity = Buffer capacity: MenuButtons--metaInfo--buffer-duration = Buffer duration: diff --git a/src/components/app/MenuButtons/MetaInfo.tsx b/src/components/app/MenuButtons/MetaInfo.tsx index f9b319342a..8defaf2ef9 100644 --- a/src/components/app/MenuButtons/MetaInfo.tsx +++ b/src/components/app/MenuButtons/MetaInfo.tsx @@ -9,6 +9,7 @@ import { getProfile, getSymbolicationStatus, getProfileExtraInfo, + getProfileTimelineUnit, } from 'firefox-profiler/selectors/profile'; import { resymbolicateProfile } from 'firefox-profiler/actions/receive-profile'; import { formatFromMarkerSchema } from 'firefox-profiler/profile-logic/marker-schema'; @@ -29,6 +30,7 @@ import type { Profile, SymbolicationStatus, ExtraProfileInfoSection, + TimelineUnit, } from 'firefox-profiler/types'; import type { ConnectedProps } from 'firefox-profiler/utils/connect'; import { StringTable } from 'firefox-profiler/utils/string-table'; @@ -43,6 +45,7 @@ type StateProps = Readonly<{ profile: Profile; symbolicationStatus: SymbolicationStatus; profileExtraInfo: ExtraProfileInfoSection[]; + timelineUnit: TimelineUnit; }>; type DispatchProps = Readonly<{ @@ -186,138 +189,151 @@ class MetaInfoPanelImpl extends React.PureComponent { ); } - override render() { - const { meta, profilerOverhead } = this.props.profile; + _renderRecordingInfo() { + const { meta } = this.props.profile; const { configuration } = meta; - - const platformInformation = formatPlatform(meta); - - let cpuCount = null; - if (meta.physicalCPUs && meta.logicalCPUs) { - cpuCount = ( - - ); - } else if (meta.physicalCPUs) { - cpuCount = ( - - ); - } else if (meta.logicalCPUs) { - cpuCount = ( - - ); - } + const { timelineUnit } = this.props; return ( - <> -
- {meta.profilingStartTime !== undefined && meta.startTime ? ( +
+ {meta.profilingStartTime !== undefined && meta.startTime ? ( +
+ + + Recording started: + + + {_formatDate(meta.startTime + meta.profilingStartTime)} +
+ ) : null} + {meta.profilingStartTime !== undefined && meta.profilingEndTime ? ( +
+ + + Recording length: + + + {formatTimestamp(meta.profilingEndTime - meta.profilingStartTime)} +
+ ) : null} + {meta.fileName ? ( +
+ + + File name: + + + {meta.fileName} +
+ ) : null} + {meta.fileSize ? ( +
+ + + File size: + + + {formatBytes(meta.fileSize)} +
+ ) : null} + {meta.profilingStartTime === undefined && meta.startTime ? ( +
+ + + Main process started: + + + {_formatDate(meta.startTime)} +
+ ) : null} + {meta.endTime ? ( +
+ + + Main process ended: + + + {_formatDate(meta.endTime)} +
+ ) : null} + {meta.interval ? ( +
+ + + Interval: + + + {timelineUnit === 'bytes' + ? formatBytes(meta.interval) + : formatTimestamp(meta.interval, 4, 1)} +
+ ) : null} + {configuration ? ( + <>
- - Recording started: + + Buffer capacity: - {_formatDate(meta.startTime + meta.profilingStartTime)} + { + /* The capacity is expressed in "entries", where 1 entry == 8 bytes. */ + formatBytes(configuration.capacity * 8, 0) + }
- ) : null} - {meta.profilingStartTime !== undefined && meta.profilingEndTime ? (
- - Recording length: + + Buffer duration: - {formatTimestamp(meta.profilingEndTime - meta.profilingStartTime)} -
- ) : null} - {meta.profilingStartTime === undefined && meta.startTime ? ( -
- - - Main process started: + {configuration.duration ? ( + + {'{$configurationDuration} seconds'} - - {_formatDate(meta.startTime)} -
- ) : null} - {meta.endTime ? ( -
- - - Main process ended: + ) : ( + + Unlimited - - {_formatDate(meta.endTime)} + )}
- ) : null} - {meta.interval ? ( -
- - - Interval: - - - {formatTimestamp(meta.interval, 4, 1)} +
+ {_renderRowOfList( + 'MenuButtons--metaInfo-renderRowOfList-label-features', + configuration.features + )} + {_renderRowOfList( + 'MenuButtons--metaInfo-renderRowOfList-label-threads-filter', + configuration.threads + )}
- ) : null} - {configuration ? ( - <> -
- - - Buffer capacity: - - - { - /* The capacity is expressed in "entries", where 1 entry == 8 bytes. */ - formatBytes(configuration.capacity * 8, 0) - } -
-
- - - Buffer duration: - - - {configuration.duration ? ( - - {'{$configurationDuration} seconds'} - - ) : ( - - Unlimited - - )} -
-
- {_renderRowOfList( - 'MenuButtons--metaInfo-renderRowOfList-label-features', - configuration.features - )} - {_renderRowOfList( - 'MenuButtons--metaInfo-renderRowOfList-label-threads-filter', - configuration.threads - )} -
- - ) : null} - {this.renderSymbolication()} -
+ + ) : null} + {this.renderSymbolication()} +
+ ); + } + + _renderApplicationSection() { + const { meta } = this.props.profile; + + if ( + !meta.product && + !meta.profilingStartTime && + !meta.updateChannel && + !meta.appBuildID && + meta.debug === undefined && + !meta.extensions && + !meta.arguments + ) { + return null; + } + + return ( + <>

Application @@ -408,6 +424,57 @@ class MetaInfoPanelImpl extends React.PureComponent {

) : null}
+ + ); + } + + _renderPlatformSection() { + const { meta } = this.props.profile; + + if ( + !meta.device && + !meta.oscpu && + !meta.platform && + !meta.abi && + !meta.CPUName && + !meta.physicalCPUs && + !meta.logicalCPUs && + !meta.mainMemory + ) { + return null; + } + + const platformInformation = formatPlatform(meta); + + let cpuCount = null; + if (meta.physicalCPUs && meta.logicalCPUs) { + cpuCount = ( + + ); + } else if (meta.physicalCPUs) { + cpuCount = ( + + ); + } else if (meta.logicalCPUs) { + cpuCount = ( + + ); + } + + return ( + <>

Platform

@@ -469,45 +536,67 @@ class MetaInfoPanelImpl extends React.PureComponent {
) : null} - {meta.visualMetrics ? ( - <> -

- - Visual metrics + + ); + } + + _renderVisualMetricsSection() { + const { meta } = this.props.profile; + + if (!meta.visualMetrics) { + return null; + } + + return ( + <> +

+ + Visual metrics + +

+
+
+ + + Speed Index: -

-
-
- - - Speed Index: - - - {meta.visualMetrics.SpeedIndex} -
-
- - - Perceptual Speed Index: - - - {meta.visualMetrics.PerceptualSpeedIndex} -
-
- - - Contentful Speed Index: - - - {meta.visualMetrics.ContentfulSpeedIndex} -
-
- - ) : null} +
+ {meta.visualMetrics.SpeedIndex} + +
+ + + Perceptual Speed Index: + + + {meta.visualMetrics.PerceptualSpeedIndex} +
+
+ + + Contentful Speed Index: + + + {meta.visualMetrics.ContentfulSpeedIndex} +
+ + + ); + } + + override render() { + const { profilerOverhead } = this.props.profile; + + return ( + <> + {this._renderRecordingInfo()} + {this._renderApplicationSection()} + {this._renderPlatformSection()} + {this._renderVisualMetricsSection()} {/* - Older profiles(before FF 70) don't have any overhead info. - Don't show anything if that's the case. - */} + Older profiles(before FF 70) don't have any overhead info. + Don't show anything if that's the case. + */} {profilerOverhead ? ( ) : null} @@ -559,6 +648,7 @@ export const MetaInfoPanel = explicitConnect<{}, StateProps, DispatchProps>({ profile: getProfile(state), symbolicationStatus: getSymbolicationStatus(state), profileExtraInfo: getProfileExtraInfo(state), + timelineUnit: getProfileTimelineUnit(state), }), mapDispatchToProps: { resymbolicateProfile, diff --git a/src/test/components/__snapshots__/MenuButtons.test.tsx.snap b/src/test/components/__snapshots__/MenuButtons.test.tsx.snap index 388a311171..944baae3a4 100644 --- a/src/test/components/__snapshots__/MenuButtons.test.tsx.snap +++ b/src/test/components/__snapshots__/MenuButtons.test.tsx.snap @@ -167,14 +167,6 @@ exports[`app/MenuButtons deleting a profile displays the delete release -

- Platform -

-
`; @@ -286,14 +278,6 @@ exports[`app/MenuButtons deleting a profile displays the delete release -

- Platform -

-
`; @@ -379,14 +363,6 @@ exports[`app/MenuButtons deleting a profile does not display the release -

- Platform -

-
`; diff --git a/src/types/profile.ts b/src/types/profile.ts index 90460a31a5..3e5e02466e 100644 --- a/src/types/profile.ts +++ b/src/types/profile.ts @@ -895,6 +895,10 @@ export type ProfileMeta = { // They also use the "product" field in the meta information, but this is somewhat // ambiguous. This field, if present, is unambiguous that it was imported. importedFrom?: string; + // For size profiles, the name of the file being profiled. + fileName?: string; + // For size profiles, the total size of the file in bytes. + fileSize?: Bytes; // The following are settings that are used to configure the views for // imported profiles, as some features do not make sense for them From abd8ccff4d3ad453aa03cab1c86a1cef4e389fe2 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Thu, 6 Nov 2025 17:17:41 -0500 Subject: [PATCH 43/61] Use valibot for symbolication API response validation. --- package.json | 1 + .../mozilla-symbolication-api.ts | 165 +++++------------- src/test/store/receive-profile.test.ts | 2 +- yarn.lock | 5 + 4 files changed, 46 insertions(+), 127 deletions(-) diff --git a/package.json b/package.json index 0c070b2d35..bda6734ad4 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "redux-thunk": "^3.1.0", "reselect": "^4.1.8", "url": "^0.11.4", + "valibot": "^1.1.0", "weaktuplemap": "^1.0.0", "workbox-window": "^7.3.0" }, diff --git a/src/profile-logic/mozilla-symbolication-api.ts b/src/profile-logic/mozilla-symbolication-api.ts index 2c8ecfc092..98c2cbee63 100644 --- a/src/profile-logic/mozilla-symbolication-api.ts +++ b/src/profile-logic/mozilla-symbolication-api.ts @@ -1,6 +1,7 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import * as v from 'valibot'; import type { AddressResult, LibSymbolicationRequest, @@ -28,156 +29,68 @@ export type QuerySymbolicationApiCallback = ( requestJson: string ) => Promise; -type APIFoundModulesV5 = { - // For every requested library in the memoryMap, this object contains a string - // key of the form `${debugName}/${breakpadId}`. The value is null if no - // address with the module index was requested, and otherwise a boolean that - // says whether the symbol server had symbols for this library. - [key: string]: null | boolean; -}; +// Valibot schemas for API response validation -type APIInlineFrameInfoV5 = { +// For every requested library in the memoryMap, this object contains a string +// key of the form `${debugName}/${breakpadId}`. The value is null if no +// address with the module index was requested, and otherwise a boolean that +// says whether the symbol server had symbols for this library. +const APIFoundModulesV5Schema = v.record(v.string(), v.nullable(v.boolean())); + +// Information about functions that were inlined at this address. +const APIInlineFrameInfoV5Schema = v.object({ // The name of the function this inline frame was in, if known. - function?: string; + function: v.optional(v.string()), // The path of the file that contains the function this inline frame was in, optional. - file?: string; + file: v.optional(v.string()), // The line number that contains the source code for this inline frame that // contributed to the instruction at the looked-up address, optional. // e.g. 543 - line?: number; -}; + line: v.optional(v.number()), +}); -type APIFrameInfoV5 = { +const APIFrameInfoV5Schema = v.object({ // The hex version of the address that we requested (e.g. "0x5ab"). - module_offset: string; + module_offset: v.string(), // The debugName of the library that this frame was in. - module: string; + module: v.string(), // The index of this APIFrameInfo in its enclosing APIStack. - frame: number; + frame: v.number(), // The name of the function this frame was in, if symbols were found. - function?: string; + function: v.optional(v.string()), // The hex offset between the requested address and the start of the function, // e.g. "0x3c". - function_offset?: string; + function_offset: v.optional(v.string()), // An optional size, in bytes, of the machine code of the outer function that // this address belongs to, as a hex string, e.g. "0x270". - function_size?: string; + function_size: v.optional(v.string()), // The path of the file that contains the function this frame was in, optional. - // As of June 2021, this is only supported on the staging symbolication server - // ("Eliot") but not on the implementation that's currently in production ("Tecken"). - // e.g. "hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:24938c537a55f9db3913072d33b178b210e7d6b5" - file?: string; + file: v.optional(v.string()), // The line number that contains the source code that generated the instructions at the address, optional. - // (Same support as file.) - // e.g. 543 - line?: number; + line: v.optional(v.number()), // Information about functions that were inlined at this address. // Ordered from inside to outside. - // As of November 2021, this is only supported by profiler-symbol-server. - // Adding this functionality to the Mozilla symbol server is tracked in - // https://bugzilla.mozilla.org/show_bug.cgi?id=1636194 - inlines?: APIInlineFrameInfoV5[]; -}; + inlines: v.optional(v.array(APIInlineFrameInfoV5Schema)), +}); -type APIStackV5 = APIFrameInfoV5[]; +const APIStackV5Schema = v.array(APIFrameInfoV5Schema); -type APIJobResultV5 = { - found_modules: APIFoundModulesV5; - stacks: APIStackV5[]; -}; +const APIJobResultV5Schema = v.object({ + found_modules: APIFoundModulesV5Schema, + stacks: v.array(APIStackV5Schema), +}); -type APIResultV5 = { - results: APIJobResultV5[]; -}; +const APIResultV5Schema = v.object({ + results: v.array(APIJobResultV5Schema), +}); -// Make sure that the JSON blob we receive from the API conforms to our flow -// type definition. -function _ensureIsAPIResultV5(result: unknown): APIResultV5 { - // It's possible (especially when running tests with Jest) that the parameter - // inherits from a `Object` global from another realm. By using toString - // this issue is solved wherever the parameter comes from. - const isObject = (subject: unknown) => - Object.prototype.toString.call(subject) === '[object Object]'; +type APIJobResultV5 = v.InferOutput; +type APIResultV5 = v.InferOutput; - if (!isObject(result) || !('results' in (result as object))) { - throw new Error('Expected an object with property `results`'); - } - const results = (result as { results: unknown }).results; - if (!Array.isArray(results)) { - throw new Error('Expected `results` to be an array'); - } - for (const jobResult of results) { - if ( - !isObject(jobResult) || - !('found_modules' in jobResult) || - !('stacks' in jobResult) - ) { - throw new Error( - 'Expected jobResult to have `found_modules` and `stacks` properties' - ); - } - const found_modules = jobResult.found_modules; - if (!isObject(found_modules)) { - throw new Error('Expected `found_modules` to be an object'); - } - const stacks = jobResult.stacks; - if (!Array.isArray(stacks)) { - throw new Error('Expected `stacks` to be an array'); - } - for (const stack of stacks) { - if (!Array.isArray(stack)) { - throw new Error('Expected `stack` to be an array'); - } - for (const frameInfo of stack) { - if (!isObject(frameInfo)) { - throw new Error('Expected `frameInfo` to be an object'); - } - if ( - !('module_offset' in frameInfo) || - !('module' in frameInfo) || - !('frame' in frameInfo) - ) { - throw new Error( - 'Expected frameInfo to have `module_offset`, `module` and `frame` properties' - ); - } - if ('file' in frameInfo && typeof frameInfo.file !== 'string') { - throw new Error('Expected frameInfo.file to be a string, if present'); - } - if ('line' in frameInfo && typeof frameInfo.line !== 'number') { - throw new Error('Expected frameInfo.line to be a number, if present'); - } - if ( - 'function_offset' in frameInfo && - typeof frameInfo.function_offset !== 'string' - ) { - throw new Error( - 'Expected frameInfo.function_offset to be a string, if present' - ); - } - if ( - 'function_size' in frameInfo && - typeof frameInfo.function_size !== 'string' - ) { - throw new Error( - 'Expected frameInfo.function_size to be a string, if present' - ); - } - if ('inlines' in frameInfo) { - const inlines = frameInfo.inlines; - if (!Array.isArray(inlines)) { - throw new Error('Expected `inlines` to be an array'); - } - for (const inlineFrame of inlines) { - if (!isObject(inlineFrame)) { - throw new Error('Expected `inlineFrame` to be an object'); - } - } - } - } - } - } - return result as APIResultV5; +// Make sure that the JSON blob we receive from the API conforms to our +// type definition using valibot validation. +function _ensureIsAPIResultV5(result: unknown): APIResultV5 { + return v.parse(APIResultV5Schema, result); } function getV5ResultForLibRequest( diff --git a/src/test/store/receive-profile.test.ts b/src/test/store/receive-profile.test.ts index bd0d50cdea..b00a183beb 100644 --- a/src/test/store/receive-profile.test.ts +++ b/src/test/store/receive-profile.test.ts @@ -937,7 +937,7 @@ describe('actions/receive-profile', function () { expect.objectContaining({ message: 'Could not obtain symbols for libxul/SOMETHING_FAKE.\n' + - ' - Error: There was a problem with the symbolication API request to the symbol server: Expected an object with property `results`\n' + + ' - Error: There was a problem with the symbolication API request to the symbol server: Invalid key: Expected "results" but received undefined\n' + ' - Error: No connection to the browser, cannot run querySymbolicationApi\n' + ' - Error: No connection to the browser, cannot obtain symbol tables', }) diff --git a/yarn.lock b/yarn.lock index 19562f3188..32107d4a08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12311,6 +12311,11 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +valibot@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/valibot/-/valibot-1.1.0.tgz#873bb1af9e1577391690307bfe0520bd1360ec2d" + integrity sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw== + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" From b76dc8ca537cb96ce31ae4d127d41416f7b80c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Fri, 7 Nov 2025 17:41:00 +0100 Subject: [PATCH 44/61] Make sure to fetch the full git history for l10n-sync job in CI (#5667) It looks like the l10n-sync job has failed in CI this morning. I believe this is because of a difference between CircleCI and GitHub Actions `actions/checkout@v5` action. It looks like the GitHub action does a shallow clone [since v4](https://github.com/actions/checkout#:~:text=Only,events), but CircleCI was doing a full clone. We need the full history to be able to do some git operations inside the l10n-sync.js script. `fetch-depth: 0` makes sure to fetch the full history for this task. --- .github/workflows/l10n-sync.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/l10n-sync.yml b/.github/workflows/l10n-sync.yml index 76a942e8f0..b38183aea0 100644 --- a/.github/workflows/l10n-sync.yml +++ b/.github/workflows/l10n-sync.yml @@ -28,6 +28,9 @@ jobs: uses: actions/checkout@v5 with: ssh-key: ${{ secrets.L10N_SYNC_SSH_KEY }} + # Fetch the full git history since we are going to need it to do some + # git operations between the main and l10n branches. + fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v6 From 2b874245cba83f8eafb39ed09085062f5ec66c6a Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 8 Nov 2025 08:31:59 +0000 Subject: [PATCH 45/61] Pontoon/Firefox Profiler: Update Chinese (Taiwan) (zh-TW) Co-authored-by: Pin-guang Chen (zh-TW) --- locales/zh-TW/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/zh-TW/app.ftl b/locales/zh-TW/app.ftl index 4358a6e6a0..af2f33ef56 100644 --- a/locales/zh-TW/app.ftl +++ b/locales/zh-TW/app.ftl @@ -441,6 +441,8 @@ MenuButtons--metaInfo--profiling-started = 紀錄開始於: MenuButtons--metaInfo--profiling-session = 紀錄長度: MenuButtons--metaInfo--main-process-started = 主處理程序開始: MenuButtons--metaInfo--main-process-ended = 主要處理程序結束於: +MenuButtons--metaInfo--file-name = 檔案名稱: +MenuButtons--metaInfo--file-size = 檔案大小: MenuButtons--metaInfo--interval = 間隔: MenuButtons--metaInfo--buffer-capacity = 緩衝區容量: MenuButtons--metaInfo--buffer-duration = 緩衝區長度: From 670371f781bafadcfc8309b69f7a8f949bec76ad Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 8 Nov 2025 08:41:54 +0000 Subject: [PATCH 46/61] Pontoon/Firefox Profiler: Update German (de) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Köhler (de) --- locales/de/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/de/app.ftl b/locales/de/app.ftl index 96b76cc3a2..6861b370e6 100644 --- a/locales/de/app.ftl +++ b/locales/de/app.ftl @@ -513,6 +513,8 @@ MenuButtons--metaInfo--profiling-started = Aufzeichnungsbeginn: MenuButtons--metaInfo--profiling-session = Aufzeichnungslänge: MenuButtons--metaInfo--main-process-started = Hauptprozess gestartet: MenuButtons--metaInfo--main-process-ended = Hauptprozess beendet: +MenuButtons--metaInfo--file-name = Dateiname: +MenuButtons--metaInfo--file-size = Dateigröße: MenuButtons--metaInfo--interval = Intervall: MenuButtons--metaInfo--buffer-capacity = Pufferkapazität: MenuButtons--metaInfo--buffer-duration = Pufferdauer: From dcdf6006f322d5dc5bdca91012ab7806fa8a979e Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 8 Nov 2025 09:02:46 +0000 Subject: [PATCH 47/61] Pontoon/Firefox Profiler: Update Swedish (sv-SE) Co-authored-by: Andreas Pettersson (sv-SE) --- locales/sv-SE/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/sv-SE/app.ftl b/locales/sv-SE/app.ftl index 1419fec85b..3d219db975 100644 --- a/locales/sv-SE/app.ftl +++ b/locales/sv-SE/app.ftl @@ -532,6 +532,8 @@ MenuButtons--metaInfo--profiling-started = Inspelningen startade: MenuButtons--metaInfo--profiling-session = Inspelningslängd: MenuButtons--metaInfo--main-process-started = Huvudprocessen startade: MenuButtons--metaInfo--main-process-ended = Huvudprocessen avslutad: +MenuButtons--metaInfo--file-name = Filnamn: +MenuButtons--metaInfo--file-size = Filstorlek: MenuButtons--metaInfo--interval = Intervall: MenuButtons--metaInfo--buffer-capacity = Buffertkapacitet: MenuButtons--metaInfo--buffer-duration = Buffertlängd: From c30cafcd2ef7d2200570c454481137e436d305c5 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 8 Nov 2025 09:21:55 +0000 Subject: [PATCH 48/61] Pontoon/Firefox Profiler: Update Interlingua (ia) Co-authored-by: Melo46 (ia) --- locales/ia/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/ia/app.ftl b/locales/ia/app.ftl index 84538dfe33..99a8617407 100644 --- a/locales/ia/app.ftl +++ b/locales/ia/app.ftl @@ -522,6 +522,8 @@ MenuButtons--metaInfo--profiling-started = Registration comenciate: MenuButtons--metaInfo--profiling-session = Durata de registration MenuButtons--metaInfo--main-process-started = Processo principal initiate: MenuButtons--metaInfo--main-process-ended = Processo principal finite: +MenuButtons--metaInfo--file-name = Nomine del file: +MenuButtons--metaInfo--file-size = Dimension de file: MenuButtons--metaInfo--interval = Intervallo: MenuButtons--metaInfo--buffer-capacity = Capacitate de buffer: MenuButtons--metaInfo--buffer-duration = Capacitate de buffer: From e21777237d9b578de2981013b0af9ea3f57da033 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 8 Nov 2025 09:51:52 +0000 Subject: [PATCH 49/61] Pontoon/Firefox Profiler: Update Italian (it) Co-authored-by: Francesco Lodolo [:flod] (it) --- locales/it/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/it/app.ftl b/locales/it/app.ftl index 0e00a2c4c6..115c1c7508 100644 --- a/locales/it/app.ftl +++ b/locales/it/app.ftl @@ -453,6 +453,8 @@ MenuButtons--metaInfo--profiling-started = Registrazione avviata: MenuButtons--metaInfo--profiling-session = Lunghezza registrazione: MenuButtons--metaInfo--main-process-started = Processo principale avviato: MenuButtons--metaInfo--main-process-ended = Processo principale completato: +MenuButtons--metaInfo--file-name = Nome file: +MenuButtons--metaInfo--file-size = Dimensione file: MenuButtons--metaInfo--interval = Intervallo: MenuButtons--metaInfo--buffer-capacity = Capacità buffer: MenuButtons--metaInfo--buffer-duration = Durata buffer: From 8c0226a2b62d8349c0c38cd488429f767573c1d7 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sat, 8 Nov 2025 19:51:47 +0000 Subject: [PATCH 50/61] Pontoon/Firefox Profiler: Update Russian (ru) Co-authored-by: Valery Ledovskoy (ru) --- locales/ru/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/ru/app.ftl b/locales/ru/app.ftl index d42c3596a0..cc5ad1d8b8 100644 --- a/locales/ru/app.ftl +++ b/locales/ru/app.ftl @@ -545,6 +545,8 @@ MenuButtons--metaInfo--profiling-started = Запись началась: MenuButtons--metaInfo--profiling-session = Длина записи: MenuButtons--metaInfo--main-process-started = Основной процесс запущен: MenuButtons--metaInfo--main-process-ended = Основной процесс завершен: +MenuButtons--metaInfo--file-name = Имя файла: +MenuButtons--metaInfo--file-size = Размер файла: MenuButtons--metaInfo--interval = Интервал: MenuButtons--metaInfo--buffer-capacity = Емкость буфера: MenuButtons--metaInfo--buffer-duration = Длительность буфера: From e1ac387ee4db39795e6c708feb06b8ccd12da4bd Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sun, 9 Nov 2025 01:12:24 +0000 Subject: [PATCH 51/61] Pontoon/Firefox Profiler: Update English (Great Britain) (en-GB) Co-authored-by: Ian Neal (en-GB) --- locales/en-GB/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/en-GB/app.ftl b/locales/en-GB/app.ftl index 33a6577884..931cae3497 100644 --- a/locales/en-GB/app.ftl +++ b/locales/en-GB/app.ftl @@ -537,6 +537,8 @@ MenuButtons--metaInfo--profiling-started = Recording started: MenuButtons--metaInfo--profiling-session = Recording length: MenuButtons--metaInfo--main-process-started = Main process started: MenuButtons--metaInfo--main-process-ended = Main process ended: +MenuButtons--metaInfo--file-name = File name: +MenuButtons--metaInfo--file-size = File size: MenuButtons--metaInfo--interval = Interval: MenuButtons--metaInfo--buffer-capacity = Buffer Capacity: MenuButtons--metaInfo--buffer-duration = Buffer Duration: From dd195388754949c5ea7871da10125aeb63c4e481 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sun, 9 Nov 2025 14:11:59 +0000 Subject: [PATCH 52/61] Pontoon/Firefox Profiler: Update Portuguese (Brazil) (pt-BR) Co-authored-by: Marcelo Ghelman (pt-BR) --- locales/pt-BR/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/pt-BR/app.ftl b/locales/pt-BR/app.ftl index de6ce28540..fb19db7a7c 100644 --- a/locales/pt-BR/app.ftl +++ b/locales/pt-BR/app.ftl @@ -460,6 +460,8 @@ MenuButtons--metaInfo--profiling-started = Gravação iniciada: MenuButtons--metaInfo--profiling-session = Duração da gravação: MenuButtons--metaInfo--main-process-started = Processo principal iniciado: MenuButtons--metaInfo--main-process-ended = Processo principal finalizado: +MenuButtons--metaInfo--file-name = Nome do arquivo: +MenuButtons--metaInfo--file-size = Tamanho do arquivo: MenuButtons--metaInfo--interval = Intervalo: MenuButtons--metaInfo--buffer-capacity = Capacidade do buffer: MenuButtons--metaInfo--buffer-duration = Duração do buffer: From dbcc73cc06723e6ef6744685e9b99442654d6d8c Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sun, 9 Nov 2025 19:12:07 +0000 Subject: [PATCH 53/61] Pontoon/Firefox Profiler: Update Greek (el) Co-authored-by: Jim Spentzos (el) --- locales/el/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/el/app.ftl b/locales/el/app.ftl index cab1c85005..f493e6c5d0 100644 --- a/locales/el/app.ftl +++ b/locales/el/app.ftl @@ -532,6 +532,8 @@ MenuButtons--metaInfo--profiling-started = Έναρξη καταγραφής: MenuButtons--metaInfo--profiling-session = Διάρκεια καταγραφής: MenuButtons--metaInfo--main-process-started = Έναρξη κύριας διεργασίας: MenuButtons--metaInfo--main-process-ended = Τέλος κύριας διεργασίας: +MenuButtons--metaInfo--file-name = Όνομα αρχείου: +MenuButtons--metaInfo--file-size = Μέγεθος αρχείου: MenuButtons--metaInfo--interval = Διάστημα: MenuButtons--metaInfo--buffer-capacity = Χωρητικότητα buffer: MenuButtons--metaInfo--buffer-duration = Διάρκεια buffer: From 0dc0200aefa9fd29c718ef097127f1a3b3208e68 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Sun, 9 Nov 2025 19:52:00 +0000 Subject: [PATCH 54/61] Pontoon/Firefox Profiler: Update Russian (ru) Co-authored-by: berry (ru) --- locales/ru/app.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ru/app.ftl b/locales/ru/app.ftl index cc5ad1d8b8..27b4369238 100644 --- a/locales/ru/app.ftl +++ b/locales/ru/app.ftl @@ -836,7 +836,7 @@ TrackContextMenu--hide-all-matching-tracks = Скрыть все совпада # any track. # Variables: # $searchFilter (String) - The search filter string that user enters. -TrackContextMenu--no-results-found = Не найдено результатов для «{ $searchFilter }» +TrackContextMenu--no-results-found = Не найдено результатов по запросу «{ $searchFilter }» # This button appears when hovering a track name and is displayed as an X icon. TrackNameButton--hide-track = .title = Скрыть трек From 6f857be00b00d912f7280153e076adf63ce5aab0 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Mon, 10 Nov 2025 07:41:55 +0000 Subject: [PATCH 55/61] Pontoon/Firefox Profiler: Update Dutch (nl) Co-authored-by: Mark Heijl (nl) --- locales/nl/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/nl/app.ftl b/locales/nl/app.ftl index 39e1029626..2f9cb7d349 100644 --- a/locales/nl/app.ftl +++ b/locales/nl/app.ftl @@ -537,6 +537,8 @@ MenuButtons--metaInfo--profiling-started = Opname gestart: MenuButtons--metaInfo--profiling-session = Opnameduur: MenuButtons--metaInfo--main-process-started = Hoofdproces gestart: MenuButtons--metaInfo--main-process-ended = Hoofdproces beëindigd: +MenuButtons--metaInfo--file-name = Bestandsnaam: +MenuButtons--metaInfo--file-size = Bestandsgrootte: MenuButtons--metaInfo--interval = Interval: MenuButtons--metaInfo--buffer-capacity = Buffercapaciteit: MenuButtons--metaInfo--buffer-duration = Bufferduur: From 0e17a0f542301c23c061201cac1eefbc53218d2d Mon Sep 17 00:00:00 2001 From: Pontoon Date: Mon, 10 Nov 2025 08:32:13 +0000 Subject: [PATCH 56/61] Pontoon/Firefox Profiler: Update French (fr) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Théo Chevalier (fr) --- locales/fr/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/fr/app.ftl b/locales/fr/app.ftl index 73d9d41378..9aca11515e 100644 --- a/locales/fr/app.ftl +++ b/locales/fr/app.ftl @@ -454,6 +454,8 @@ MenuButtons--metaInfo--profiling-started = Enregistrement commencé : MenuButtons--metaInfo--profiling-session = Durée d’enregistrement : MenuButtons--metaInfo--main-process-started = Processus principal démarré : MenuButtons--metaInfo--main-process-ended = Processus principal terminé : +MenuButtons--metaInfo--file-name = Nom du fichier : +MenuButtons--metaInfo--file-size = Taille du fichier : MenuButtons--metaInfo--interval = Intervalle : MenuButtons--metaInfo--buffer-capacity = Capacité de la mémoire tampon : MenuButtons--metaInfo--buffer-duration = Durée de la mémoire tampon : From 6d88ac67f25942ce45ced3903888488e5f7ff398 Mon Sep 17 00:00:00 2001 From: Pontoon Date: Mon, 10 Nov 2025 13:51:58 +0000 Subject: [PATCH 57/61] Pontoon/Firefox Profiler: Update Frisian (fy-NL) Co-authored-by: Fjoerfoks (fy-NL) --- locales/fy-NL/app.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/locales/fy-NL/app.ftl b/locales/fy-NL/app.ftl index 817a69019a..c76008ff97 100644 --- a/locales/fy-NL/app.ftl +++ b/locales/fy-NL/app.ftl @@ -537,6 +537,8 @@ MenuButtons--metaInfo--profiling-started = Opname start: MenuButtons--metaInfo--profiling-session = Opnamedoer: MenuButtons--metaInfo--main-process-started = Haadproses start: MenuButtons--metaInfo--main-process-ended = Haadproses stoppe: +MenuButtons--metaInfo--file-name = Bestânsnamme: +MenuButtons--metaInfo--file-size = Bestânsgrutte: MenuButtons--metaInfo--interval = Ynterfal: MenuButtons--metaInfo--buffer-capacity = Bufferkapasiteit: MenuButtons--metaInfo--buffer-duration = Bufferdoer: From b2facbe5b77b3582e850a6fb2916375ec0d3c7af Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:31:41 +0100 Subject: [PATCH 58/61] =?UTF-8?q?Update=20react-intersection-observer=209.?= =?UTF-8?q?16.0=20=E2=86=92=2010.0.0=20(major)=20(#5652)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index bda6734ad4..97e2ee14e9 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "query-string": "^9.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-intersection-observer": "^9.16.0", + "react-intersection-observer": "^10.0.0", "react-redux": "^9.2.0", "react-splitter-layout": "^4.0.0", "react-transition-group": "^4.4.5", diff --git a/yarn.lock b/yarn.lock index 32107d4a08..ea40e36413 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10135,10 +10135,10 @@ react-dom@^18.3.1: loose-envify "^1.1.0" scheduler "^0.23.2" -react-intersection-observer@^9.16.0: - version "9.16.0" - resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz#7376d54edc47293300961010844d53b273ee0fb9" - integrity sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA== +react-intersection-observer@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-10.0.0.tgz#77613d4e819dd170fbac4821c126c046aab69978" + integrity sha512-JJRgcnFQoVXmbE5+GXr1OS1NDD1gHk0HyfpLcRf0575IbJz+io8yzs4mWVlfaqOQq1FiVjLvuYAdEEcrrCfveg== react-is@^16.13.1: version "16.13.1" From 61a58948db3cae712b5688e181d46784dc7497aa Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:41:45 +0000 Subject: [PATCH 59/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20rimraf=20to?= =?UTF-8?q?=20version=206.1.0=20(#5664)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Nazım Can Altınova --- package.json | 2 +- yarn.lock | 52 ++++++++++++++-------------------------------------- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 97e2ee14e9..4dcae6c4a2 100644 --- a/package.json +++ b/package.json @@ -178,7 +178,7 @@ "postinstall-postinstall": "^2.1.0", "prettier": "^3.6.2", "raw-loader": "^4.0.2", - "rimraf": "^5.0.10", + "rimraf": "^6.1.0", "style-loader": "^4.0.0", "stylelint": "^16.25.0", "stylelint-config-idiomatic-order": "^10.0.0", diff --git a/yarn.lock b/yarn.lock index ea40e36413..8b7f7fb8ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5677,7 +5677,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^10.3.10, glob@^10.3.7: +glob@^10.3.10: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== @@ -9324,10 +9324,10 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -package-json-from-dist@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" - integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== +package-json-from-dist@^1.0.0, package-json-from-dist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== package-json@^8.1.0: version "8.1.0" @@ -10662,12 +10662,13 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== -rimraf@^5.0.10: - version "5.0.10" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.10.tgz#23b9843d3dc92db71f96e1a2ce92e39fd2a8221c" - integrity sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ== +rimraf@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.1.0.tgz#b9168360a26e10ffaca0c8b803f47069f99ca47e" + integrity sha512-DxdlA1bdNzkZK7JiNWH+BAx1x4tEJWoTofIopFo6qWUU94jYrFZ0ubY05TqH3nWPJ1nKa1JWVFDINZ3fnrle/A== dependencies: - glob "^10.3.7" + glob "^11.0.3" + package-json-from-dist "^1.0.1" rollup@^2.43.1: version "2.79.2" @@ -11258,16 +11259,7 @@ string-length@^4.0.2: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -11389,7 +11381,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11403,13 +11395,6 @@ strip-ansi@^0.3.0: dependencies: ansi-regex "^0.2.1" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -12887,16 +12872,7 @@ workbox-window@7.3.0, workbox-window@^7.3.0: "@types/trusted-types" "^2.0.2" workbox-core "7.3.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From 1074767ed781d7b1bac70a993033406f465db60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Wed, 12 Nov 2025 19:16:56 +0100 Subject: [PATCH 60/61] Do not switch to call tree when clicking the activity graph while on sample based panels (#5672) --- src/reducers/app.ts | 6 +++++- src/reducers/url-state.ts | 6 +++++- src/test/components/ThreadActivityGraph.test.tsx | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/reducers/app.ts b/src/reducers/app.ts index d3cff8785e..5c3653dfd9 100644 --- a/src/reducers/app.ts +++ b/src/reducers/app.ts @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { combineReducers } from 'redux'; -import { tabSlugs } from '../app-logic/tabs-handling'; +import { tabSlugs, tabsShowingSampleData } from '../app-logic/tabs-handling'; import type { TabSlug } from '../app-logic/tabs-handling'; import type { BrowserConnectionStatus } from '../app-logic/browser-connection'; @@ -170,6 +170,10 @@ const lastVisibleThreadTabSlug: Reducer = ( } return state; case 'FOCUS_CALL_TREE': + if (tabsShowingSampleData.includes(state)) { + // Don't switch to call tree if the tab is already showing sample data. + return state; + } return 'calltree'; default: return state; diff --git a/src/reducers/url-state.ts b/src/reducers/url-state.ts index 2813575b15..bebe69468d 100644 --- a/src/reducers/url-state.ts +++ b/src/reducers/url-state.ts @@ -5,7 +5,7 @@ import { combineReducers } from 'redux'; import { oneLine } from 'common-tags'; import { objectEntries } from '../utils/types'; -import { tabSlugs } from '../app-logic/tabs-handling'; +import { tabSlugs, tabsShowingSampleData } from '../app-logic/tabs-handling'; import type { ThreadIndex, @@ -98,6 +98,10 @@ const selectedTab: Reducer = (state = 'calltree', action) => { case 'CHANGE_TAB_FILTER': return action.selectedTab; case 'FOCUS_CALL_TREE': + if (tabsShowingSampleData.includes(state)) { + // Don't switch to call tree if the tab is already showing sample data. + return state; + } return 'calltree'; default: return state; diff --git a/src/test/components/ThreadActivityGraph.test.tsx b/src/test/components/ThreadActivityGraph.test.tsx index a7d83f7cf6..48ceb4a170 100644 --- a/src/test/components/ThreadActivityGraph.test.tsx +++ b/src/test/components/ThreadActivityGraph.test.tsx @@ -264,7 +264,7 @@ describe('ThreadActivityGraph', function () { expect(getCallNodePath()).toEqual([]); }); - it('when clicking a stack, this selects the call tree panel', function () { + it('when clicking a stack while on a tab that does not show sample data, this selects the call tree panel', function () { const { dispatch, getState, clickActivityGraph } = setup(); expect(getSelectedTab(getState())).toBe('calltree'); @@ -277,6 +277,19 @@ describe('ThreadActivityGraph', function () { expect(getLastVisibleThreadTabSlug(getState())).toBe('calltree'); }); + it('when clicking a stack while on a tab that shows sample data, it should not change the selected panel', function () { + const { dispatch, getState, clickActivityGraph } = setup(); + + expect(getSelectedTab(getState())).toBe('calltree'); + dispatch(changeSelectedTab('flame-graph')); + + // The full call node at this sample is: + // A -> B -> C -> F -> G + clickActivityGraph(1, 0.2); + expect(getSelectedTab(getState())).toBe('flame-graph'); + expect(getLastVisibleThreadTabSlug(getState())).toBe('flame-graph'); + }); + it(`when clicking outside of the graph, this doesn't select the call tree panel`, function () { const { dispatch, getState, clickActivityGraph } = setup(); From 79cd96d14cb2bd23fc2634bec21d557b90285b8a Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:54:21 +0100 Subject: [PATCH 61/61] Update all Yarn dependencies (2025-11-12) (#5673) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Nazım Can Altınova --- package.json | 10 +-- yarn.lock | 192 +++++++++++++++++++++++++-------------------------- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index 4dcae6c4a2..e5a4616f09 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "@babel/preset-env": "^7.28.5", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", - "@eslint/js": "^9.37.0", + "@eslint/js": "^9.39.1", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", @@ -123,7 +123,7 @@ "@types/common-tags": "^1.8.4", "@types/jest": "^30.0.0", "@types/minimist": "^1.2.5", - "@types/node": "^22.19.0", + "@types/node": "^22.19.1", "@types/query-string": "^6.3.0", "@types/react": "^18.3.26", "@types/react-dom": "^18.3.1", @@ -144,9 +144,9 @@ "copy-webpack-plugin": "^13.0.1", "cross-env": "^10.1.0", "css-loader": "^7.1.2", - "cssnano": "^7.1.1", + "cssnano": "^7.1.2", "devtools-license-check": "^0.9.0", - "eslint": "^9.37.0", + "eslint": "^9.39.1", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.32.0", @@ -160,7 +160,7 @@ "fetch-mock": "^12.5.5", "file-loader": "^6.2.0", "glob": "^11.0.3", - "globals": "^16.4.0", + "globals": "^16.5.0", "html-webpack-plugin": "^5.6.4", "husky": "^4.3.8", "jest": "^30.2.0", diff --git a/yarn.lock b/yarn.lock index 8b7f7fb8ab..a55afd6ac2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1217,26 +1217,26 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== -"@eslint/config-array@^0.21.0": - version "0.21.0" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.0.tgz#abdbcbd16b124c638081766392a4d6b509f72636" - integrity sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ== +"@eslint/config-array@^0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.1.tgz#7d1b0060fea407f8301e932492ba8c18aff29713" + integrity sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA== dependencies: - "@eslint/object-schema" "^2.1.6" + "@eslint/object-schema" "^2.1.7" debug "^4.3.1" minimatch "^3.1.2" -"@eslint/config-helpers@^0.4.0": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.1.tgz#7d173a1a35fe256f0989a0fdd8d911ebbbf50037" - integrity sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw== +"@eslint/config-helpers@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz#1bd006ceeb7e2e55b2b773ab318d300e1a66aeda" + integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw== dependencies: - "@eslint/core" "^0.16.0" + "@eslint/core" "^0.17.0" -"@eslint/core@^0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.16.0.tgz#490254f275ba9667ddbab344f4f0a6b7a7bd7209" - integrity sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q== +"@eslint/core@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.17.0.tgz#77225820413d9617509da9342190a2019e78761c" + integrity sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ== dependencies: "@types/json-schema" "^7.0.15" @@ -1255,22 +1255,22 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.37.0", "@eslint/js@^9.37.0": - version "9.37.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.37.0.tgz#0cfd5aa763fe5d1ee60bedf84cd14f54bcf9e21b" - integrity sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg== +"@eslint/js@9.39.1", "@eslint/js@^9.39.1": + version "9.39.1" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.1.tgz#0dd59c3a9f40e3f1882975c321470969243e0164" + integrity sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw== -"@eslint/object-schema@^2.1.6": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" - integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== +"@eslint/object-schema@^2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad" + integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== -"@eslint/plugin-kit@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz#f6a245b42886abf6fc9c7ab7744a932250335ab2" - integrity sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A== +"@eslint/plugin-kit@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz#9779e3fd9b7ee33571a57435cf4335a1794a6cb2" + integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA== dependencies: - "@eslint/core" "^0.16.0" + "@eslint/core" "^0.17.0" levn "^0.4.1" "@firefox-devtools/react-contextmenu@^5.2.3": @@ -2313,10 +2313,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.19.0": - version "22.19.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.0.tgz#849606ef3920850583a4e7ee0930987c35ad80be" - integrity sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA== +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^22.19.1": + version "22.19.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.1.tgz#1188f1ddc9f46b4cc3aec76749050b4e1f459b7b" + integrity sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ== dependencies: undici-types "~6.21.0" @@ -4181,26 +4181,26 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^7.0.9: - version "7.0.9" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-7.0.9.tgz#ba778ab7cbec830e4dbcac722443a90fd99ae34e" - integrity sha512-tCD6AAFgYBOVpMBX41KjbvRh9c2uUjLXRyV7KHSIrwHiq5Z9o0TFfUCoM3TwVrRsRteN3sVXGNvjVNxYzkpTsA== +cssnano-preset-default@^7.0.10: + version "7.0.10" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-7.0.10.tgz#4fb6ee962c0852a03084e8c7a4b60fb0e2db45e0" + integrity sha512-6ZBjW0Lf1K1Z+0OKUAUpEN62tSXmYChXWi2NAA0afxEVsj9a+MbcB1l5qel6BHJHmULai2fCGRthCeKSFbScpA== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" css-declaration-sorter "^7.2.0" cssnano-utils "^5.0.1" postcss-calc "^10.1.1" - postcss-colormin "^7.0.4" - postcss-convert-values "^7.0.7" - postcss-discard-comments "^7.0.4" + postcss-colormin "^7.0.5" + postcss-convert-values "^7.0.8" + postcss-discard-comments "^7.0.5" postcss-discard-duplicates "^7.0.2" postcss-discard-empty "^7.0.1" postcss-discard-overridden "^7.0.1" postcss-merge-longhand "^7.0.5" - postcss-merge-rules "^7.0.6" + postcss-merge-rules "^7.0.7" postcss-minify-font-values "^7.0.1" postcss-minify-gradients "^7.0.1" - postcss-minify-params "^7.0.4" + postcss-minify-params "^7.0.5" postcss-minify-selectors "^7.0.5" postcss-normalize-charset "^7.0.1" postcss-normalize-display-values "^7.0.1" @@ -4208,11 +4208,11 @@ cssnano-preset-default@^7.0.9: postcss-normalize-repeat-style "^7.0.1" postcss-normalize-string "^7.0.1" postcss-normalize-timing-functions "^7.0.1" - postcss-normalize-unicode "^7.0.4" + postcss-normalize-unicode "^7.0.5" postcss-normalize-url "^7.0.1" postcss-normalize-whitespace "^7.0.1" postcss-ordered-values "^7.0.2" - postcss-reduce-initial "^7.0.4" + postcss-reduce-initial "^7.0.5" postcss-reduce-transforms "^7.0.1" postcss-svgo "^7.1.0" postcss-unique-selectors "^7.0.4" @@ -4222,12 +4222,12 @@ cssnano-utils@^5.0.1: resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-5.0.1.tgz#f529e9aa0d7930512ca45b9e2ddb8d6b9092eb30" integrity sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg== -cssnano@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-7.1.1.tgz#a24ae8a87ec4129f9a783498402c9cbcb2e9fe25" - integrity sha512-fm4D8ti0dQmFPeF8DXSAA//btEmqCOgAc/9Oa3C1LW94h5usNrJEfrON7b4FkPZgnDEn6OUs5NdxiJZmAtGOpQ== +cssnano@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-7.1.2.tgz#a8a533a8f509d74b2d22e73d80ec1294f65fdc70" + integrity sha512-HYOPBsNvoiFeR1eghKD5C3ASm64v9YVyJB4Ivnl2gqKoQYvjjN/G0rztvKQq8OxocUtC6sjqY8jwYngIB4AByA== dependencies: - cssnano-preset-default "^7.0.9" + cssnano-preset-default "^7.0.10" lilconfig "^3.1.3" csso@^5.0.5: @@ -5037,24 +5037,23 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@^9.37.0: - version "9.37.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.37.0.tgz#ac0222127f76b09c0db63036f4fe289562072d74" - integrity sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig== +eslint@^9.39.1: + version "9.39.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.1.tgz#be8bf7c6de77dcc4252b5a8dcb31c2efff74a6e5" + integrity sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g== dependencies: "@eslint-community/eslint-utils" "^4.8.0" "@eslint-community/regexpp" "^4.12.1" - "@eslint/config-array" "^0.21.0" - "@eslint/config-helpers" "^0.4.0" - "@eslint/core" "^0.16.0" + "@eslint/config-array" "^0.21.1" + "@eslint/config-helpers" "^0.4.2" + "@eslint/core" "^0.17.0" "@eslint/eslintrc" "^3.3.1" - "@eslint/js" "9.37.0" - "@eslint/plugin-kit" "^0.4.0" + "@eslint/js" "9.39.1" + "@eslint/plugin-kit" "^0.4.1" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" "@types/estree" "^1.0.6" - "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.6" @@ -5762,10 +5761,10 @@ globals@^14.0.0: resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== -globals@^16.4.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-16.4.0.tgz#574bc7e72993d40cf27cf6c241f324ee77808e51" - integrity sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw== +globals@^16.5.0: + version "16.5.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-16.5.0.tgz#ccf1594a437b97653b2be13ed4d8f5c9f850cac1" + integrity sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ== globalthis@^1.0.4: version "1.0.4" @@ -9619,28 +9618,28 @@ postcss-calc@^10.1.1: postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" -postcss-colormin@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-7.0.4.tgz#12b5ed701bc860d58e5267a51679415939563bdb" - integrity sha512-ziQuVzQZBROpKpfeDwmrG+Vvlr0YWmY/ZAk99XD+mGEBuEojoFekL41NCsdhyNUtZI7DPOoIWIR7vQQK9xwluw== +postcss-colormin@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-7.0.5.tgz#0c7526289ab3f0daf96a376fd7430fae7258d5cf" + integrity sha512-ekIBP/nwzRWhEMmIxHHbXHcMdzd1HIUzBECaj5KEdLz9DVP2HzT065sEhvOx1dkLjYW7jyD0CngThx6bpFi2fA== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" caniuse-api "^3.0.0" colord "^2.9.3" postcss-value-parser "^4.2.0" -postcss-convert-values@^7.0.7: - version "7.0.7" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-7.0.7.tgz#e24f8118d8f5cb3830dd8841c8a01537b7535293" - integrity sha512-HR9DZLN04Xbe6xugRH6lS4ZQH2zm/bFh/ZyRkpedZozhvh+awAfbA0P36InO4fZfDhvYfNJeNvlTf1sjwGbw/A== +postcss-convert-values@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-7.0.8.tgz#0c599dc29891d47d7b4d6db399c402cf3ba8efc3" + integrity sha512-+XNKuPfkHTCEo499VzLMYn94TiL3r9YqRE3Ty+jP7UX4qjewUONey1t7CG21lrlTLN07GtGM8MqFVp86D4uKJg== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" postcss-value-parser "^4.2.0" -postcss-discard-comments@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-7.0.4.tgz#9aded15cf437d14ee02b7589ee911b780cd73ffb" - integrity sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg== +postcss-discard-comments@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-7.0.5.tgz#0a95aa4d229a021bc441861d4773d57145ee15dd" + integrity sha512-IR2Eja8WfYgN5n32vEGSctVQ1+JARfu4UH8M7bgGh1bC+xI/obsPJXaBpQF7MAByvgwZinhpHpdrmXtvVVlKcQ== dependencies: postcss-selector-parser "^7.1.0" @@ -9676,12 +9675,12 @@ postcss-merge-longhand@^7.0.5: postcss-value-parser "^4.2.0" stylehacks "^7.0.5" -postcss-merge-rules@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-7.0.6.tgz#f5a0cabf6423b1370ba76d5363dfe44776f1e619" - integrity sha512-2jIPT4Tzs8K87tvgCpSukRQ2jjd+hH6Bb8rEEOUDmmhOeTcqDg5fEFK8uKIu+Pvc3//sm3Uu6FRqfyv7YF7+BQ== +postcss-merge-rules@^7.0.7: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-7.0.7.tgz#f49537e5029ce0e655c2f31fdb205f14575c7334" + integrity sha512-njWJrd/Ms6XViwowaaCc+/vqhPG3SmXn725AGrnl+BgTuRPEacjiLEaGq16J6XirMJbtKkTwnt67SS+e2WGoew== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" caniuse-api "^3.0.0" cssnano-utils "^5.0.1" postcss-selector-parser "^7.1.0" @@ -9702,12 +9701,12 @@ postcss-minify-gradients@^7.0.1: cssnano-utils "^5.0.1" postcss-value-parser "^4.2.0" -postcss-minify-params@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-7.0.4.tgz#665848c0674c5ff59e054e63e052339738cbc6a3" - integrity sha512-3OqqUddfH8c2e7M35W6zIwv7jssM/3miF9cbCSb1iJiWvtguQjlxZGIHK9JRmc8XAKmE2PFGtHSM7g/VcW97sw== +postcss-minify-params@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-7.0.5.tgz#4a0d15e312252e41d0c8504227d43538e3f607a2" + integrity sha512-FGK9ky02h6Ighn3UihsyeAH5XmLEE2MSGH5Tc4tXMFtEDx7B+zTG6hD/+/cT+fbF7PbYojsmmWjyTwFwW1JKQQ== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" cssnano-utils "^5.0.1" postcss-value-parser "^4.2.0" @@ -9787,12 +9786,12 @@ postcss-normalize-timing-functions@^7.0.1: dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.4.tgz#9fd8d1d1e931b60ed946556e4d657b5879e3ee00" - integrity sha512-LvIURTi1sQoZqj8mEIE8R15yvM+OhbR1avynMtI9bUzj5gGKR/gfZFd8O7VMj0QgJaIFzxDwxGl/ASMYAkqO8g== +postcss-normalize-unicode@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.5.tgz#d47a3cc40529d7eeb18d7f7a8a215c38c54455cd" + integrity sha512-X6BBwiRxVaFHrb2WyBMddIeB5HBjJcAaUHyhLrM2FsxSq5TFqcHSsK7Zu1otag+o0ZphQGJewGH1tAyrD0zX1Q== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" postcss-value-parser "^4.2.0" postcss-normalize-url@^7.0.1: @@ -9817,12 +9816,12 @@ postcss-ordered-values@^7.0.2: cssnano-utils "^5.0.1" postcss-value-parser "^4.2.0" -postcss-reduce-initial@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-7.0.4.tgz#ebe8b4c85990efaa5a1accfc77f41f23cfa66187" - integrity sha512-rdIC9IlMBn7zJo6puim58Xd++0HdbvHeHaPgXsimMfG1ijC5A9ULvNLSE0rUKVJOvNMcwewW4Ga21ngyJjY/+Q== +postcss-reduce-initial@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-7.0.5.tgz#cf74bb747dfa003cd3d5372081f6157e6d8e1545" + integrity sha512-RHagHLidG8hTZcnr4FpyMB2jtgd/OcyAazjMhoy5qmWJOx1uxKh4ntk0Pb46ajKM0rkf32lRH4C8c9qQiPR6IA== dependencies: - browserslist "^4.25.1" + browserslist "^4.27.0" caniuse-api "^3.0.0" postcss-reduce-transforms@^7.0.1: @@ -12873,6 +12872,7 @@ workbox-window@7.3.0, workbox-window@^7.3.0: workbox-core "7.3.0" "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==