From dc2db7f6de3b958b7ea7703b0b4ac981217598af Mon Sep 17 00:00:00 2001 From: Chikamatsu Kazuya <43089218+chika3742@users.noreply.github.com> Date: Tue, 24 Mar 2026 00:34:47 +0900 Subject: [PATCH 01/29] fix: Non-ASCII test names being escaped when creating run configurations (#8838) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `StringUtil.escapeProperty()` was incorrectly applied to test names in [`CommonTestConfigUtils.findTestName()`](https://github.com/flutter/flutter-intellij/blob/24d11f2a5b5165dc284df06e982a2b56892b632f/src/io/flutter/run/common/CommonTestConfigUtils.java#L139), converting non-ASCII characters (e.g. Japanese "テスト") to Unicode escape sequences. This caused `flutter test --plain-name` to receive an escaped string that did not match the actual test name, preventing the test from running. Fix by removing the `escapeProperty()` call, which is intended for `.properties` file encoding and is unnecessary here. fixes #7985 --- - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR.
Contribution guidelines:
- See our [contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--------- Co-authored-by: Helin Shiah --- AUTHORS | 1 + CHANGELOG.md | 1 + .../run/common/CommonTestConfigUtils.java | 11 ++++--- .../run/common/CommonTestConfigUtilsTest.java | 33 +++++++++++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 testSrc/unit/io/flutter/run/common/CommonTestConfigUtilsTest.java diff --git a/AUTHORS b/AUTHORS index 8b8de49417..ab420d2175 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,3 +26,4 @@ Mohamed El Sayed Edwin Ludik Japnit Singh Dmitry Kandalov +Kazuya Chikamatsu diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f30b06d4d..b4a40d02ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Fixed - Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and migrating configuration logic to `FlutterInitializer`. (#8845) +- Gutter buttons not running tests with non-ASCII characters in their names. (#7985) ## 90.0.0 diff --git a/src/io/flutter/run/common/CommonTestConfigUtils.java b/src/io/flutter/run/common/CommonTestConfigUtils.java index ba5f72d821..7e54278331 100644 --- a/src/io/flutter/run/common/CommonTestConfigUtils.java +++ b/src/io/flutter/run/common/CommonTestConfigUtils.java @@ -130,13 +130,16 @@ public String findTestName(@Nullable PsiElement elt) { final DartCallExpression call = findEnclosingTestCall(elt, getTestsFromOutline(elt.getContainingFile())); if (call == null) return null; + return extractTestName(call); + } + + @VisibleForTesting + @Nullable + public String extractTestName(@NotNull DartCallExpression call) { final DartStringLiteralExpression lit = DartSyntax.getArgument(call, 0, DartStringLiteralExpression.class); if (lit == null) return null; - final String name = DartSyntax.unquote(lit); - if (name == null) return null; - - return StringUtil.escapeProperty(name, false); + return DartSyntax.unquote(lit); } /** diff --git a/testSrc/unit/io/flutter/run/common/CommonTestConfigUtilsTest.java b/testSrc/unit/io/flutter/run/common/CommonTestConfigUtilsTest.java new file mode 100644 index 0000000000..2c0bd768fe --- /dev/null +++ b/testSrc/unit/io/flutter/run/common/CommonTestConfigUtilsTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2026 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.run.common; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.LeafPsiElement; +import com.jetbrains.lang.dart.psi.DartCallExpression; +import io.flutter.AbstractDartElementTest; +import io.flutter.dart.DartSyntax; +import io.flutter.run.test.TestConfigUtils; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CommonTestConfigUtilsTest extends AbstractDartElementTest { + @Test + public void extractTestNameShouldNotEscapeNonAscii() throws Exception { + run(() -> { + final PsiElement testKeyword = setUpDartElement( + "main() { test('テスト', () {}); }", "test", LeafPsiElement.class); + final DartCallExpression call = + DartSyntax.findEnclosingFunctionCall(testKeyword, "test"); + assertNotNull(call); + + final String name = TestConfigUtils.getInstance().extractTestName(call); + assertEquals("テスト", name); + }); + } +} From 66bcb11ab38137dd03d9d520e19aca7ad60ab657 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Mon, 23 Mar 2026 10:21:57 -0700 Subject: [PATCH 02/29] Fix reported freeze (#8864) This is to fix an internal freeze report that `close` can take a long time to finish. ``` com.teamdev.jxbrowser.browser.internal.BrowserImpl.close(BrowserImpl.java:779) com.teamdev.jxbrowser.internal.rpc.UniversalServiceConnection.invoke(UniversalServiceConnection.java:183) com.teamdev.jxbrowser.internal.rpc.transport.CommonThreadCallExecutor.execute(CommonThreadCallExecutor.java:29) ==> com.teamdev.jxbrowser.internal.rpc.transport.CommonThreadResponseConsumer.await(CommonThreadResponseConsumer.java:49) <== java.util.concurrent.CountDownLatch.await(Unknown Source) ``` I don't really have a good way to test (e.g. making this part slow), other than to make sure that opening and closing the tool windows remains okay. --- CHANGELOG.md | 1 + .../jxbrowser/EmbeddedBrowserEngine.java | 33 ++++++++++--------- .../flutter/jxbrowser/EmbeddedJxBrowser.java | 14 +++++++- src/io/flutter/view/EmbeddedBrowser.java | 15 +++++---- .../widgetpreview/WidgetPreviewPanel.java | 7 +++- 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4a40d02ec..5dd7877fae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and migrating configuration logic to `FlutterInitializer`. (#8845) - Gutter buttons not running tests with non-ASCII characters in their names. (#7985) +- Freeze from JX Browser close. (#8864) ## 90.0.0 diff --git a/src/io/flutter/jxbrowser/EmbeddedBrowserEngine.java b/src/io/flutter/jxbrowser/EmbeddedBrowserEngine.java index 6198beb332..31277e8b71 100644 --- a/src/io/flutter/jxbrowser/EmbeddedBrowserEngine.java +++ b/src/io/flutter/jxbrowser/EmbeddedBrowserEngine.java @@ -5,10 +5,11 @@ */ package io.flutter.jxbrowser; -import com.intellij.openapi.application.ApplicationListener; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; +import io.flutter.utils.OpenApiUtils; import com.teamdev.jxbrowser.engine.Engine; import com.teamdev.jxbrowser.engine.EngineOptions; import com.teamdev.jxbrowser.engine.PasswordStore; @@ -22,7 +23,7 @@ import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED; import static com.teamdev.jxbrowser.engine.RenderingMode.OFF_SCREEN; -public class EmbeddedBrowserEngine { +public class EmbeddedBrowserEngine implements Disposable { private static final @NotNull Logger LOG = PluginLogger.createLogger(EmbeddedBrowserEngine.class); private final Engine engine; @@ -60,22 +61,22 @@ public EmbeddedBrowserEngine() { } engine = temp; - ApplicationManager.getApplication().addApplicationListener(new ApplicationListener() { - @Override - public boolean canExitApplication() { - try { - if (engine != null && !engine.isClosed()) { - engine.close(); - } + } + + @Override + public void dispose() { + OpenApiUtils.safeExecuteOnPooledThread(() -> { + try { + if (engine != null && !engine.isClosed()) { + engine.close(); } - catch (Exception ex) { - if (FlutterSettings.getInstance().isFilePathLoggingEnabled()) { - LOG.info(ex); - } else { - LOG.info("Exception when closing JX Browser engine: " + ex.getMessage()); - } + } + catch (Exception ex) { + if (FlutterSettings.getInstance().isFilePathLoggingEnabled()) { + LOG.info(ex); + } else { + LOG.info("Exception when closing JX Browser engine: " + ex.getMessage()); } - return true; } }); } diff --git a/src/io/flutter/jxbrowser/EmbeddedJxBrowser.java b/src/io/flutter/jxbrowser/EmbeddedJxBrowser.java index 76cce7bca6..e1d915f206 100644 --- a/src/io/flutter/jxbrowser/EmbeddedJxBrowser.java +++ b/src/io/flutter/jxbrowser/EmbeddedJxBrowser.java @@ -28,6 +28,7 @@ import io.flutter.settings.FlutterSettings; import io.flutter.utils.AsyncUtils; import io.flutter.utils.JxBrowserUtils; +import io.flutter.utils.OpenApiUtils; import io.flutter.utils.ZoomLevelSelector; import io.flutter.view.EmbeddedBrowser; import io.flutter.view.EmbeddedTab; @@ -98,7 +99,18 @@ public void loadUrl(String url) { @Override public void close() { - this.browser.close(); + OpenApiUtils.safeExecuteOnPooledThread(() -> { + try { + this.browser.close(); + } + catch (Exception ex) { + if (FlutterSettings.getInstance().isFilePathLoggingEnabled()) { + LOG.info(ex); + } else { + LOG.info("Exception when closing JX Browser instance: " + ex.getMessage()); + } + } + }); } @Override diff --git a/src/io/flutter/view/EmbeddedBrowser.java b/src/io/flutter/view/EmbeddedBrowser.java index 0bcb847b3a..a5326cc3e9 100644 --- a/src/io/flutter/view/EmbeddedBrowser.java +++ b/src/io/flutter/view/EmbeddedBrowser.java @@ -69,14 +69,15 @@ public void projectClosing(@NotNull Project project) { final Map tabs = windows.get(window); for (final String tabName : tabs.keySet()) { final BrowserTab tab = tabs.get(tabName); - if (tab.embeddedTab != null) { - try { - tab.embeddedTab.close(); + final EmbeddedTab embeddedTab = tab.embeddedTab; + if (embeddedTab != null) { + try { + embeddedTab.close(); + } + catch (Exception ex) { + logger().info(ex); + } } - catch (Exception ex) { - logger().info(ex); - } - } } tabs.clear(); } diff --git a/src/io/flutter/widgetpreview/WidgetPreviewPanel.java b/src/io/flutter/widgetpreview/WidgetPreviewPanel.java index c016fd126e..3f530478cd 100644 --- a/src/io/flutter/widgetpreview/WidgetPreviewPanel.java +++ b/src/io/flutter/widgetpreview/WidgetPreviewPanel.java @@ -264,7 +264,12 @@ public void dispose() { // Dispose the browser tab final EmbeddedTab tab = browserTabRef.getAndSet(null); if (tab != null) { - tab.close(); + try { + tab.close(); + } + catch (Exception ex) { + LOG.info(ex); + } } } } From f98a22a8c7145c7e9a4b2eeffe1dec48271014aa Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 25 Mar 2026 09:54:22 -0700 Subject: [PATCH 03/29] [build] inline dev-build upload in `deploy.sh` (#8868) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the call to `plugin..dart deploy` in favor of a bash implementation inline. Fixes: #8866 . --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- tool/kokoro/deploy.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tool/kokoro/deploy.sh b/tool/kokoro/deploy.sh index dfefc78c4a..9aac60ca14 100755 --- a/tool/kokoro/deploy.sh +++ b/tool/kokoro/deploy.sh @@ -10,6 +10,26 @@ echo "kokoro build start" echo "kokoro build finished" echo "kokoro deploy start" -./bin/plugin deploy --channel=dev + +KOKORO_TOKEN_FILE="${KOKORO_KEYSTORE_DIR}/${FLUTTER_KEYSTORE_ID}_${FLUTTER_KEYSTORE_NAME}" +if [ ! -f "$KOKORO_TOKEN_FILE" ]; then + echo "Error: Keystore token file not found at $KOKORO_TOKEN_FILE" + exit 1 +fi +TOKEN=$(cat "$KOKORO_TOKEN_FILE") + +ZIP_FILE="build/distributions/flutter-intellij-kokoro.zip" +if [ ! -f "$ZIP_FILE" ]; then + echo "Error: Zip file not found at $ZIP_FILE" + exit 1 +fi + +echo "Uploading $ZIP_FILE to JetBrains Marketplace..." +curl -if --fail \ + --header "Authorization: Bearer $TOKEN" \ + -F pluginId=9212 \ + -F file=@"$ZIP_FILE" \ + -F channel=dev \ + https://plugins.jetbrains.com/plugin/uploadPlugin echo "kokoro deploy finished" From dd0088d730b620019ca39f13254cd4f8bf758765 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Tue, 31 Mar 2026 08:31:50 -0700 Subject: [PATCH 04/29] Update sunsetted Flutter SDK versions (#8874) The general rules are: - SDKs that are 2 years old should no longer be supported - SDKs that are 3 months away from not being supported should get a warning. --- src/io/flutter/sdk/FlutterSdkVersion.java | 8 +++---- .../io/flutter/sdk/FlutterSdkVersionTest.java | 21 ++++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/io/flutter/sdk/FlutterSdkVersion.java b/src/io/flutter/sdk/FlutterSdkVersion.java index 975337cee8..5614ad2024 100644 --- a/src/io/flutter/sdk/FlutterSdkVersion.java +++ b/src/io/flutter/sdk/FlutterSdkVersion.java @@ -26,11 +26,11 @@ public final class FlutterSdkVersion implements Comparable { * Note, this is for the Flutter SDK version, not the Dart SDK version, this mapping can be found: * Flutter SDK Release Archive list. *

- * This version was updated last on December 5, 2025. + * This version was updated last on March 26, 2026. */ @VisibleForTesting @NotNull - public static final FlutterSdkVersion MIN_SDK_SUPPORTED = new FlutterSdkVersion("3.16"); + public static final FlutterSdkVersion MIN_SDK_SUPPORTED = new FlutterSdkVersion("3.19.4"); /** * The minimum version of the Flutter SDK that will be supported for 3 more months. A version less than this is either not supported or @@ -39,11 +39,11 @@ public final class FlutterSdkVersion implements Comparable { * Note, this is for the Flutter SDK version, not the Dart SDK version, this mapping can be found: * Flutter SDK Release Archive list. *

- * This version was updated last on December 5, 2025. + * This version was updated last on March 26, 2026. */ @VisibleForTesting @NotNull - public static final FlutterSdkVersion MIN_SDK_WITHOUT_SUNSET_WARNING = new FlutterSdkVersion("3.19.4"); + public static final FlutterSdkVersion MIN_SDK_WITHOUT_SUNSET_WARNING = new FlutterSdkVersion("3.22.2"); @NotNull private static final FlutterSdkVersion MIN_SUPPORTS_TOOL_EVENT_STREAM = new FlutterSdkVersion("3.7.1"); diff --git a/testSrc/unit/io/flutter/sdk/FlutterSdkVersionTest.java b/testSrc/unit/io/flutter/sdk/FlutterSdkVersionTest.java index 0a288e3105..a72f2f39c1 100644 --- a/testSrc/unit/io/flutter/sdk/FlutterSdkVersionTest.java +++ b/testSrc/unit/io/flutter/sdk/FlutterSdkVersionTest.java @@ -18,18 +18,19 @@ public void parsesGoodVersion() { @Test public void trackSdkVersionSupport() { - assertFalse(new FlutterSdkVersion("3.15.0").isSDKSupported()); - assertFalse(new FlutterSdkVersion("3.16.0-0.1.pre").isSDKSupported()); - assertTrue(new FlutterSdkVersion("3.16.0").isSDKSupported()); - assertTrue(new FlutterSdkVersion("3.16.1").isSDKSupported()); - assertTrue(new FlutterSdkVersion("3.17.0").isSDKSupported()); + assertFalse(new FlutterSdkVersion("3.19.3").isSDKSupported()); + assertFalse(new FlutterSdkVersion("3.19.4-0.1.pre").isSDKSupported()); + assertTrue(new FlutterSdkVersion("3.19.4").isSDKSupported()); + assertTrue(new FlutterSdkVersion("3.19.5").isSDKSupported()); + assertTrue(new FlutterSdkVersion("3.20.0").isSDKSupported()); assertFalse(new FlutterSdkVersion("unknown").isSDKSupported()); - assertTrue(new FlutterSdkVersion("3.16.0").isSDKAboutToSunset()); - assertTrue(new FlutterSdkVersion("3.17.0").isSDKAboutToSunset()); - assertTrue(new FlutterSdkVersion("3.19.3").isSDKAboutToSunset()); - assertFalse(new FlutterSdkVersion("3.19.4").isSDKAboutToSunset()); - assertFalse(new FlutterSdkVersion("3.20.0").isSDKAboutToSunset()); + assertTrue(new FlutterSdkVersion("3.19.4").isSDKAboutToSunset()); + assertTrue(new FlutterSdkVersion("3.20.0").isSDKAboutToSunset()); + assertTrue(new FlutterSdkVersion("3.22.0").isSDKAboutToSunset()); + assertTrue(new FlutterSdkVersion("3.22.1").isSDKAboutToSunset()); + assertFalse(new FlutterSdkVersion("3.22.2").isSDKAboutToSunset()); + assertFalse(new FlutterSdkVersion("3.23.0").isSDKAboutToSunset()); } @Test From 76d8e587b3eb622940ce12d164e3c8dbd3d4ede6 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Tue, 31 Mar 2026 17:15:13 -0700 Subject: [PATCH 05/29] Add reflection utility to fix split debugger error (#8878) Fixes https://github.com/flutter/flutter-intellij/issues/8831 There is an API change somewhere in 2025.3 which causes the error to be thrown during debugging. I considered making this a separate plugin branch in https://github.com/flutter/flutter-intellij/pull/8877. To test this change in IntelliJ IDEA 2026.1: - Debug an app - Debug a test - Attach an app (Run menu > Flutter Attach, then start the app on device) - I don't have a way to test bazel code. It should probably be removed. --- .gemini/styleguide.md | 8 +- src/io/flutter/run/AttachState.java | 2 +- .../flutter/run/FlutterDebugSessionUtils.java | 84 +++++++++++++++++++ src/io/flutter/run/LaunchState.java | 18 ++-- .../run/bazelTest/BazelTestRunner.java | 7 +- .../flutter/run/test/FlutterTestRunner.java | 7 +- 6 files changed, 103 insertions(+), 23 deletions(-) create mode 100644 src/io/flutter/run/FlutterDebugSessionUtils.java diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index caf2b51937..c97d94e9fb 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -13,6 +13,8 @@ enforce standard modern Java/Kotlin coding conventions, but strictly police the - `[NIT]`: Idiomatic improvements or minor naming suggestions. - **Focus:** Prioritize logic, performance on the UI thread, and architectural consistency. - **No Empty Praise:** Do not leave "Looks good" or "Nice change" comments. If there are no issues, leave no comments. +- **Copyright Headers:** Ensure all new files have a proper copyright header (e.g., `Copyright 2026 The Chromium Authors`). Flag any missing + headers as `[MUST-FIX]`. ## 2. IntelliJ Platform Best Practices @@ -30,8 +32,10 @@ enforce standard modern Java/Kotlin coding conventions, but strictly police the as recommended by the modern SDK. - **Backward Compatibility:** Avoid using `@ApiStatus.Internal` or `@ApiStatus.ScheduledForRemoval` APIs unless strictly necessary. - **Logging:** - - Reject any use of `System.out.println` or `System.err.println` for logging in `src/` code (integration tests may use them for milestone logging). - - Enforce the use of the IntelliJ SDK's built-in logger (`com.intellij.openapi.diagnostic.Logger`) or our own (`io.flutter.logging.PluginLogger`). + - Reject any use of `System.out.println` or `System.err.println` for logging in `src/` code (integration tests may use them for + milestone logging). + - Enforce the use of the IntelliJ SDK's built-in logger (`com.intellij.openapi.diagnostic.Logger`) or our own ( + `io.flutter.logging.PluginLogger`). - **Actions:** - Classes extending `AnAction` must be completely stateless. Flag any `AnAction` class that defines mutable instance variables (fields), as the platform instantiates a single instance of the action for the lifetime of the IDE. diff --git a/src/io/flutter/run/AttachState.java b/src/io/flutter/run/AttachState.java index fe67d8c2ae..f655fe226e 100644 --- a/src/io/flutter/run/AttachState.java +++ b/src/io/flutter/run/AttachState.java @@ -47,6 +47,6 @@ protected RunContentDescriptor launch(@NotNull ExecutionEnvironment env) throws // Cache for use in console configuration, and for updating registered extensionRPCs. FlutterApp.addToEnvironment(env, app); final ExecutionResult result = setUpConsoleAndActions(app); - return createDebugSession(env, app, result).getRunContentDescriptor(); + return createDebugSession(env, app, result); } } diff --git a/src/io/flutter/run/FlutterDebugSessionUtils.java b/src/io/flutter/run/FlutterDebugSessionUtils.java new file mode 100644 index 0000000000..a41a1971fe --- /dev/null +++ b/src/io/flutter/run/FlutterDebugSessionUtils.java @@ -0,0 +1,84 @@ +/* + * Copyright 2026 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.run; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.xdebugger.XDebugProcessStarter; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +// TODO(helin24): This class is using reflection to find experimental APIs that are only present in platform versions 2025.3+. We should be +// able to use the APIs directly once we are only supporting versions past 2025.3. +// See https://github.com/flutter/flutter-intellij/issues/8879. +public class FlutterDebugSessionUtils { + + private static final Method newSessionBuilderMethod; + private static final Method environmentMethod; + private static final Method startSessionMethod; + + static { + Method nsb = null; + Method env = null; + Method ss = null; + try { + nsb = XDebuggerManager.class.getMethod("newSessionBuilder", XDebugProcessStarter.class); + Class builderClass = nsb.getReturnType(); + env = builderClass.getMethod("environment", ExecutionEnvironment.class); + ss = builderClass.getMethod("startSession"); + } catch (NoSuchMethodException e) { + // Fallback for older platforms + } + newSessionBuilderMethod = nsb; + environmentMethod = env; + startSessionMethod = ss; + } + + public static @NotNull RunContentDescriptor startSessionAndGetDescriptor( + @NotNull XDebuggerManager manager, + @NotNull ExecutionEnvironment env, + @NotNull XDebugProcessStarter starter, + boolean muteBreakpoints) throws ExecutionException { + try { + if (newSessionBuilderMethod == null) { + throw new NoSuchMethodException("newSessionBuilder is not available"); + } + Object builder = newSessionBuilderMethod.invoke(manager, starter); + builder = environmentMethod.invoke(builder, env); + Object sessionResult = startSessionMethod.invoke(builder); + + if (muteBreakpoints) { + Method getSessionMethod = sessionResult.getClass().getMethod("getSession"); + XDebugSession session = (XDebugSession) getSessionMethod.invoke(sessionResult); + session.setBreakpointMuted(true); + } + + Method getDescriptorMethod = sessionResult.getClass().getMethod("getRunContentDescriptor"); + return (RunContentDescriptor) getDescriptorMethod.invoke(sessionResult); + + } catch (NoSuchMethodException e) { + // Fallback to old API for 2025.1 and older + XDebugSession session = manager.startSession(env, starter); + if (muteBreakpoints) { + session.setBreakpointMuted(true); + } + return session.getRunContentDescriptor(); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof ExecutionException) { + throw (ExecutionException) cause; + } + throw new ExecutionException("Failed to start debug session via reflection", cause != null ? cause : e); + } catch (Exception e) { + throw new ExecutionException("Failed with unexpected reflection error", e); + } + } +} diff --git a/src/io/flutter/run/LaunchState.java b/src/io/flutter/run/LaunchState.java index 90a720a0bb..18c8a6581c 100644 --- a/src/io/flutter/run/LaunchState.java +++ b/src/io/flutter/run/LaunchState.java @@ -160,7 +160,7 @@ protected RunContentDescriptor launch(@NotNull ExecutionEnvironment env) throws final RunContentDescriptor descriptor; if (launchMode.supportsDebugConnection()) { ToolWindowBadgeUpdater.updateBadgedIcon(app, project); - descriptor = createDebugSession(env, app, result).getRunContentDescriptor(); + descriptor = createDebugSession(env, app, result); } else { descriptor = new RunContentBuilder(result, env).showRunContent(env.getContentToReuse()); @@ -224,28 +224,22 @@ protected void showNoDeviceConnectedMessage(Project project) { } @NotNull - protected XDebugSession createDebugSession(@NotNull final ExecutionEnvironment env, - @NotNull final FlutterApp app, - @NotNull final ExecutionResult executionResult) + protected RunContentDescriptor createDebugSession(@NotNull final ExecutionEnvironment env, + @NotNull final FlutterApp app, + @NotNull final ExecutionResult executionResult) throws ExecutionException { final DartUrlResolver resolver = DartUrlResolver.getInstance(env.getProject(), sourceLocation); final FlutterPositionMapper mapper = createPositionMapper(env, app, resolver); final XDebuggerManager manager = XDebuggerManager.getInstance(env.getProject()); - final XDebugSession session = manager.startSession(env, new XDebugProcessStarter() { + return FlutterDebugSessionUtils.startSessionAndGetDescriptor(manager, env, new XDebugProcessStarter() { @Override @NotNull public XDebugProcess start(@NotNull final XDebugSession session) { return new FlutterDebugProcess(app, env, session, executionResult, resolver, mapper); } - }); - - if (app.getMode() != RunMode.DEBUG) { - session.setBreakpointMuted(true); - } - - return session; + }, app.getMode() != RunMode.DEBUG); } @NotNull diff --git a/src/io/flutter/run/bazelTest/BazelTestRunner.java b/src/io/flutter/run/bazelTest/BazelTestRunner.java index 7ffa75c510..94bdad13ab 100644 --- a/src/io/flutter/run/bazelTest/BazelTestRunner.java +++ b/src/io/flutter/run/bazelTest/BazelTestRunner.java @@ -45,6 +45,7 @@ import io.flutter.bazel.WorkspaceCache; import io.flutter.logging.PluginLogger; import io.flutter.run.FlutterPositionMapper; +import io.flutter.run.FlutterDebugSessionUtils; import io.flutter.run.common.CommonTestConfigUtils; import io.flutter.run.test.FlutterTestRunner; import io.flutter.settings.FlutterSettings; @@ -100,15 +101,13 @@ protected RunContentDescriptor runInDebugger(@NotNull BazelTestLaunchState launc // Create the debug session. final XDebuggerManager manager = XDebuggerManager.getInstance(env.getProject()); - final XDebugSession session = manager.startSession(env, new XDebugProcessStarter() { + return FlutterDebugSessionUtils.startSessionAndGetDescriptor(manager, env, new XDebugProcessStarter() { @Override @NotNull public XDebugProcess start(@NotNull final XDebugSession session) { return new BazelTestDebugProcess(env, session, executionResult, resolver, connector, mapper); } - }); - - return session.getRunContentDescriptor(); + }, false); } /** diff --git a/src/io/flutter/run/test/FlutterTestRunner.java b/src/io/flutter/run/test/FlutterTestRunner.java index 55c8b1ee77..077b771afc 100644 --- a/src/io/flutter/run/test/FlutterTestRunner.java +++ b/src/io/flutter/run/test/FlutterTestRunner.java @@ -33,6 +33,7 @@ import com.intellij.xdebugger.XDebuggerManager; import com.jetbrains.lang.dart.util.DartUrlResolver; import io.flutter.FlutterUtils; +import io.flutter.run.FlutterDebugSessionUtils; import io.flutter.ObservatoryConnector; import io.flutter.logging.PluginLogger; import io.flutter.run.FlutterPositionMapper; @@ -210,15 +211,13 @@ protected RunContentDescriptor runInDebugger(@NotNull TestLaunchState launcher, // Create the debug session. final XDebuggerManager manager = XDebuggerManager.getInstance(env.getProject()); - final XDebugSession session = manager.startSession(env, new XDebugProcessStarter() { + return FlutterDebugSessionUtils.startSessionAndGetDescriptor(manager, env, new XDebugProcessStarter() { @Override @NotNull public XDebugProcess start(@NotNull final XDebugSession session) { return new TestDebugProcess(env, session, executionResult, resolver, connector, mapper); } - }); - - return session.getRunContentDescriptor(); + }, false); } /** From b0d959eb4f8a68cfddedb4a05b1ebd98f742f9d9 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Wed, 1 Apr 2026 11:39:15 -0700 Subject: [PATCH 06/29] Add missing changelog entries and update version (#8880) --- CHANGELOG.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd7877fae..7ef88f6472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,24 @@ ### Changed -- Updated gradle plugin version to re-enable running `./gradlew verifyPlugin` locally. (#8847) - ### Removed ### Fixed -- Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and migrating configuration logic to `FlutterInitializer`. (#8845) +## 91.0.0 + +### Changed + +- Gradle plugin version to re-enable running `./gradlew verifyPlugin` locally. (#8847) + +### Fixed + +- Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and + migrating configuration logic to `FlutterInitializer`. (#8846) - Gutter buttons not running tests with non-ASCII characters in their names. (#7985) - Freeze from JX Browser close. (#8864) +- Crash in split debugger mode in IntelliJ 2025.3+. (#8831) +- Passing additional arguments from the Flutter test template. (#7261) ## 90.0.0 From e5c96f8858f4390e30b3965e657a43f790ad9451 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Thu, 2 Apr 2026 09:06:44 -0700 Subject: [PATCH 07/29] =?UTF-8?q?Revert=20"Fix=20IntelliJ=20IDEA=20project?= =?UTF-8?q?=20open=20hang=20by=20removing=20FlutterProjec=E2=80=A6=20(#888?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …tOpenProcessor (#8846)" This reverts commit 4681015cd82dfc4b675f7e3471648853238855e3. The problem is seeing the open project dialog (the one below) twice upon creating a new project. Screenshot 2026-04-01 at 8 59 27 PM --- CHANGELOG.md | 2 - resources/META-INF/plugin.xml | 2 + src/io/flutter/FlutterInitializer.java | 14 +-- .../project/FlutterProjectOpenProcessor.kt | 107 ++++++++++++++++++ 4 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 src/io/flutter/project/FlutterProjectOpenProcessor.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ef88f6472..1ec2074e81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,6 @@ ### Fixed -- Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and - migrating configuration logic to `FlutterInitializer`. (#8846) - Gutter buttons not running tests with non-ASCII characters in their names. (#7985) - Freeze from JX Browser close. (#8864) - Crash in split debugger mode in IntelliJ 2025.3+. (#8831) diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 5c943d83d2..0e49834ac7 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -335,6 +335,8 @@ + + diff --git a/src/io/flutter/FlutterInitializer.java b/src/io/flutter/FlutterInitializer.java index 7bc1e41078..cd2621ee4c 100644 --- a/src/io/flutter/FlutterInitializer.java +++ b/src/io/flutter/FlutterInitializer.java @@ -67,6 +67,8 @@ * Runs actions after the project has started up and the index is up to date. * * @see ProjectOpenActivity for actions that run earlier. + * @see io.flutter.project.FlutterProjectOpenProcessor for additional actions that + * may run when a project is being imported. */ public class FlutterInitializer extends FlutterProjectActivity { private boolean toolWindowsInitialized = false; @@ -97,18 +99,6 @@ public void executeProjectStartup(@NotNull Project project) { // Start a DevTools server DevToolsService.getInstance(project); - // Ensure Flutter project configuration is applied for projects that may have been - // opened without a .idea directory. Previously this was handled by FlutterProjectOpenProcessor, - // but that processor silently failed when no delegate processor could open the project. - // Instead, we let the platform open the project normally and apply our configuration here. - // See https://github.com/flutter/flutter-intellij/issues/8661 (Android Studio equivalent) - for (Module module : FlutterModuleUtils.getModules(project)) { - if (FlutterModuleUtils.declaresFlutter(module) && !FlutterModuleUtils.isFlutterModule(module)) { - log().info("Fixing Flutter module configuration for " + module.getName()); - FlutterModuleUtils.setFlutterModuleAndReload(module, project); - } - } - // If the project declares a Flutter dependency, do some extra initialization. boolean hasFlutterModule = false; diff --git a/src/io/flutter/project/FlutterProjectOpenProcessor.kt b/src/io/flutter/project/FlutterProjectOpenProcessor.kt new file mode 100644 index 0000000000..edadecba92 --- /dev/null +++ b/src/io/flutter/project/FlutterProjectOpenProcessor.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2025 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.project + +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.projectImport.ProjectOpenProcessor +import icons.FlutterIcons +import io.flutter.FlutterBundle +import io.flutter.FlutterUtils +import io.flutter.pub.PubRoot +import io.flutter.utils.FlutterModuleUtils +import java.util.* +import javax.swing.Icon + +/** + * Originally `FlutterProjectOpenProcessor.java`. + * + * This processor handles opening Flutter projects when they are selected directly (e.g. via "Open" in the IDE). + * It delegates the actual opening to the platform's default processor (e.g. Gradle or Maven processor if applicable, + * or the generic project opener) and then ensures that any modules in the project are correctly configured as Flutter modules. + * + * Converted to Kotlin to support `openProjectAsync` which is a suspend function. + */ +open class FlutterProjectOpenProcessor : ProjectOpenProcessor() { + override val name: String + get() = FlutterBundle.message("flutter.module.name") + + override fun getIcon(file: VirtualFile): Icon? { + return FlutterIcons.Flutter + } + + override fun canOpenProject(file: VirtualFile): Boolean { + if (FlutterUtils.isAndroidStudio()) { + return false + } + val root = PubRoot.forDirectory(file) + return root != null && root.declaresFlutter() + } + + /** + * Replaces the deprecated `doOpenProject`. + * + * This method is `suspend` and must be used instead of `doOpenProject` to avoid `IllegalStateException` in newer IDE versions. + * + * It performs the following steps: + * 1. Finds a delegate processor (e.g. Gradle) to open the project. + * 2. Opens the project asynchronously. + * 3. Once opened, checks if the project contains Flutter modules that are not yet configured as such (e.g. missing module type). + * 4. Configures these modules as Flutter modules within a write action. + */ + override suspend fun openProjectAsync( + virtualFile: VirtualFile, + projectToClose: Project?, + forceOpenInNewFrame: Boolean, + ): Project? { + // Delegate opening to the platform open processor. + val importProvider = getDelegateImportProvider(virtualFile) ?: return null + val project = importProvider.openProjectAsync(virtualFile, projectToClose, forceOpenInNewFrame) + if (project == null || project.isDisposed) return project + + // Convert any modules that use Flutter but don't have IntelliJ Flutter metadata. + convertToFlutterProject(project) + + return project + } + + /** + * Deprecated method, kept to satisfy the compiler/interface. + * + * We return `null` to indicate that this processor does not support the synchronous opening method + * and that `openProjectAsync` should be used instead. + */ + override fun doOpenProject( + virtualFile: VirtualFile, + projectToClose: Project?, + forceOpenInNewFrame: Boolean, + ): Project? { + return null + } + + protected open fun getDelegateImportProvider(file: VirtualFile): ProjectOpenProcessor? { + return EXTENSION_POINT_NAME.extensionList.stream().filter { processor: ProjectOpenProcessor -> + processor.canOpenProject(file) && !Objects.equals( + processor.name, + name + ) + }.findFirst().orElse(null) + } +} + +/** + * Sets up a project that doesn't have any Flutter modules. + * + * + * (It probably wasn't created with "flutter create" and probably didn't have any IntelliJ configuration before.) + */ +private fun convertToFlutterProject(project: Project) { + for (module in FlutterModuleUtils.getModules(project)) { + if (FlutterModuleUtils.declaresFlutter(module) && !FlutterModuleUtils.isFlutterModule(module)) { + FlutterModuleUtils.setFlutterModuleAndReload(module, project) + } + } +} \ No newline at end of file From c57eba90cd3a886b787148a4c66e2f952e01bcc3 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Thu, 2 Apr 2026 09:10:15 -0700 Subject: [PATCH 08/29] Use PR numbers in changelog, not issue numbers (#8881) --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec2074e81..548a5d4f93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,10 @@ ### Fixed -- Gutter buttons not running tests with non-ASCII characters in their names. (#7985) +- Gutter buttons not running tests with non-ASCII characters in their names. (#8838) - Freeze from JX Browser close. (#8864) -- Crash in split debugger mode in IntelliJ 2025.3+. (#8831) -- Passing additional arguments from the Flutter test template. (#7261) +- Crash in split debugger mode in IntelliJ 2025.3+. (#8878) +- Passing additional arguments from the Flutter test template. (#8836) ## 90.0.0 From 2352bc0c2d007dcc7fcb0f7dc28dff14372feded Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Thu, 2 Apr 2026 09:13:51 -0700 Subject: [PATCH 09/29] Update Dart plugin version (#8886) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 16dbccfb1f..9186e9e84b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ # ideaVersion=2025.2.3.9 -dartPluginVersion= 503.0.0 +dartPluginVersion= 504.0.0 # Also update the versions for verify checks in tool/github.sh. sinceBuild=251 untilBuild=261.* From 27965c3b71e4ba095a643c67681dcd45095b26e3 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 8 Apr 2026 09:34:07 -0700 Subject: [PATCH 10/29] [fix] target device selector updates (#8891) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In #8853, users are reporting an exception in Android Studio thanks to excessive toolbar updates. This is caused by the Flutter plugin triggering frequent global toolbar updates via a call to `ActivityTracker.getInstance().inc()` whenever the device or emulator lists change. **The Fix.** To reduce update frequency, this change makes the updates targeted, removing the (global)`ActivityTracker.getInstance().inc()` calls from `DeviceSelectorAction.updateActions()` and `DeviceService.refreshDeviceDaemon()`, invoking a newly extracted `updateComponent` method in `DeviceSelectorAction` instead. This ensures that the Flutter device selector UI still updates immediately when devices are connected or disconnected, but without forcing a global re-query of all actions on the toolbar. **Verification.** Verified manually and `io.flutter.actions.DeviceSelectorActionTest` still passes. Fixes #8853 --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.

Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- .../flutter/actions/DeviceSelectorAction.java | 52 ++++++++++--------- src/io/flutter/run/daemon/DeviceService.java | 1 - 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/io/flutter/actions/DeviceSelectorAction.java b/src/io/flutter/actions/DeviceSelectorAction.java index 812eb6b31e..c166b116a9 100644 --- a/src/io/flutter/actions/DeviceSelectorAction.java +++ b/src/io/flutter/actions/DeviceSelectorAction.java @@ -6,7 +6,6 @@ package io.flutter.actions; import com.intellij.icons.AllIcons; -import com.intellij.ide.ActivityTracker; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.ActionUpdateThread; import com.intellij.openapi.actionSystem.AnAction; @@ -46,6 +45,7 @@ import io.flutter.run.FlutterDevice; import io.flutter.run.daemon.DeviceService; import io.flutter.sdk.AndroidEmulatorManager; +import io.flutter.utils.AsyncUtils; import io.flutter.utils.FlutterModuleUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -381,14 +381,19 @@ public void projectClosing(@NotNull Project project) { update(project, presentation); } + updateComponent(project, presentation); + } + + private void updateComponent(@NotNull Project project, @NotNull Presentation presentation) { final DeviceService deviceService = DeviceService.getInstance(project); final FlutterDevice selectedDevice = deviceService.getSelectedDevice(); final Collection devices = deviceService.getConnectedDevices(); final String text; - Icon icon = DEFAULT_DEVICE_ICON; + Icon icon; if (devices.isEmpty()) { + icon = DEFAULT_DEVICE_ICON; final boolean isLoading = deviceService.getStatus() == DeviceService.State.LOADING; if (isLoading) { text = FlutterBundle.message("devicelist.loading"); @@ -398,6 +403,7 @@ public void projectClosing(@NotNull Project project) { } } else if (selectedDevice == null) { + icon = DEFAULT_DEVICE_ICON; text = FlutterBundle.message("devicelist.noDeviceSelected"); } else { @@ -412,25 +418,27 @@ else if (selectedDevice == null) { // Update the custom component if it exists final JButton customComponent = presentation.getClientProperty(CUSTOM_COMPONENT_KEY); if (customComponent != null) { - final @Nullable JBLabel iconLabel = (JBLabel)customComponent.getClientProperty(ICON_LABEL_KEY); - final @Nullable JBLabel textLabel = (JBLabel)customComponent.getClientProperty(TEXT_LABEL_KEY); + AsyncUtils.invokeLater(() -> { + final @Nullable JBLabel iconLabel = (JBLabel)customComponent.getClientProperty(ICON_LABEL_KEY); + final @Nullable JBLabel textLabel = (JBLabel)customComponent.getClientProperty(TEXT_LABEL_KEY); - if (iconLabel != null) { - iconLabel.setIcon(icon); - } - if (textLabel != null) { - textLabel.setText(text); - // Update the foreground color to adapt to theme changes. - textLabel.setForeground(getToolbarForegroundColor()); - customComponent.invalidate(); - Container parent = customComponent.getParent(); - while (parent != null) { - parent.invalidate(); - parent = parent.getParent(); + if (iconLabel != null) { + iconLabel.setIcon(icon); } - customComponent.revalidate(); - customComponent.repaint(); - } + if (textLabel != null) { + textLabel.setText(text); + // Update the foreground color to adapt to theme changes. + textLabel.setForeground(getToolbarForegroundColor()); + customComponent.invalidate(); + Container parent = customComponent.getParent(); + while (parent != null) { + parent.invalidate(); + parent = parent.getParent(); + } + customComponent.revalidate(); + customComponent.repaint(); + } + }); } } @@ -447,6 +455,7 @@ private void update(@NotNull Project project, @NotNull Presentation presentation } updateActions(project, presentation); updateVisibility(project, presentation); + updateComponent(project, presentation); } private static void updateVisibility(final Project project, final @NotNull Presentation presentation) { @@ -531,11 +540,6 @@ private void updateActions(@NotNull Project project, @NotNull Presentation prese // Atomically replace the action list LOG.debug("[" + projectName + "] Replacing device selector actions"); this.actions = newActions; - - var tracker = ActivityTracker.getInstance(); - if (tracker != null) { - tracker.inc(); - } } private static class SelectDeviceAction extends AnAction { diff --git a/src/io/flutter/run/daemon/DeviceService.java b/src/io/flutter/run/daemon/DeviceService.java index 72d65e90f9..c2a61c9edd 100644 --- a/src/io/flutter/run/daemon/DeviceService.java +++ b/src/io/flutter/run/daemon/DeviceService.java @@ -191,7 +191,6 @@ private void refreshDeviceDaemon() { if (project.isDisposed()) return; deviceDaemon.refresh(this::chooseNextDaemon); refreshInProgress = false; - ActivityTracker.getInstance().inc(); }); } From cb146148c8e061759ad3211adff8917c608ea1e8 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 9 Apr 2026 16:06:56 -0700 Subject: [PATCH 11/29] [ai] add `.aiconfig` (#8894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verified in vscode. image Fixes: https://github.com/flutter/flutter-intellij/issues/8893 --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- .aiconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .aiconfig diff --git a/.aiconfig b/.aiconfig new file mode 100644 index 0000000000..308e96ff48 --- /dev/null +++ b/.aiconfig @@ -0,0 +1,21 @@ +# Gemini Code Assist Configuration +version: 1.0 +project: + context: + instruction_files: + - .gemini/styleguide.md + + generation_rules: + - "Strictly adhere to the IntelliJ Platform Threading Model: No I/O on the EDT." + - "All generated AnAction classes must be stateless." + - "Apply [MUST-FIX], [CONCERN], and [NIT] severity logic to any code suggestions that violate plugin SDK best practices or style guidelines." + - "Use io.flutter.logging.PluginLogger for all logging; avoid System.out." + - "Always include the standard Chromium Authors copyright header in new files." + - "Adhere to the Zero-Formatting Policy: Do not comment on indentation, spacing, or brace placement." + # Ensure local agents read styleguide files automatically. + - "At the start of the session, read and adhere to the guidelines in all files listed in project.context.instruction_files." + + languages: + - java + - kotlin + - dart \ No newline at end of file From e965bb8d9c339811484643aa2e94a54d698464ab Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Thu, 16 Apr 2026 09:46:09 -0700 Subject: [PATCH 12/29] Fix IDEA project open hang (#8903) Fixes https://github.com/flutter/flutter-intellij/issues/8845. Follows up on https://github.com/flutter/flutter-intellij/pull/8846 which I reverted before the last release because it was causing new projects to prompt the user to open twice (at least in my environment). The change I made since then is to not reload after setting up the modules. The risk of not reloading is that there could be things that don't recognize the new module identity e.g., tool windows or DAS may not start properly. I checked that those two things aren't an issue, so I feel like this is reasonable and better than being prompted twice to open a new project. --- CHANGELOG.md | 2 + resources/META-INF/plugin.xml | 2 - src/io/flutter/FlutterInitializer.java | 17 ++- .../project/FlutterProjectOpenProcessor.kt | 107 ------------------ src/io/flutter/utils/FlutterModuleUtils.java | 3 +- 5 files changed, 16 insertions(+), 115 deletions(-) delete mode 100644 src/io/flutter/project/FlutterProjectOpenProcessor.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 548a5d4f93..b3ec164c81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ ### Removed ### Fixed +- Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and + migrating configuration logic to `FlutterInitializer`. (#8903) ## 91.0.0 diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 0e49834ac7..5c943d83d2 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -335,8 +335,6 @@ - - diff --git a/src/io/flutter/FlutterInitializer.java b/src/io/flutter/FlutterInitializer.java index cd2621ee4c..d9d1ab6681 100644 --- a/src/io/flutter/FlutterInitializer.java +++ b/src/io/flutter/FlutterInitializer.java @@ -67,8 +67,6 @@ * Runs actions after the project has started up and the index is up to date. * * @see ProjectOpenActivity for actions that run earlier. - * @see io.flutter.project.FlutterProjectOpenProcessor for additional actions that - * may run when a project is being imported. */ public class FlutterInitializer extends FlutterProjectActivity { private boolean toolWindowsInitialized = false; @@ -115,8 +113,19 @@ public void executeProjectStartup(@NotNull Project project) { } log().info("Flutter module has been found for project: " + project.getName()); - // Ensure SDKs are configured; needed for clean module import. - FlutterModuleUtils.enableDartSDK(module); + + // Ensure Flutter project configuration is applied for projects that may have been + // opened without a .idea directory. Previously this was handled by FlutterProjectOpenProcessor, + // but that processor silently failed when no delegate processor could open the project. + // Instead, we let the platform open the project normally and apply our configuration here. + // See https://github.com/flutter/flutter-intellij/issues/8661 (Android Studio equivalent) + if (!FlutterModuleUtils.isFlutterModule(module)) { + log().info("Fixing Flutter module configuration for " + module.getName()); + FlutterModuleUtils.setFlutterModuleWithoutReload(module, project); + } else { + // Ensure SDKs are configured; needed for clean module import. + FlutterModuleUtils.enableDartSDK(module); + } for (PubRoot root : PubRoots.forModule(module)) { // Set Android SDK. diff --git a/src/io/flutter/project/FlutterProjectOpenProcessor.kt b/src/io/flutter/project/FlutterProjectOpenProcessor.kt deleted file mode 100644 index edadecba92..0000000000 --- a/src/io/flutter/project/FlutterProjectOpenProcessor.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2025 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -package io.flutter.project - -import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.projectImport.ProjectOpenProcessor -import icons.FlutterIcons -import io.flutter.FlutterBundle -import io.flutter.FlutterUtils -import io.flutter.pub.PubRoot -import io.flutter.utils.FlutterModuleUtils -import java.util.* -import javax.swing.Icon - -/** - * Originally `FlutterProjectOpenProcessor.java`. - * - * This processor handles opening Flutter projects when they are selected directly (e.g. via "Open" in the IDE). - * It delegates the actual opening to the platform's default processor (e.g. Gradle or Maven processor if applicable, - * or the generic project opener) and then ensures that any modules in the project are correctly configured as Flutter modules. - * - * Converted to Kotlin to support `openProjectAsync` which is a suspend function. - */ -open class FlutterProjectOpenProcessor : ProjectOpenProcessor() { - override val name: String - get() = FlutterBundle.message("flutter.module.name") - - override fun getIcon(file: VirtualFile): Icon? { - return FlutterIcons.Flutter - } - - override fun canOpenProject(file: VirtualFile): Boolean { - if (FlutterUtils.isAndroidStudio()) { - return false - } - val root = PubRoot.forDirectory(file) - return root != null && root.declaresFlutter() - } - - /** - * Replaces the deprecated `doOpenProject`. - * - * This method is `suspend` and must be used instead of `doOpenProject` to avoid `IllegalStateException` in newer IDE versions. - * - * It performs the following steps: - * 1. Finds a delegate processor (e.g. Gradle) to open the project. - * 2. Opens the project asynchronously. - * 3. Once opened, checks if the project contains Flutter modules that are not yet configured as such (e.g. missing module type). - * 4. Configures these modules as Flutter modules within a write action. - */ - override suspend fun openProjectAsync( - virtualFile: VirtualFile, - projectToClose: Project?, - forceOpenInNewFrame: Boolean, - ): Project? { - // Delegate opening to the platform open processor. - val importProvider = getDelegateImportProvider(virtualFile) ?: return null - val project = importProvider.openProjectAsync(virtualFile, projectToClose, forceOpenInNewFrame) - if (project == null || project.isDisposed) return project - - // Convert any modules that use Flutter but don't have IntelliJ Flutter metadata. - convertToFlutterProject(project) - - return project - } - - /** - * Deprecated method, kept to satisfy the compiler/interface. - * - * We return `null` to indicate that this processor does not support the synchronous opening method - * and that `openProjectAsync` should be used instead. - */ - override fun doOpenProject( - virtualFile: VirtualFile, - projectToClose: Project?, - forceOpenInNewFrame: Boolean, - ): Project? { - return null - } - - protected open fun getDelegateImportProvider(file: VirtualFile): ProjectOpenProcessor? { - return EXTENSION_POINT_NAME.extensionList.stream().filter { processor: ProjectOpenProcessor -> - processor.canOpenProject(file) && !Objects.equals( - processor.name, - name - ) - }.findFirst().orElse(null) - } -} - -/** - * Sets up a project that doesn't have any Flutter modules. - * - * - * (It probably wasn't created with "flutter create" and probably didn't have any IntelliJ configuration before.) - */ -private fun convertToFlutterProject(project: Project) { - for (module in FlutterModuleUtils.getModules(project)) { - if (FlutterModuleUtils.declaresFlutter(module) && !FlutterModuleUtils.isFlutterModule(module)) { - FlutterModuleUtils.setFlutterModuleAndReload(module, project) - } - } -} \ No newline at end of file diff --git a/src/io/flutter/utils/FlutterModuleUtils.java b/src/io/flutter/utils/FlutterModuleUtils.java index 3fc281e013..edc36b6928 100644 --- a/src/io/flutter/utils/FlutterModuleUtils.java +++ b/src/io/flutter/utils/FlutterModuleUtils.java @@ -373,7 +373,7 @@ public static void setFlutterModuleType(@NotNull Module module) { module.setModuleType(getModuleTypeIDForFlutter()); } - public static void setFlutterModuleAndReload(@NotNull Module module, @NotNull Project project) { + public static void setFlutterModuleWithoutReload(@NotNull Module module, @NotNull Project project) { if (project.isDisposed()) return; ApplicationManager.getApplication().invokeLater(() -> { ApplicationManager.getApplication().runWriteAction(() -> setFlutterModuleType(module)); @@ -381,7 +381,6 @@ public static void setFlutterModuleAndReload(@NotNull Module module, @NotNull Pr project.save(); EditorNotifications.getInstance(project).updateAllNotifications(); - ProjectManager.getInstance().reloadProject(project); }); } From a105e503a485e9ed555e892faa9fb7760ba73bb3 Mon Sep 17 00:00:00 2001 From: Helin Shiah Date: Thu, 16 Apr 2026 09:51:33 -0700 Subject: [PATCH 13/29] Fix losing focus in full screen mode (#8906) Fixes https://github.com/flutter/flutter-intellij/issues/8904 I was able to reproduce and fix the problem in workbench (2025.3) and checked that installing to Idea 2026.1 also fixed the issue. --- .../vmService/DartVmServiceDebugProcess.java | 79 ------------------- 1 file changed, 79 deletions(-) diff --git a/src/io/flutter/vmService/DartVmServiceDebugProcess.java b/src/io/flutter/vmService/DartVmServiceDebugProcess.java index 5179a63db8..3404996c13 100644 --- a/src/io/flutter/vmService/DartVmServiceDebugProcess.java +++ b/src/io/flutter/vmService/DartVmServiceDebugProcess.java @@ -98,23 +98,6 @@ public DartVmServiceDebugProcess(@NotNull final ExecutionEnvironment executionEn session.setPauseActionSupported(true); - session.addSessionListener(new XDebugSessionListener() { - @Override - public void sessionPaused() { - // This can be removed if XFramesView starts popping the project window to the top of the z-axis stack. - final Project project = getSession().getProject(); - focusProject(project); - stackFrameChanged(); - } - - @Override - public void stackFrameChanged() { - final XStackFrame stackFrame = getSession().getCurrentStackFrame(); - myLatestCurrentIsolateId = - stackFrame instanceof DartVmServiceStackFrame ? ((DartVmServiceStackFrame)stackFrame).getIsolateId() : null; - } - }); - this.executionEnvironment = executionEnvironment; this.mapper = mapper; myConnector = connector; @@ -594,68 +577,6 @@ private static boolean isDartPatchUri(@NotNull final String uri) { return uri.startsWith("dart:_") || uri.startsWith("dart:") && uri.contains("-patch/"); } - private static void focusProject(@NotNull Project project) { - final WindowManager windowManager = WindowManager.getInstance(); - if (windowManager == null) { - return; - } - - final JFrame projectFrame = windowManager.getFrame(project); - if (projectFrame == null) { - return; - } - - final int frameState = projectFrame.getExtendedState(); - - if (BitUtil.isSet(frameState, java.awt.Frame.ICONIFIED)) { - // restore the frame if it is minimized - projectFrame.setExtendedState(frameState ^ java.awt.Frame.ICONIFIED); - projectFrame.toFront(); - } - else { - final JFrame anchor = new JFrame(); - anchor.setType(Window.Type.UTILITY); - anchor.setUndecorated(true); - anchor.setSize(0, 0); - anchor.addWindowListener(new WindowListener() { - @Override - public void windowOpened(WindowEvent e) { - } - - @Override - public void windowClosing(WindowEvent e) { - } - - @Override - public void windowClosed(WindowEvent e) { - } - - @Override - public void windowIconified(WindowEvent e) { - } - - @Override - public void windowDeiconified(WindowEvent e) { - } - - @Override - public void windowActivated(WindowEvent e) { - if (projectFrame.isDisplayable()) { - projectFrame.setVisible(true); - } - anchor.dispose(); - } - - @Override - public void windowDeactivated(WindowEvent e) { - } - }); - anchor.pack(); - anchor.setVisible(true); - anchor.toFront(); - } - } - public interface PositionMapper { void onConnect(ScriptProvider provider, String remoteBaseUrl); From 662daed88b6dd32ec03ceab4dc9958567d78c3db Mon Sep 17 00:00:00 2001 From: Dustin Feucht Date: Thu, 16 Apr 2026 19:39:56 +0200 Subject: [PATCH 14/29] feat: Add file chooser support for widget preview initialization. (#8888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using a multi-module project, the widget previewer sometimes fails to automatically find the correct pubspec.yaml. Adding the possibility to manually choose the file allows for more complex project setups. Screenshot 2026-04-03 at 22 46 57 Screenshot 2026-04-16 at 16 12 18 --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- AUTHORS | 1 + CHANGELOG.md | 2 + src/io/flutter/FlutterBundle.properties | 5 ++ .../widgetpreview/WidgetPreviewPanel.java | 53 +++++++++++++++++-- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index ab420d2175..5a33b3d9d7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -27,3 +27,4 @@ Edwin Ludik Japnit Singh Dmitry Kandalov Kazuya Chikamatsu +Dustin Feucht diff --git a/CHANGELOG.md b/CHANGELOG.md index b3ec164c81..8f75b61c19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Added +- Option to specify the pub root module for Flutter Widget Previewer. (#8888) + ### Changed ### Removed diff --git a/src/io/flutter/FlutterBundle.properties b/src/io/flutter/FlutterBundle.properties index d58de0f0b5..4d468d93f8 100644 --- a/src/io/flutter/FlutterBundle.properties +++ b/src/io/flutter/FlutterBundle.properties @@ -193,4 +193,9 @@ widget.preview.starting=Starting Flutter Widget Preview web server... widget.preview.loading=Loading Flutter Widget Preview at {0}... widget.preview.error=Error: {0} widget.preview.sdk.too.old=Flutter SDK version is too old for Flutter Widget Preview. Please update your SDK. +widget.preview.pubroot.not.found=Pub root could not be found to start Flutter Widget Preview. +widget.preview.retry=Reload and try again +widget.preview.choose_pubroot=Choose module and try again +widget.preview.choose_pubroot.title=Select Flutter Project +widget.preview.choose_pubroot.description=Select the Flutter project to use for Flutter Widget Preview. flutter.sdk.not.found=Flutter SDK not found. \ No newline at end of file diff --git a/src/io/flutter/widgetpreview/WidgetPreviewPanel.java b/src/io/flutter/widgetpreview/WidgetPreviewPanel.java index 3f530478cd..21efbd12bd 100644 --- a/src/io/flutter/widgetpreview/WidgetPreviewPanel.java +++ b/src/io/flutter/widgetpreview/WidgetPreviewPanel.java @@ -8,9 +8,14 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.colors.EditorColorsListener; import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.util.messages.MessageBusConnection; import com.jetbrains.lang.dart.ide.toolingDaemon.DartToolingDaemonService; @@ -22,12 +27,14 @@ import io.flutter.devtools.DevToolsUtils; import io.flutter.logging.PluginLogger; import io.flutter.pub.PubRoot; +import io.flutter.pub.PubRootCache; import io.flutter.run.daemon.DevToolsInstance; import io.flutter.run.daemon.DevToolsService; import io.flutter.sdk.FlutterCommand; import io.flutter.sdk.FlutterSdk; import io.flutter.sdk.FlutterSdkVersion; import io.flutter.settings.FlutterSettings; +import io.flutter.utils.LabelInput; import io.flutter.utils.MostlySilentColoredProcessHandler; import io.flutter.utils.OpenApiUtils; import io.flutter.view.BrowserUrlProvider; @@ -71,10 +78,10 @@ public WidgetPreviewPanel(@NotNull Project project, @NotNull ToolWindow toolWind showInfoMessage(FlutterBundle.message("widget.preview.initializing")); // Start the preview process asynchronously - startWidgetPreview(); + startWidgetPreview(null); } - private void startWidgetPreview() { + private void startWidgetPreview(@Nullable VirtualFile file) { OpenApiUtils.safeExecuteOnPooledThread(() -> { try { // Check versioning of Flutter SDK. @@ -125,10 +132,10 @@ private void startWidgetPreview() { }); }); - final PubRoot root = PubRoot.forFile(project.getProjectFile()); + final PubRoot root = getPubRoot(file); if (root == null) { LOG.warn("Pub root not found for project: " + project.getName()); - showInfoMessage("Pub root could not be found to start widget preview."); + showRetryMessage(FlutterBundle.message("widget.preview.pubroot.not.found"), file); return; } @@ -150,6 +157,16 @@ private void startWidgetPreview() { }); } + private @Nullable PubRoot getPubRoot(@Nullable VirtualFile file) { + return OpenApiUtils.safeRunReadAction(() -> { + if (file != null) { + return PubRootCache.getInstance(project).getRoot(file); + } else { + return PubRoot.forFile(project.getProjectFile()); + } + }); + } + private @Nullable String getDevToolsUri() { try { final CompletableFuture devToolsFuture = DevToolsService.getInstance(project).getDevToolsInstance(); @@ -252,6 +269,34 @@ private void showInfoMessage(@NotNull String message) { }); } + private void showRetryMessage(@NotNull String message, @Nullable VirtualFile file) { + ApplicationManager.getApplication().invokeLater(() -> { + final List inputs = List.of( + new LabelInput(message), + new LabelInput(FlutterBundle.message("widget.preview.retry"), (label, data) -> startWidgetPreview(file)), + new LabelInput(FlutterBundle.message("widget.preview.choose_pubroot"), (label, data) -> chooseFile()) + ); + final JPanel panel = viewUtils.createClickableLabelPanel(inputs); + contentPanel.removeAll(); + contentPanel.add(panel, BorderLayout.CENTER); + contentPanel.revalidate(); + contentPanel.repaint(); + }); + } + + private void chooseFile() { + final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.singleFileOrDir() + .withTitle(FlutterBundle.message("widget.preview.choose_pubroot.title")) + .withDescription(FlutterBundle.message("widget.preview.choose_pubroot.description")) + .withRoots(FlutterUtils.getProjectRoot(project)); + + final VirtualFile selectedFile = FileChooser.chooseFile(descriptor, project, null); + if (selectedFile != null + && OpenApiUtils.safeRunReadAction(() -> ProjectFileIndex.getInstance(project).isInContent(selectedFile))) { + startWidgetPreview(selectedFile); + } + } + @Override public void dispose() { // Terminate the Flutter process when the tool window is closed From 5e47de62d739f52998505d33bc70738a9bff3b15 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Fri, 17 Apr 2026 06:55:15 -0700 Subject: [PATCH 15/29] [ai] add Claude config (#8912) See: https://github.com/flutter/flutter-intellij/issues/8895 Adds `Claude.md` config. The `@.gemini/styleguide.md` import pulls in the full styleguide automatically, and the additional rules below it mirror the key generation rules for Gemini from `.aiconfig`. --- Review the contribution guidelines below:
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- CLAUDE.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..b832fac27e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,12 @@ +# Flutter IntelliJ Plugin — Claude Code Guide + +@.gemini/styleguide.md + +## Additional Rules + +- No I/O or heavy computation on the EDT (IntelliJ Threading Model). +- All `AnAction` subclasses must be stateless (no mutable instance fields). +- Use `io.flutter.logging.PluginLogger` (or IntelliJ's `Logger`) for all logging; never `System.out`. +- All new files must include the standard Chromium Authors copyright header. +- Zero-Formatting Policy: do not comment on indentation, spacing, or brace placement. +- Categorize code suggestions with `[MUST-FIX]`, `[CONCERN]`, or `[NIT]` severity prefixes. From c471478e564d787e57346a7555350477d8338d52 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Fri, 17 Apr 2026 07:07:31 -0700 Subject: [PATCH 16/29] [docs] stop specifying a JDK version (#8911) Stale and not adding value. (Destined to get stale again too.) --- Review the contribution guidelines below:
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a82ede3ea..f7a6dd1879 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -58,7 +58,6 @@ name and contact info to the [AUTHORS](AUTHORS) file. ## Environment set-up 1. Install the latest [Java Development Kit](https://www.java.com/en/download/). - - The current Java Development Kit version is: **23**. - **[Googlers only]** Install Java from go/softwarecenter instead. 2. Set your `JAVA_HOME` directory in the configuration file for your shell environment. From 70da7a03179bccb72eb90d569e0ad53ca8b92279 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Fri, 17 Apr 2026 08:36:06 -0700 Subject: [PATCH 17/29] [infra] add parameterized `runTarget` to allow running against custom IDE targets (#8910) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for running the plugin against custom target IDEs using the new [`intellijPlatformTesting`](https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-testing-extension.html) Gradle extension, introducing a new parameterized `runTarget`. ## Why not update `runIde` directly? In the new IntelliJ Platform Gradle Plugin (v2.x), the default `runIde` task is strictly bound to the main project dependency used for compilation (which is Android Studio in our project). To run against a different IDE *without* changing the compilation target (which would break compilation due to our project's hard dependencies on Android Studio APIs), the plugin requires using the `intellijPlatformTesting` extension to register a custom task. We can't easily re-target the default `runIde` task without also changing what we compile against. (And if we don't change what we compile against we're in the reflection business so we can compile in the absence of AS deps OR code splitting which is a headache; see relevant conversation in https://github.com/flutter/flutter-intellij/pull/8865.) ## Details - Registers a custom `runIde` task named `runTarget` in `build.gradle.kts`. - Added support for `-Pide` (values: `AndroidStudio`, `IntelliJ`, `Ultimate`) and `-PideV` (version string or build number) properties. - Adds a self-documenting help output to `runTarget` that lists available options and examples when run without parameters, and then exits without launching the IDE. - Updates the existing `printProductsReleases` task to include instructions on how to map its output to the new `-Pide` and `-PideV` parameters. --- ## Sample Outputs ### 1. Running `runTarget` without parameters Running the task without parameters prints a help report and stops execution. ```bash ./gradlew runTarget ============================================================ runTarget - Available Options ============================================================ Valid values for -Pide: - AndroidStudio (default) - IntelliJ (IntelliJ IDEA Community) - Ultimate (IntelliJ IDEA Ultimate) Valid values for -PideV: - Any valid version string for the selected IDE. - Examples for IntelliJ/Ultimate: 2024.1, 2024.2, 2024.3, 2025.1 - Run './gradlew printProductsReleases' to see the full list. Examples: ./gradlew runTarget -Pide=IntelliJ -PideV=2025.1 ./gradlew runTarget -Pide=Ultimate -PideV=2025.1 ============================================================ Stopping execution. Please run with parameters to launch a specific IDE. ``` ### 2. Running printProductsReleases The task now prints mapping instructions after listing the available releases. ``` ./gradlew printProductsReleases IU-261.23567.71 IU-253.31033.53 IC-252.27397.28 Mapping printProductsReleases output to ideV: - The prefix (e.g., IU-, IC-) maps to -Pide (Ultimate, IntelliJ). - The number part (e.g., 261.23567.71) maps to -PideV. - Example: IU-261.23567.71 -> -Pide=Ultimate -PideV=261.23567.71 ``` Fixes: https://github.com/flutter/flutter-intellij/issues/8909 --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- CONTRIBUTING.md | 17 +++++++++++++++ build.gradle.kts | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7a6dd1879..7ad5bc9ea8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -232,6 +232,23 @@ name and contact info to the [AUTHORS](AUTHORS) file. - Expand `Edit configuration templates...` and verify that Flutter is present. - Click [+] and verify that Flutter is present. +### Running against custom target IDEs + +To test or debug the plugin against a different IDE target (like IntelliJ IDEA Community or Ultimate) without changing the project's compilation target, you can use the custom `runTarget` Gradle task. + +Run it from the command line specifying the target IDE and version: +```bash +./gradlew runTarget -Pide=IntelliJ -PideV=2025.1 +``` + +* **`-Pide`**: Valid values are `AndroidStudio` (default), `IntelliJ` (Community), and `Ultimate`. +* **`-PideV`**: Any valid version string or build number for the selected IDE. + +To see a full list of available options and usage examples, run the task without any parameters: +```bash +./gradlew runTarget +``` + ## Provision Tool This is not currently required. However, for debugging unit tests, it may be handy; please ignore for now. diff --git a/build.gradle.kts b/build.gradle.kts index 992f124b9c..81d8be9f29 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -389,12 +389,18 @@ tasks { // https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-faq.html#how-to-check-the-latest-available-eap-release tasks { printProductsReleases { - channels = listOf(ProductRelease.Channel.EAP) - types = listOf(IntelliJPlatformType.IntellijIdeaCommunity) + channels = listOf(ProductRelease.Channel.RELEASE, ProductRelease.Channel.EAP) + types = listOf(IntelliJPlatformType.IntellijIdeaCommunity, IntelliJPlatformType.IntellijIdeaUltimate) untilBuild = provider { null } doLast { productsReleases.get().max() + println() + println("Mapping printProductsReleases output to ideV:") + println(" - The prefix (e.g., IU-, IC-) maps to -Pide (Ultimate, IntelliJ).") + println(" - The number part (e.g., 261.23567.71) maps to -PideV.") + println(" - Example: IU-261.23567.71 -> -Pide=Ultimate -PideV=261.23567.71") + println() } } prepareJarSearchableOptions { @@ -415,6 +421,53 @@ tasks { } } +intellijPlatformTesting { + runIde { + register("runTarget") { + val target = project.findProperty("ide") as? String + val version = project.findProperty("ideV") as? String + + val actualTarget = target ?: "AndroidStudio" + type = when (actualTarget) { + "IntelliJ" -> IntelliJPlatformType.IntellijIdeaCommunity + "Ultimate" -> IntelliJPlatformType.IntellijIdeaUltimate + else -> IntelliJPlatformType.AndroidStudio + } + this.version = version ?: ideaVersion + } + } +} + +tasks.named("runTarget") { + val target = project.findProperty("ide") as? String + val version = project.findProperty("ideV") as? String + + doFirst { + if (target == null && version == null) { + println("============================================================") + println("runTarget - Available Options") + println("============================================================") + println("Valid values for -Pide:") + println(" - AndroidStudio (default)") + println(" - IntelliJ (IntelliJ IDEA Community)") + println(" - Ultimate (IntelliJ IDEA Ultimate)") + println() + println("Valid values for -PideV:") + println(" - Any valid version string for the selected IDE.") + println(" - Examples for IntelliJ/Ultimate: 2024.1, 2024.2, 2024.3, 2025.1") + println(" - Run './gradlew printProductsReleases' to see the full list.") + println() + println("Examples:") + println(" ./gradlew runTarget -Pide=IntelliJ -PideV=2025.1") + println(" ./gradlew runTarget -Pide=Ultimate -PideV=2025.1") + println("============================================================") + println("Stopping execution. Please run with parameters to launch a specific IDE.") + + throw org.gradle.api.tasks.StopExecutionException() + } + } +} + // A task to print the classpath used for compiling an IntelliJ plugin // Run with `./gradlew printCompileClasspath --no-configuration-cache ` tasks.register("printCompileClasspath") { From 6d04cb35fb907ca5df56a161f96f3e0ba10960fa Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Mon, 20 Apr 2026 14:50:24 -0700 Subject: [PATCH 18/29] [friction] add auto-baseline updating (#8917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/flutter/flutter-intellij/issues/8916 --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- tool/github.sh | 3 +++ tool/update_baselines.sh | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100755 tool/update_baselines.sh diff --git a/tool/github.sh b/tool/github.sh index a17814ce8c..6e21407a13 100755 --- a/tool/github.sh +++ b/tool/github.sh @@ -135,6 +135,9 @@ elif [ "VERIFY_BOT" = "$BOT" ] ; then if [ $EXIT_STATUS -ne 0 ]; then echo -e "${RED}${BOLD}Build failed: New verification issues were detected.${NC}" + echo -e "${YELLOW}To update the baselines with these new issues, run:${NC}" + echo -e "${YELLOW} ./tool/update_baselines.sh${NC}" + echo -e "${YELLOW}from the repository root and commit the changes.${NC}" exit 1 fi diff --git a/tool/update_baselines.sh b/tool/update_baselines.sh new file mode 100755 index 0000000000..8052bd039a --- /dev/null +++ b/tool/update_baselines.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright 2026 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +if [ ! -f "build.gradle.kts" ]; then + echo "Error: This script must be run from the repository root directory." + exit 1 +fi + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BOLD='\033[1m' +NC='\033[0m' # None (Reset) + +echo -e "${BOLD}Running plugin verification...${NC}" + +rm -rf build/reports/pluginVerifier + +VERSIONS=$(ls tool/baseline) + +if [ -z "$VERSIONS" ]; then + echo -e "${YELLOW}Warning: No baseline directories found in tool/baseline.${NC}" + exit 0 +fi + +echo -e "${BOLD}Found versions to update: $VERSIONS${NC}" + +for version in $VERSIONS; do + echo -e "${BOLD}Verifying version $version...${NC}" + ./gradlew verifyPlugin -PsingleIdeVersion=$version --no-configuration-cache --no-daemon || true + + echo -e "${BOLD}Processing baseline for $version...${NC}" + BASELINE="tool/baseline/$version/verifier-baseline.txt" + REPORT=$(find build/reports/pluginVerifier -path "*-$version.*/report.md" | head -n 1) + + if [ -f "$REPORT" ]; then + echo "Extracting issues from $REPORT" + mkdir -p "$(dirname "$BASELINE")" + grep "^*" "$REPORT" | sort > "$BASELINE" + echo -e "${GREEN}Updated baseline at $BASELINE${NC}" + else + echo -e "${YELLOW}Warning: Report does not exist for version $version. Skipping.${NC}" + fi +done + +echo -e "${BOLD}Done updating baselines.${NC}" From f47490f1a2cbbdbd87c3ecdf68c35d9d5c1a4084 Mon Sep 17 00:00:00 2001 From: Cory R Date: Tue, 21 Apr 2026 09:55:57 -0700 Subject: [PATCH 19/29] [infra] include Android Studio in release printing (#8915) Added Android Studio to the release printing. Android studio releases are prefixed with "AI" IU-261.23567.71 IU-2025.3.4 IC-2025.2.6.1 IU-2025.2.6.1 IC-2025.1.7 IU-2025.1.7 AI-2025.3.3.6 AI-2025.2.3.9 AI-2025.1.4.8 --- build.gradle.kts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 81d8be9f29..2cf6acec29 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -390,16 +390,18 @@ tasks { tasks { printProductsReleases { channels = listOf(ProductRelease.Channel.RELEASE, ProductRelease.Channel.EAP) - types = listOf(IntelliJPlatformType.IntellijIdeaCommunity, IntelliJPlatformType.IntellijIdeaUltimate) + types = listOf(IntelliJPlatformType.IntellijIdeaCommunity, IntelliJPlatformType.IntellijIdeaUltimate, IntelliJPlatformType.AndroidStudio) untilBuild = provider { null } doLast { productsReleases.get().max() println() println("Mapping printProductsReleases output to ideV:") - println(" - The prefix (e.g., IU-, IC-) maps to -Pide (Ultimate, IntelliJ).") + println(" - The prefix (e.g., IU-, IC-, AI-) maps to -Pide (Ultimate, IntelliJ, Android Studio).") println(" - The number part (e.g., 261.23567.71) maps to -PideV.") println(" - Example: IU-261.23567.71 -> -Pide=Ultimate -PideV=261.23567.71") + println(" - Example: AI-2025.3.3.6 -> -Pide=AndroidStudio -PideV=2025.3.3.6") + println() } } From afc33b5d4ca561b4b5d9bbef8fae3e847eeb4b78 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 23 Apr 2026 14:36:20 -0700 Subject: [PATCH 20/29] remove stale link (#8920) Follow-up from: https://github.com/flutter/dart-intellij-third-party/pull/337/changes/dfaef98f73dc77eeb56be57e854803951d0a46d4#r3132800413 --- Review the contribution guidelines below:
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- .github/dependabot.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 109ca2991d..907f07712b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,3 @@ -# See Dependabot documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - version: 2 updates: - package-ecosystem: "github-actions" From 5ba28eed1683a6c56fa78b1c1254ce801001072f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 17:13:51 -0700 Subject: [PATCH 21/29] Bump actions/upload-artifact from 6 to 7 (#8841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
Release notes

Sourced from actions/upload-artifact's releases.

v7.0.0

v7 What's new

Direct Uploads

Adds support for uploading single files directly (unzipped). Callers can set the new archive parameter to false to skip zipping the file during upload. Right now, we only support single files. The action will fail if the glob passed resolves to multiple files. The name parameter is also ignored with this setting. Instead, the name of the artifact will be the name of the uploaded file.

ESM

To support new versions of the @actions/* packages, we've upgraded the package to ESM.

What's Changed

New Contributors

Full Changelog: https://github.com/actions/upload-artifact/compare/v6...v7.0.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Phil Quitslund --- .github/workflows/presubmit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/presubmit.yaml b/.github/workflows/presubmit.yaml index 7ab6c5ec11..c10d8ebead 100644 --- a/.github/workflows/presubmit.yaml +++ b/.github/workflows/presubmit.yaml @@ -37,7 +37,7 @@ jobs: env: BOT: ${{ matrix.bot }} - name: upload build artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: always() with: name: build-${{ matrix.bot }} From 44c3709bfeb4601e0be425f6498889d67ab1059d Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 23 Apr 2026 17:53:23 -0700 Subject: [PATCH 22/29] [maintenance] migrate deps to `libs.versions.toml` (#8923) Fixes: #8921. --- Review the contribution guidelines below:
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- build.gradle.kts | 30 +++++++++++++++--------------- gradle/libs.versions.toml | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 gradle/libs.versions.toml diff --git a/build.gradle.kts b/build.gradle.kts index 2cf6acec29..a851bf9b48 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,10 +40,10 @@ plugins { // https://plugins.gradle.org/plugin/org.jetbrains.intellij.platform // https://plugins.gradle.org/plugin/org.jetbrains.kotlin.jvm id("java") // Java support - id("org.jetbrains.intellij.platform") version "2.12.0" // IntelliJ Platform Gradle Plugin - id("org.jetbrains.kotlin.jvm") version "2.2.0" // Kotlin support - id("org.jetbrains.changelog") version "2.2.0" // Gradle Changelog Plugin - id("org.jetbrains.kotlinx.kover") version "0.9.4" + alias(libs.plugins.intellij.platform) // IntelliJ Platform Gradle Plugin + alias(libs.plugins.kotlin.jvm) // Kotlin support + alias(libs.plugins.changelog) // Gradle Changelog Plugin + alias(libs.plugins.kover) idea // IntelliJ IDEA support } @@ -239,13 +239,13 @@ dependencies { pluginVerifier() } - compileOnly("org.jetbrains:annotations:24.0.0") - testImplementation("org.jetbrains:annotations:24.0.0") - compileOnly("com.google.guava:guava:32.0.1-android") - compileOnly("com.google.code.gson:gson:2.10.1") - testImplementation("com.google.guava:guava:32.0.1-jre") - testImplementation("com.google.code.gson:gson:2.10.1") - testImplementation("junit:junit:4.13.2") + compileOnly(libs.jetbrains.annotations) + testImplementation(libs.jetbrains.annotations) + compileOnly(libs.guava.android) + compileOnly(libs.gson) + testImplementation(libs.guava.jre) + testImplementation(libs.gson) + testImplementation(libs.junit) implementation( fileTree( mapOf( @@ -256,12 +256,12 @@ dependencies { ) // UI Test dependencies - integrationImplementation("org.kodein.di:kodein-di-jvm:7.26.1") - integrationImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0") + integrationImplementation(libs.kodein.di) + integrationImplementation(libs.kotlinx.coroutines) // JUnit 5 is required for UI tests - integrationImplementation("org.junit.jupiter:junit-jupiter:5.11.4") - integrationRuntimeOnly("org.junit.platform:junit-platform-launcher") + integrationImplementation(libs.junit.jupiter) + integrationRuntimeOnly(libs.junit.platform.launcher) } intellijPlatform { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000000..f4af5fae10 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,35 @@ +# Copyright 2026 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +[versions] +jetbrains-annotations = "24.0.0" +guava-android = "32.0.1-android" +guava-jre = "32.0.1-jre" +gson = "2.10.1" +junit = "4.13.2" +kodein-di = "7.26.1" +kotlinx-coroutines = "1.9.0" +junit-jupiter = "5.11.4" +junit-platform = "1.11.4" +intellij-platform-plugin = "2.12.0" +kotlin = "2.2.0" +changelog = "2.2.0" +kover = "0.9.4" + +[libraries] +jetbrains-annotations = { group = "org.jetbrains", name = "annotations", version.ref = "jetbrains-annotations" } +guava-android = { group = "com.google.guava", name = "guava", version.ref = "guava-android" } +guava-jre = { group = "com.google.guava", name = "guava", version.ref = "guava-jre" } +gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +kodein-di = { group = "org.kodein.di", name = "kodein-di-jvm", version.ref = "kodein-di" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } +junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit-jupiter" } +junit-platform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version.ref = "junit-platform" } + +[plugins] +intellij-platform = { id = "org.jetbrains.intellij.platform", version.ref = "intellij-platform-plugin" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } +kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } From a3394826aff4529fe4d624a3a141ceee4aceab70 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 23 Apr 2026 18:11:22 -0700 Subject: [PATCH 23/29] [maintenance] add gradle deps to dependabot tracking (#8924) Fixes: #8922. --- Review the contribution guidelines below:
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 907f07712b..ba26e31e05 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,3 +11,10 @@ updates: ignore: - dependency-name: "*" update-types: ["version-update:semver-patch"] + + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + labels: + - "autosubmit" \ No newline at end of file From 50e466b8ca3bd8d748d53e9cac0fb13e81f1cbe5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:39:57 -0700 Subject: [PATCH 24/29] Bump gradle-wrapper from 9.3.0 to 9.4.1 (#8926) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.3.0 to 9.4.1.
Release notes

Sourced from gradle-wrapper's releases.

9.4.1

The Gradle team is excited to announce Gradle 9.4.1.

Here are the highlights of this release:

  • Java 26 support
  • Non-class-based JVM tests
  • Enhanced console progress bar

Read the Release Notes

We would like to thank the following community members for their contributions to this release of Gradle: akankshaa-00, Attila Kelemen, Björn Kautler, dblood, Dennis Rieks, duvvuvenkataramana, John Burns, Julian, kevinstembridge, Niels Doucet, Philip Wedemann, ploober, Richard Hernandez, Roberto Perez Alcolea, Sebastian Lövdahl, stephan2405, Stephane Landelle, Ujwal Suresh Vanjare, Victor Merkulov, Vincent Potuček, Vladimir Sitnikov.

Upgrade instructions

Switch your build to use Gradle 9.4.1 by updating your wrapper:

./gradlew wrapper --gradle-version=9.4.1 && ./gradlew
wrapper

See the Gradle 9.x upgrade guide to learn about deprecations, breaking changes and other considerations when upgrading.

For Java, Groovy, Kotlin and Android compatibility, see the full compatibility notes.

Reporting problems

If you find a problem with this release, please file a bug on GitHub Issues adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the forum.

We hope you will build happiness with Gradle, and we look forward to your feedback via Twitter or on GitHub.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=gradle-wrapper&package-manager=gradle&previous-version=9.3.0&new-version=9.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 43705 -> 48966 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 9 +- gradlew.bat | 187 +++++++++++------------ 4 files changed, 97 insertions(+), 101 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9bbc975c742b298b441bfb90dbc124400a3751b9..d997cfc60f4cff0e7451d19d49a82fa986695d07 100644 GIT binary patch delta 40550 zcmXVXQ+!?T^L3KOIk8S`+qP{qwr!urwr#sj(zr1j+qUiG?f3V8Z}!Fh?3-uL%$jG` zTGO@wG4u)1V2cD|n3#YMW=4VB_9ebbz+Rqy%+Re+g-jI%)vvYM5Dz7UJU&!6FBu4MJHC2G(Y3TqhL_46F?-d50Q5c>zfl0U6$a|FEQGO=7-1nHHH2v<>h8cGfH< z??+CB=oQJmB#iT1IcKiu;i(+|mEe?1^ooa;5Jtl$6?X}A!I8y#c4Cz8A)L}MlOQ~? z8G5lJp6!M5_P<>dVu~dpr5AS-Mai8-nz1d9&@V)8iheEuttu5^XuY>V#fbQ3r5fz! za*h;adt=fusRlQ)^Aeg{FT$tCS3(Eej?#NcQbh;+iB<1X@^ipjX)qOAL z0Jx5w7C`CRTZv|i_=|&j812w%f>e@Zo5ievAhk6`bQKK!@D_l5xEzASbr83Km7JV}Lo-D;3KO|R z3oEOgoj$a07Eum%xWR4g5@DEv zaSYq?&?3rP;hfI#tp{kL(Q#0*n`jIlCbKq!(B99XhM_)3U9%hu{ksXCq?YT$m?8ux z%;QCnDPw&W;jCG|&bY8BGjc2FE`_61A5iED-6W%-#xZ2&WHkZHjOV)EeZ4k?yP^`S*!5 zBZ0+fm0M=d16NC6=Q@jqoEqRCM&#Yn&zv>shS=_t#x&j7qZwN?Po%fL!`H#K+(x!l%1UnzsCp9JB{&V3Ieo2@M!VK3sreVF;67adO?QGkL{sDPHHgknS8Sh3J{{jK6DJirP!bG-0 zI0i6@m_(ECJ(h?#-#a;f947;Sq-@?`i^G9$F}C5YpF-WvF*IRg_bj)7E9N{3$Fv=) z!^LhR`X@{|T_VK*5IpR-8|92^5Y4@Ggmekwr%{k3_3kGzj&l$_8Q!Ssn-sAX0O~IE z6a2sQG_DD~h=TwFTl@B}OhuBF&OgauqX%my# zAE<*VOcuVsy9m41Y#-~WS#HJN5d)?nDP{(Uw&Ph94PjvwaIcbbS2B+>Gjnr4K8}W& zz@8FKpWU3Ue?IqCxKxvr*w^4{PH3~%^fff3iCioIj^BZjk_Y81zx#Yr_;A`8fSbQ} z=N|C9s=VwmrOZ*{5dA>QjO&*G4P_qM)4X6~UbW2w-_C946O5K3k15#|g0M#6&)~I_ z;In>y-QAZow{LkifZUrI;YHh(gkC=HxEkXuk^5?Uqk8CcpY{<4IZKfH-)*!FQ(`U% z@Ad5R51(hy4$dJoX3Y++m`-OrhM}6`I5sQ%$!B||ZsHl{V#@BDIaiD<&3exSWSwc8 zaTT&~a4*VUi@yaJXLUzklogn2#&A&FTC3Q%X2tp#<4*kn$?5g3}CmYcVq*sc@-KVkF~*g=|z zpctlTIeRI!C~XEYlJqj8+WMBG9_JbyI3UoxtYf3`0(sxtcMx;Um5=t;F(Um(8xX%( z`yUd$UVq1+)H&>8N?~KT6;&e$39AtA{Q$th;ItEDle&FSJA@4;z6|??9?3f_xljm6 z+dK2I;^L{&p=P@XXEpijNOVXaTS{Lr<%J5*#j`>?MUa4Se#eH80R$9V)4A>}_d|?{ zUDodr**t@NA9Ooa)SUoA?mN_RZ1?uMX--LnU6g)dI}?GMmHb%kO4h5;G~A&jG5IX5 zmN_bf&nJ3 zOSmXPngxOe6fvV7P_~4#b*ZWx6(w=q0$4lN6g!&BDD1vYiQ277uldEUew!ya1sXS` zCY#B1StJFU&0~(v<1le7M!sY1#dgzA-;|&lJ6FB!Bi$06Z@@F81<_!b%kQG~7ZP-e z7cq?khwI;P1YA2Xys~!8-vKKw_m8wn18<5Hd8r_l;4L89FZOF|-kGd!d6)~qddOcL zRLtEQO|*T8sP{Ac$;TW6K5s!cl3%Mm|DI2__ih*$_fRQrJa z56HX;1zX`K?tm0Wn3{ga=?`eCpCFNskiy&ADWFpL^oZ+yJ(+%4dE?*Wd)&z`onbGY z8&g8;an}o-N)YJ>SHSoF)cCUuxbJs5oMN5T^?k>6a{`eq^&{cBvg|*vF~buRL}|oG ze&D$wCKLMjC#G@YlVg6EF-wOTtz`&AW{&)FG zz>x=i*Tq}H34jTK8CXX0`nDEn?){BKq;r5$cmvEC4F5!m+O;+6XcBTy~~w_Z`F4@4UP8 z_^mgxAEw&M*Qcp;mb&@KamP2#iHeYGK{qoXBW~btRh<5L{eD>~RZYaZBu@Wa3j`hK%6!fo;QIr3hdIkNCJ%#)Ht ztUk_J8C9x~i)pNr+6k#_T{1WpRKG&BD2T5gsm*)4Ed3bpirOAODXh=n)S3nqic8l( zvZeQKq_PT@ZfmHIpLtCjnU_=2+dN}GsyjqOm3k97Lghy6l?%QTdiSJiV>XFjsVFHH z==X-@KtT0=kz^&4c)I&#YKsoAB~qi6NQaX3(pnkd=_IxRF_oubtt}{Dko(=O=?QIToZ|`aWRonWu2zug%V?5(3av@n)3~CCg+o?5_h8WU% zP*XdOuq?i*gy-U3iYZ{yHt32`RPCRFBL=9CYX}F2#kye5H^5~d*a*?h$$GAi+R2va zL+K;7!DjjJt|TFg?D@>0YSUTJ;%dkHY@Tkbhso5_u&&#m#?94{gp|>;lhzo4=5BWq z%*oZ+*`$LT*~;1ZsWWw)w0r&O3ah!t*0ax5JpUprSR*3uwC0oTK|cAA_9oFhwu1JH zB04T&k2v^aIB{k@n1t_%P2s<1BXicU;o}MhCI^JQCc|f4GJcottsHkwj8{1#AUr6j zJl33^$wZ1!AIgQt5Cvw;=L!#jS}0>eq#-34_!6$VBV;xL_4c5V2%L~Ow01E}MblCy z{e<*Lx0F(0M{F1o3!diMb&#}E<3j2$mw?=XVdVU9-L99=i~%Y zt%=Z?_*8yx2s*Er$6!>1xyrs?9wd9eVoZ+lBT{pBTNwBt4wJO#p{nYF0=V<`#Ji8$ zoGhzliNZgCedTZ*H0xAumTj3u{)=CUg*_!ZaZqS|k!xX6_ID$xUb4M$sm7OMxE7+z zw1RuXbIYTRy5toFE$W+jp^P0iA?5{^tep&);<7Ct`Y|dJ5TdJi2S&6i47AJksdXBy zHZ7bfHTluNbXoZ9;C3k`*L3QijD$_Jfe0mNJ&181|@S~56K1-UPSd)Eroi5=QIh0a^N7}|MttlLK zGnS=q&w!b0sLGGKXVQ4q7AI{>9*RkuC+LunJ99sY_9u-;6+vPUZa1TKtd~mfkU8ql zYOn8U(xfxitWpn%67U@ibL6z%AESitl-(M!j@xTFqj5Jm)7Me>Ki!`lFzZY_jeUHR z+M>^3;1wS&6qdHt^=(k8m}%^sr%cbKYFPR)TP}6}UOkG&dTS~ko!mcbylabk$4)f7 z>J2L4zzISgc+Fgc*m7!z&YpQbq>~$dx}+z)%IPKhIZ{{1u4;0!{f%3262KldtfeJj zO8fJ;XCGOV^su+#C_h86ijcnPc&#f$ICus0)h(%k3%eum#_o#s?1E1y5eJcYv$cgx zj=64XbUSpbW=c<%KXc1@C=(?jPfq;oe*IaAYV3#U?P`OjWts3Tm{^qMTHp>LBFfl{vkxW$^Pox z-rG0ASc!2l(6{Dzj*Y(LyWs!Hx;@JD?D5MJ2_Y?JL89PFUmmX%3>Ey#;6pZTQJs?{g-y={xp`Tq!!o`s_@qapdskkg7$q$%PVU#QxJck(JivKhCGg< z?4j3oP3w{r&ryBT`272$KKCzz7w_U>_Anb;#PBNZXUwUOq5mL$Qoll@6M4(8O|I~H zVZo$AAo@=x*&7_a(^5CXIRNFq!|wR&b%iqB;GH2RJ~od44BBI_QjC}Tue;)K{PO?k zPrcR^f_RXBK88D*^t+$aBzByLUb-;8ldrnr{ZVF)ePz~ir1c^ieyw07wcUH&6>`Dd z%Ic4$n6#?sS&=Szd+porl3`~`tmMiu)p@ri*Hd0PB(poYxGKl~QhauG5l}h+72kdv z$GMbRAoWo$R4-B-WWfv@>p+OEp&qmiMRvX<1D%_Q)-jHaktz(Ht%HB{eftW`?}%^M zD&`>~K0n}42uxk@${1VCSQwVUF>#D*q42Q8a?x=d7~l5`-Qbzn^ozy3!BSZ_ za-1}x`;4@I{^9;i;<0Ty-^h5D>hFh>b7z<8i{a*(z`&>shgaHHNMFs;?miq>o zd_;|vyiKeM3U;@X7{Wl^nucF(OnnJ51us@9iX4U914wpnG^eXtJEpggu}B6){OLu` zI+lOmM!uH9QREx=$rq|bmaHDgHaS! z93Aj9z-a0Ghi+X(W}TYulR&&&wT$ePH%gSzXC`_WdD}{)8VI;t8zCjyOD*;w?XXo6 zLoc=nQc?$|WlOodfg{t@pnm0%cT~q!R8Q#ouAZtR9YT zT`jN%w=Hzc5))d-m#nKZ^wSP8kKPzowbRznI57zf^xczw{gq={7(!$LWycJq1w28@ z1H`4OymS5M!{YU_wrTWoO_e|zuQUucGb*e<1aP4@8a~r7 z39MLO!X_6OqO$d`nT_HBkeOTm<(O?Sdx3m1h|CV8cBY6fg7Fy!At#4ArXZ}Y7v0h% zC*p8GT7t$-zKlkU_AXY|(f_ldgW{KN2+$iPzn93Sl|1ViOfcn!9_k>?jVp8GWzw_T zHIwbn*ZVV+5r!)uKR!b^je;DwQt$swZH^C`%u*0IxwHO?yteCW2${Nm}9nWe-mb%b(^U4 zI0xJY_H40sh$V~^^sg+E#|0%sBS7MU>i5&#W^;tF$Ru{Qvi&dy)^>aIL%FzqebdO4 zw6^<@80^QO99N>&PGL>|O9ZH9z)98Q68|X(2lwF%1KRy0tcPc#m6UBl`N~n(!0#C8 zvDOLPcgTeSl(wT##M|Zbyx&1hY6U1pdIH*@M}wnC$U(xJsIU{`XZ)iu@dLCm)GO}k z5KWJz=`XJR^BUW1Ei^y2^~#d3a8d?x(&wSo5L=Z3xM<+pBX^zh4|}6`!FkD!MVLU% zb^C{Mm!;3u9Rt;xeh>T=-~AU(wWf!il<=REj!M3Jgq-=RYg4$b{63dglnrP#^ZsV+M`X{wr-v{#uQ3-pHn3HbPJaeEmVZ9*F)GYz*eIj3Q1g(Uy-Qw_r<7TaFL zvp$Xzr9y-rC|W>)^_PZ(g!$I7=z-$GM@0@c6NZyhmC6b!w~)g>=+O~256EjZ?cM7q zufuV#p<1h7?)4lRfMa1@Tkd#0bR8j$dCM9Jz5m=Z#IhPclg}$*^8uXLV(AQsihRh= zSO*f%;aGHks-2S5^1dP`JEGGxsk!Kf+~*F%=BA^+BK()<5@GH`i~l$(S*ZU_Gv}02 zAO$5n78HVHrmR_EIU&Wa8gB9k^Ai{p5sgZTD&eRC8x$CaUmeM@y=VF>n-!{1LLs2u zN>$_!@DG&;=d7qr6v1cj&1~=#P!bUTaTy+mPLCZLWKbx>pzGs-?$X+$#I2yM%PqdYN)d#54 z42BSxK8K0TX3mRCp2n=e;f#Y=whTePH<8t{AhGX=A)CS_%+X#+G2y&)Gw88tRpp*kK*F_a zeBXa~d(DSoH9^gHz;q>ZvcGqzSv|5`CUkcwQKC1@Tp(WB@BM-H@D3AowN6d;fDrVA z@!SC98unZU6Y$}*`8Rpi@%NqFlhx5<@)&6P$73@Y&1B2QuLZqb<#ym;=mxjHP&S!b~L}b_v-WpHYA6{IHeeqi-9WT6( zt=WBIc?mabrz7y_l(;Fv5b}y!i>2J6STLrxedWz0WL&$l07pyf7 z1z+NFEfK2L*ySHxJrRUQGz>pM+Q;%%L*$H|l10pSet}la?Oog^4m=K{`+6QZH&G7-tA>f7^6vwQTli zhv|#JFvFSE(*XevYPZshQxL;y@}*I{%zQoWGmJ}l3ArZcJ!D#R)-;?^L-{fER1^E> zF&K?>BmzRl0Bs{g=FERJZIgMWPkfNlzid94Odj+jU7a7o0n)08xw{# z^h_(>eZNW^`N|UD9p0$~yn843v7Dpjw?%|qMHZFd2|&e@16=C##yn}QwI*1uEIP(U z_jR~p7Ri)Bh0~E%$1UF1NuGOC3`1MbHCG;?^1zf4=FmfSiHIC>^(cRNprk-mQ~j(p zxV4UOWA|^*sNGXI*;w?ye$Yu6RUj-YVlh~&rFa!ut+3Wl!aKvpRxOZPU5+T<&|ehK zu!;cj1NxY{FBy=mESD7%aq~SoTS$he;2Gpkasizaa{7<|rAm{(l>+I%BDeUDh{jKL zrxOMxZpq<^pbT5a%CKi;Y1-%e@%Ty0P8K&U6zqzX2BE0OJa4b9Z|whU|Bd&^2#)$8 z_RjRGe%&k7BP7dF@bNk!Tdv( zf!S=gdWKx_$Na#6w_Fr68J2Ixi%NV^v|R$oV$%X!LsFqW|C#2|{{$%1?;f+n)wr8r9_!TQQ8#ynoc^dLd>?h9CuAlA2o6dN=^|Aic4;1B-jKEkcC0ev;c1}37 z=*A*qRn}z=>nL6awi8%;Nsot7Hztxa00nrdeWiIfS%EUh zF=w(L@K>_{fC)bL@G)c!6*XC3>V<<=Y!|TXnT*n)=lFHx?&A4eJCymOYR2(&l5$>Q zc_rY9SE)xUeHD$_@;-28sy0A@clK@j_ej=Ey==f)236zu6s1uw1roHi^dqF01ph2) z{Fpxlii1lhqw9TQtgEB4_hch@1`{!3$LpN9>-RxbVaT}H2}CY9WCy0DpcO6eU#;(RA|u-BYIhiKAU}jMT!t1^ zEaCSbarDQ6crG=LS_Qb2JT+c`e>9%>;X~HeTP39azi^=J_D?vlQR&ocSEI#iS)LPm z_`zbf7}WlAz;p>6@bv83|sk()4&HgM zwtt5_3D}n9@);p^`C{{+2L@#7MvzgP&R_RcFaaGbp6K&a5-f9DCN)8iofDE7y}I z!~P;`QGmSI)vD&}i^96g#)Z!qC5|U$FwNXV?H8suDZSJR^%Q%@ zssU|^0(LC(EE~AM1X=@>&cTRO2spHP$)EZtIzEqtB8-x#G z3XABf-DL5Jy3K{miX#GtE<76gC+5nc1-Ew-u19+eZp z4kk9F7xD;kvZPEY9IzG#tC?m-M)uy|i`fl)Tf$dR(k&v#nl)W_4lxHz$L+0CDr!N# zWm()=>sJ8I8T-M1oqn%p#KQkaEN%3;2Cp5c7`WrK)@9%Qj``l7!*%;f7}kZ&F6PR} z0*RLUn~eKMu(7li$i!;3m!yy<28&$+rT0^keVbYA7(#!8io3yku10ZEHi89TGqm=* z=tK>lp;N2cudcmI$!qY{KJK7m)R4xhQaej4x%H0shpyA&7>9Y3;Umyq>AtLFmuiF?+`m#37PPpiIT2VeIrBJ(Hh=YnMFR zbn@+2YV!R%S;olG5@BMxxwmX4JsPB;gj(zDgY1}nqhI84psWysG2ykHG}En_oLkO1 z_wsPtm0vc!`;^tQ0;~f=%11VyX~Zj6R$>(l6lTQljlo zMRt!O($+X7eHq7d(snJL{LsWfX0flY&cx`OKAI^t5V!uH(H)hr$M-Y^T>Dvu-UW&8 zm~1Ipw1Kzk6YjGreG{H7rSDm%p%3S`eVL8)-O>v_(IvZ&5f;hnRA?Otd-g8I zghTciqxl1m8ipyO%#=>?ssnmg+-n_bBCYa8Sp}X}i~~NE9H^Gh`V9gbl%r!I47fpA4Q|UBFhirVBp5)N@{+DxqiG z+Qw}(LGQrqMx*HK=gahtaB$JZE?nq_46U(CX#oXvG zH_Ly=4)8h;1pQCd-$xB*I)elQn+1pc|A>g5%*2bDT+Z=-h=}ot1g8ju$fAzYk&Piu zK%glCwk<;p7Lgmprb?ceC-K02OU`t&=$l>8(9-&n`1sbntAo+>-QNFHOzTUS=#A}l zy6kN~NG5rK6WR6gd?np6|KlRp@bmRk3QSAI$m{X`r0Y4oHzsLgCk!_S&cd}*k6ioY#p>fn$Q#W`?n>MjP@k?15z#(!&4r;|ww4>{gmDh^#vlI9=@hdLG6fitd zL_KWam*gU@8I~MbWjs1_zZ_-aNRhfrF9w>~<>bnF$nx&^9>v%9cNfYvy;{oRZ{L!A-wi**u?4yUW{l!2*}2W~-3EJm~cDhkCZ5i_%m_4^)?Pz-jK5m5c1tNb0lvZ_0HFzPZo&W-nO=Nf1)(n` zD|5h+OXP7tbDs9=C9BS$gMAgXYV7b*g%fBLr}n<*5p8@xhg;_($MeJcSMQ*>zdD z*>MLcRu=&NG~u5}Ruk*koj>B+NoKx6v&nV1$X^CTEAuvAWzLFhM0~NRj@!f>nMSI! zC+qtQ-F)s)sK$ZPR7lRe?*!1}+*JE_n>AWefD8yC2`ibekF;lHvpHBKR!Pm z5NQ{`3Q_uYRnYZar|ABKfsn3eHc``}A)=8P;l^v=%Yq6|vqN4^--v)ESM1pC{J-2X z9e7PsjEKaT8XMc=<=n_0S>&Z|myr`@vu*2?#|RYNrBpxN?kNOUs<96H%b#lqtwJH( zXLtyUY)KPVmfVV~g^Kx_w4jwbBr-I#xDTenN4`+jga`sJzg71r0XHFkR$*YzLoNM} z!vreCpalOzD%Jl3Dtul((70^BFouBX{JhRqyL)1&l{KJfv4~W@>1%~x6(w<(@=r> z!_e=n>NgW}}zbV)~T+6chL42%WcGNz4dijp(95OXkeO``fa^46#_9%aSJ8INL^O+WZ>#z-5%>;WgRw0`(t&_gOsH~4h6$iK;RTcRNt|1Ne1Np4at;|lelK+ zc2d$hU#87V4iboxi*I*6Qk~kVpDw=Xn1d-Dkhsiz6A0M43aEd7zw#6UTaMNRsBt*} zo(!WgS_LU0FjOL)5FpJZ=;JR`A3dxWTp;R7o8rtUlXnia-tTMx)d#dzFPgGCj zZ|D*%gl%;}ERe1q8#9A4{TKkaHJb7g+@(5)SEH5QO{v#KbYh<|&MYi0A9s|c;SNBOo*n{;v#SB$M3&`$o_*l&r-ovp40sZ6K2%_ZEb5pHZ-Af+J{I+arRC*q02oK{7MLIgSFNQDBaWLd zH*s6F_vPlas$!=xBFV26x%URkHHVL|@5R#jT5HxVLIP*Jec+hfqzdB^FkBo&8DuIxm zg`%RH!GPTC$Fbi$)jj-d3N3C7iSq)&4y2~XF1Mm8bu=WvwkVp7Yb_$=1)g>GQp03> z<(IXNO-I53J+%2di4PJJ2rIqB3rR)uo!ub49ybjp(O!;HBd63)jcKMJjG6R7-zyki z0oTSq^>Fj52u0Ge<3J&dA-<8VjAm^8ulG7SRo!V3x zrkhYKYe$WG+`17xUJ-Q)!-oWiNko|DJ)TpnHHEPRTFN{<$} z(C9w?+b<;kKv$4t5j{+!iAoPMU)8nTx_J(waB+GV+WP{)G{VruDwpkFVZZ=8oIZ_Z z03G`21mqlpk~Xw=gPxH|nv(HD7)K>O*=mH=RM?64)%M3L1ZjKOf5R)k)}`;P3}jGy zroq}g1@Y(fwww!`|0TL4>4tP9( z@g@49`N$r}-@_6{uWxA48XN2U>Jz&obq@NW20+}GyyPSr#N+;D^vid%giZ)3xFj3^ z4?{k2n16E(1@gB4yaaV}gw}dy{~7Ae>n(i;z`x{0@9eURf0O){Ud|%9Uj6cTRk;5v zP@B>2X)~M;@v1OCh3ObyVz?cIqK0a&Fy<{Rg6%&C$KJT|hmN~$+Kp+Q#nV=5tp@8E z!Czs_L6|a^9k0g^(og2kgqhNul5a<>hY?u+{xfFkF%LFvKiO<$g{fZ)`}9Z{N&}_e zgJ9iOe>mbg03_-Df>r$o{JjX;?=tY~pKuEU3yo-JMG6H5rU{!&B4i6v>2;VBM)6-G zcTXN_DlA?1w<&JNDne9=rY(e5RELck^X|&yUaMJ3TZ*ed`9KNy;i?3SgwJ!W(z8sv z+e2vKx#@dn!Txr)^!o}7=|*{bZek+)B%CDhnTE$n^GbRrPrcl=@i&aX<6HJ z8Z_?TyI7m&##^>CRrlB1npjI`#k7p>WEsuP$mt9RwMuA_t0AgEO3e!kmBN;uS1u78 z_b}JYC_wXD-ZHjiJ|BJCs=v)Wlb7R*;zufSBg@mHn-tMs!2;{($CZ=>Cg>mTc1Gk4 z500>e=}{Krge{QmmYuZVUq!oH-06dBLy%FJwzb-LI1$1e*Da|*K&ehV$?*7huv_6bc!Q97L2*=}nS4$F2?1keT_cmtN@O#T%}kO?z8 zm6Oj`&n0`>QyV21tJ?`vzEc86?~^aNu2Y{kS4@AvxnZJrK)oMtOJP@%(NXPvv8rz5 zRcXbM6*ii-S#`@<*5uU|k;&`3yjrI@Na-m)s`|U9vRx{*Qc`1421k)rwMjL!%_Wq6 zIZOu1ve=ACbsU|hh7QNPaHn#zw*dP#l^MV!!$d`bTdJ;mAL+~W^h)85S!BKBm3J@j z-TRkurJv3mh(~O_iMBGTG{r5?W;rWw7LctQR#fhwEn7QOD-)gGYHW*<1j!}l^!>Yr zYP*TLYTGWWmOb1CfN-tE45x2pW3Q7z6vv!fS^YGN*YHSll{y=+VVYIAvIqFq_;LD1 z5xj(>*Vuaoe!u;L2n`8(J9G*LISBk&x0<gL2)yw{u z`-l_wBFnHVH2Rx|B3aeW7wKL3S zTZ!89)>|vXF?wtNZQ|qFlZTTF)f%c&+Ui z(=)ROo=oyAgky{TnCg@!o6qr{3?lL_#h`t0YEd?5>pasNi8Qz+_i8y}oL#6AMV8Ki z2xLBRw_qP6dJoRnF$z`85G|oZ1d8Vs51MThj!tZvjp-zEm2lWa$x}8n#ExiF zKDG;l$vS|2o@<$s9OX$C&#Rkt{xjd{rhOY?Xi;ZqdjmTakda+jsftXvQ%ZXU*DA2u z4x~|vBB^HX%Az&d;jJ;zf)hRk3cv$FU>{jcd`Q?`fnqL&*TC@IcobQF(S53jbmZ`v zHBI(WW$MWhU7*}ZZ{fBH`Y>pyL!mR@J1j7$6G-S6BaTi48J@+BS1y5$oxiJ!omX6+ zuo5J-DIWrJvV9xpmWh6oEfri!iA0l)dXNcir?j z(1b#5mXOkc3%Dc>nq#mg!2VCxtKcl0JdKG73(5%j!@s}14bF~A27j|6BIJ5FiU3{7DQycvb&UYL&iFv8=oo3`9qV4T~y^pS!s5FyigV z%zYdjLB7$tR!5WZs`ePJmpSFVcwIETdIAd~zz64{p(d5>_=_XSjt4`Zue=~@N#9qrK^tBQ1Z z@3HEE??Mq-aov%Wlxjcrg&#wb7w$-Jag zrl|IjaS$}wpVFhsPnnwpzh3WvkD!i=xqyfF=RiU0enXp3EKINI*GCn}_7{#XHG;f= zhGd&1MCz%~y`%qg27@WID}*Jwi$b1lek`MA`d8Uo#_&s!-%iQw)FMBOLw ztex$yu~MJdO(T>19a`()jB5&Wudh=`rl#%PCdp)M!!;CwR7KO}qGYREL^atue+2=) zt>YaCX_qhh`(a}|1OsbM?*Q_Dy>O`i*^x;tQY8$Y_8pI6yXgWcTZtdvUK7`>d))L8MomlcqWb%2SWoJ8dV#uZXH<>Z9iV z<|YGvs;hM}8I*K7K+jJYA4kpSL#oI1TuU?+B?=}~xUa0!($@HQa#?ShhmWZPlIWi3 z5k_X{?%DL4Y#~pLh2kB8T7&3s7w;^-F?hu-zA9UflV4Tvg3@_XC9*m^SF%fKRV8%DPRD!@2?w=WNz{> zVMvFTkX6dK!XJA>)1qRD_<%|i46{l!f~&Zt>>AIF52u7Gmy=jACB5T9fybEnkOsw@CKLG{j%F z^uV$$B5n|4JpLBllfN7aA*|N5^0Y~OxcM)tzqQPl;X^Lz9fjJ=&>n45Fy>Nu&fRJU zn(mRUA{Pgr4(IKVAp!=1Vrn}paa7{lUYvzus3929*Q>iLgE}i{VtZ#Q%+R$5!+|t) zymdwuZ-M%a-yGVCeiB^w3PYySeYPCEuJbxexOs!lC7F)$p}GkonC*Ct$@x($q}j~4 zUJ|tQE>}{UC(D@0Fv$R9b&hMKMj7_ql)`M^YuI9R<{`4BQbq=sP`?~0-R5^hh{NKD z!oQp#F;64_H6ky1PW)7_5j$Qx3~-oSK-JLQusCNkj*5(VmMD2>_%b&uFDV}$0^Xq# z&kPWWWmm*vlov)goxo{u12CoU)W+F#Ulnh3nEA6xVaa=5%{fN&;e|lPo;?bYz`L`0 zhx?HH(u;S~S5WAt9_u$LO?^}{;54D5QTt34EmX4c#ZXaS3S0v5s(8R@KbE6fyWmoK zptwm1`!QE+5R&1>oSt88{t2cvr@?y|69Z(1iiv2RQ$`$``ny3eq2?Dr4X*!&F1A_e zD#L`BC?x6*AZ2K;AKx`{677E`2Vi@1?N~v0zt}%NvhlAd3^SkgamK)Q!|zpzg(U5o zqr2Ax4oMTap79c`r(^>uv+mU$20r3o(IAt>wPY$WyvcdIlU1+9`I55F!7E8Atw5dP zzxZcEz|=|~kK&!K=aI@*kdR6}nD3Yq{ZuJ$g5F^yk72q;EiXawOtL~d(~ee_%{3gJ zOrWX!q4UMxm21AtkIeZC>uX&e8s0x}Z!BEKkSkJL;9ur=%#q7IoGJMXH3CF<%FlP# z8Q`DEhUz|IbUN-~AIe|a-jJCoPYhw0(4Nu&i`|cOtflYkjDi8u?vuOZs}-^;XdNNd zk@|x^Cc5mhzF_GzCpaZvL7l_$5)U}6v?*>ryGo~nRFH9M!*ME^cLST``3{b=)${)& z8Cz8|Eam>K!=U}2fecPY45a&C-}`5n)J?0!Qt#Ztnzuh0q{C3hi1q>}1Lxor{AWs< zu5<7_JI5mbXU0Vqe65j`n;&>Ci4>CMA0KQA70+_>Jj}VuxyxnSI=>P!{PV3f!a9s= zeEe6NmQP~#RH*GqaXU|ax!YW|x_vlI%TXC!9>oY_C|N7h$oInl&?-H`U7KO`^XoCc zr(fc1b*WpZ)|^Mip6b7~IkEnb)V7J|m#n>nUZ%Tyo>lnYW*z^mNeqeZBGUObi2~_u z38SS9jRk+=f>b1SZjP7U=qO`3 z7-jQcmjro)bzAxcf-Ln>&2;^80nVUNWbsf^8Z{$?eB-Bk+-|I8#Ye(=1B>HMlMWB& zp=sNuXS8@AspM`VG-eh&6bqt?n|tB64jiO3apr!1&`h$Xn6*uE;g+=g*Iu(g1nn?Q ze~p(4x*%#mgL)|(Fg8#D5s{sQ$#yxoi=^Bi@Qp80xgoz0WNPvFxd+jIl8eO?A*Rp$ zqhG=7M4o6esbx3TY*h5Qm>VmJcd~%P2P4Pq7zu{5tA|Y>-1y3(p?^cwgAq1W6z-L! zKy;WU?4x!Qk7KP7GWQ$@6WYYhrBGBan#A5tp_$`Nk{?sXgjqh3^u@fYu!iteR5H;x z0(z5IyMHAC6dC9WXr%m3-75UEz`!ad*8K`QACAqcs>68J2~KRojVRpOqP7MjhWT8l zys@hvebj#Fj{HyES@u8A zu&NlcPk(TS!j5^Kt#+hzVUt~;Ll7U^zOlz{5AWLPNz6s!XDYY!49IN78ZIOYC= zYU6zGvD(>GiXqn((b5rC`!l`5$N7M`grIIhD$%NYl}y)q7ZCe`A%I+HkEw*JV#U5g zR2>lrq?y-`h^TqMeEFaGY9ApQ1pTi-MEgU+3QM!AScxA06t>7V*{keXRhyt({m(Hkm+R!6eBc+jVY8g$nG)@kxRwOy7CHGkQtX1FI zuVyT*xjr`#$*Q?XTIx8bZ>^eIdoI_S>q_$d`AmikYfz1xNmA1X(z>RZX?=j)y_#up zFY?#5oZYf6lG66pU+04m@W+k3nbbC=Gn&9+!yJeXf0$}2qeb_bYA&al(Mybddd5&w z3OoYUSE_r}XhzisqL=nvsU>X%UIA~$7#Pq@%6Cnppv#$Tqj1hN229Pey3&@d=~Cc= z=>$qUuDC?&SMwRWL~orWE>&7X{LXTQf_7T71m<-)HsTum1mMSPxoc+tb1_eTbqg#Z;``GBc~hhI z{X^^X_8<|LPC8X6fJ-GrE3uU@u+)C7*GxM*I;Ug;MSHh(l>Aj91p?)?f*ye?Mk>zg zm1U^5%lP$T2UU{0#jxxE5-#rwm$%h0e_gcE=3RKHoOxMsMzse6c)7b;brEn`UNZ@y zq{~bR%qDY_sSad$kO2B!KJk=mmoN8KHh{I(PTG1fWe-8sJ zXmbZ`JJ*tvLGQIR(}(3@EIq5HNt|iZWC&N!#(rGGiYxV7*O;Z*#T;S;%3wQTsiW|9c)cI5#T!^= z)l_O?8VEE_f_ypE)o$oIPtS$ae>9=?yKZ42e+&I>YFFjcrWP~w7%$}jZp77oycKV& z#??&5YbQCm1fr>|YTPVPe}bLX_ZoY&XqTGpOR3$Ot@f))o{AOr7Un|s1ViAF@*RqD zlo&KpTU4Dfu~u{$#-4m`W_(W&>>0{wFK*J^a%S1ask7~BCKKnyMzFmbf4BPaF5EWH zi`xY%38xGX*)jz$WpsaDcOn(tRQ#Zt_u_p)HfHZ9W>c)JX1XsgXL`+y4PrIKVceEI}ND(>m{BUCl&yxJ%nj zEhUl3_D{hl2rJ&Dn^_o(f9eH#|A#7f5|>PS?S2xU^5af?T441H+QH4z&q|qtrSdoZ zehTg)P>Zf`OT}TvqR7~)S{D1Xln({=XOp+tkWXh)@+Lg$$B68tyi!Q#Ef9G@*;JJ0 z`9|@1sp1}9i4E;DFT77KykGvX37ONUTIr-TyF>3ce0ZR|Bu%Iee+s_jUQVUO0X*bh zPG2T^opR~J!#n~D1;Z<_V7jWy4(t(p&5t%b%1dF#`fag}*yd2LMH@p~dV02oeE7yB z(FqaxmbClZ+|ZVwV|kq}*x$wXsu;NM6QUb5)zr*T5u!g7s5@!9q2R~VyFvQHho1;! zLlf(0$Y5_BQuR<;f48(GTaHk2+&S`IOBHW|5QRdUogG5u8QBur>b!=em?e`alpjBK zyv2u~@w(!pBY>aFQ$B`YFgnr#!%Sc87~sP%*+&#lT#Ve@v`Vv z@6$)w6VK|(VLJO z3b?#ebQQ3(yMWyn7SPw~DL`wjEMTzJ8*XY|TIZ>&tn&_I&%w@77>VFj;bGYKIZ9^p zf1#YE7i*j`hy~8L5OvPD7|Wb7gwvgICC+k2*98HHF_QF%LSBu01r|+=GXjERQ}{48 z2KSEO+6wx$#-XlvsAH%Z#SIC`8OE!R;*Ij06^>djDwaHpIii{0epFxuRjuY&gE!&L z?gkZ2goc+J_c=Qxj^d^rcjE&ws&W?8`Vs#!d zj6(-tH*uEy;1PF0Wt}HDEI(t%&=xs{b4M|fsH@yPjJpfCx4N}}FGToJz!zguPpc;q ze2{zGPndJfp*m0O07BIHl|-z#RjWrtEGIK+Bq=y|LoP0nF^61QB3nHUecCu(S?#+AN`jm0YW2>l70ctET5)>3G7|UJdE!c4 zW!x8zS9_b{)k<@`R;;Y^9u@6aWYa2mk;8lkX@FlNov!lQ5?ve~nUIPZLoPJ(mKz{Xnszp!mhAP!hHq zqhf=^1f{@34WzXuJ~g+y)9upz%H7=>V&sSTFN_HqP5c4=DC4wfjN*eY_s*P|GjnF{ z{r3IyR{#&NEb#95xLJE+bfrC@&@na)yJxH!b`->(FHpGCp%rDyrX9~Gft5(PmaC-Wll5B3I3{K7j@@=bYA*_?5k-S6 z)-WkBdnkv}@@42+``tsbQw`Gs3)}Ubf30@oMQ69UwcV(9+O2xCv$y}eE>Ld#X0+0g zvd04YrtN#7mp&25RaRdL%>SMAH1m9il!lVP^yWCXgmWksFoW{~`HZDi`>ajJg+Ela zj*^rD4HpH9E~N)5;(5{|f#u3sC97wl5-#C#0dtt=#-n9~j)3`J+@G4c#1&i}X$f8A zNv-PXYIR&^FO5!91?DRMY@j44iA&;eznN^8eYt?XT~TPXM@pset$G_C9@;8R`wW zTrQ<96CD zaS}}x?Sk6cRbTDCyzYzLSF7fI&$)M!nPdX`-an5|!oByL-|u&R+xac$d8OR8ShtW-0~QwnRu76NRD%~)yhpG##X2EGx%j7nHugJj1m@2E=CYp71&0a6nQ$VLW zYJjaQP9lj$Nwaagk?w^N&t`IfA^1;qp%6Kl^5MbS3OYxp<#aAn`Q&+xR)VE;!t%&5 zy#Pdx0DBc(P)g@h6SyhjW*S|X^9D8Ckx-tt-t69($i%}NlF39;ql zeHLaX(?#oycs!Bzht0H^j3KJ{LsF%EP?f)bJCXF;%lo$&Nq=`T5%Y(zLAnsj{L7Z6 zmNj^27xW0gm;o2Lpokv#6>+;_F1?4|B>ga`(@v@I`T4%qIS@}9NAeiokA0iJ*3RB! z;;_*rm9ETosibny+DhADws_i0hO~P#by>d9VZ=-?g{?8@&Aq?jawA#gp&o4dhQ4Hf z0z#)FX39emxD$*YHDn-7rXc33B4QSCpkh)UqNtQI#*4(6pK zT_9($yZw0{6N*L<#$que9&Up{fsit>Ei#hQcAfg^Fm{&_jV2E7iXVz64#&4Ct%3?8 z9t_ZxC4jjKUp*eW2D{WE8_0l4pf?eJL$rA_^p)tdV&eHl^FiCx{8+0&7uV7ClAE`j zlKXA8#czZajATzH2H|%O^ub~?^OjX%03>gsx0TRa>1Hs0g@@jO5PU@@Vx~QGD@N9P z=yn)4HIPc1v4AwOhyDXwTan46BhkjTND8^`T@b3%O#3ZBzwHYH{zSJw-D~=Px9o2B zSDOtz4gSFT*npf}6C3C^q8YOW+u_|++lpEmn>ih+r zo~QqUjDf(uOV=Ez^U#Zb_&{DlDV6flcO*A;^j#!{RHiFsyLV-EYtcCUefoif{vl#+ zB3>Zv-q#uYPb;cLFwb&W_Q&)Ssj~lOTJgs5HToH%na!@Wa&rloA51U7}b;D<%yjCy$j$V?w`n~jj<<_ax`9}%zC$uDq zc(WbGnOcf@&Ku?SFZ5T*?cb0f6t|LD#p^#1y{eEGWFm(rSmRxi)yIj|DXg^Y=KN5ZZPygW~8_$i)` z-LL56%&{RJ_VPkmQ#{3I$WRXLT=;rSI%x}!*93efLOG*<3p(rd;b>fiUEDSyi`rT7 zV|-Q#FXd&q-lh;h;~Jf7Wq{>19cUoHio%d(`NwFMs*5xX+s8;s5}Tp5sC32)t){$F6*uEB zOp7M0nV*(_RMzK`2Pb8h zJZTIGfmUQuUV(tJr^kq@ur}W6Fyh2~i&a08w?CGNrX$$MeyhN0@Nl=zrVJ~KY^ZR; zO!;L?*K72fej`3$fdUep%(5vv%Uv+cX4s`IkvNorrVb$(uHUe+c~{%cgPV3VuW#FM za98Jlh8+htZ)@M+lb-4;qN27$PmkO@ zZ;?rFujTAF>U;ygmFbc_%{w|;J2v@Sd*Ud6EyMm$CY45`Y^l{R9o{b;-XFEkk0+Ih#+9+ALO&;FD?m!)cR^$sw3ihPHxqSeiTxg(@8tJlO-l-a?q=*oS9t`ZnC-vZmXrdk4p3h%LtKa zPSl8Xg^jAhgQcponQkjedxG&+7dw7`It5FoQ1|L$#vjW9yS@Bz{)A30{^SfdqYYa; zzHTJmpEzVTwkb*4&9u>NguvT?#t$Pf#Ks4hp34smHXbl~6JaYerK+sJQzX?*g(!~! z{&$nslBdS4nLNABh(X9cWS00l*5Ig5{ zIzPpqXF71ojdx0&osJiKC1mpxjE>kFj>s;tD`WM2((BG>cXKDDV;30hW-4X$nCl}wrYv#4Z)Ip@l(@VYSw3}!E=~jd{E&a7 z^AGsPOs-u!HwIRD7#*qyWLpN(GK$VFMsr__mw(1TmrD2r(nY2(Y{&zDYFG8X78z82 z#lMy`f0N6{Xw-WfTOvKJ@wBOO?eBmTRvgHrtH}MH{~&Sxh?(kEMF#fzv(7K^Ut}Zn z1Nrth*<~T8mF1hS#YmxU_@^vd?&E*K7Tb4h+p=NZP7nWk0;H8{U$r1#1LT#FK7}nv zjS05K6r6BaV`%W^nMXo@(M&4RuWs9#Lm{ZJ-H1brC~?;0`(6YBCgVobx)niDa0u#Z z+%P5jYOin$t%Oeq57UCFH(b?nP3TO?Q*Ne0Pb;=1Y-&a4ie`0X1>x02shDPYg*uHz zU0raNWFOIr8KO)lO`s`tHbg^*JfZ^Dj2#L`k}0pKRP~FH7jF@NH0()JWe=~IYmNJu z&R&y@mWvg- zSSHS4TK#`;LrutbRh|B=izZU$CGucBIxxQZvAUYbUBig;#VTE_6c-fqY&&~lwXh~u zBNC*drr9Sq_ZA7hMqH$e3&q-8vtD?yqlsofhTxfAv5ua9mEN`IZz#xq2|KI*{X{+88u3xhy_x1_-{?&PKp~bsg<-$ z6#FLJTZ#^`O*-iI+%b@S4Xm8L4cSNPZ->0A@!QwJZCVCm;AOAar;DK2?VvE1l4R7mls6Dl~P)fMQV-7>+-ceK5w{z%H7vF;^3;_U^&VEj}> z+yb7)mjmN0AZkWz{ln@u&2C00{2sH=W>$0?dh&I=^$;q}yX$RA%M`&lz`8a98t&Y0R z^4+z=w0DU1o!BbJYlrBv6NE~Irc;m((0r<*YFbM|+$sNLiJYVO6dJA3XbG`KYexZp zXni*mjgk&rIfd8RKmf!6@oq&;G7s0qd<))n`L_y|Xqpc~>O{_mYU^@5hw$57-dlco zmf}NnMV8XmPumFf2lwyq7@{N2N9bzT<5U+6I?9iBI?J!^%+d|zb&t^7bECIl^fo!V zCpU5jM&2n$g5`Gtu>3ub(A~py-w54*A8c}t&;!B1ar#J>J~2d}9-`wTlnpky0zT&u zJ^Cn}U}|#v+>g@JOvm_HpG&@fndwQ8Zql;!wPXAdpH}`2Wr~?2^gM7S>bC|*pTqdK zv-G`VAFW!ZQCYsY528_?s1PX(rPry=F z7qBad558th&6y3cR-$BifqXy5=ag(M8leY+9YgFdzaz^_j&pUE>tH;WWoz0b-*T3A zS8yQ9X9rhm_Y!o2&lOo-xo2?nd3;oAKDVP%lY+RNmq|0b4_dR2NYAc+tKd~byn2|M zn_P0qVBnz7HN@+)ys3g)v)pE_aFV?E^tp%ml080Wu>2^-z}KGRyvK)^y~n822XAd| za+e>)IJ{4>e873VbRg^FGUo?rj?b;W99a&5GQz+hnImilE4XKfdrw%em&@0OIk5+8 z4s%MaUn#k5f-u1GX-)8dnLq_+hWW@8voq9)8&oiqo3(^hayG%@kQ$;YIj=fNnsbnx z4msIW;`8`Qa(YlB*mEvli8V0HZqEe3oyo&+3Y!B2P=LfLXFn{FW z5Pz)R=dOELEBNtTv_v#hF_CYl1*3F7X;utWKm8iruhCN)eV*tQTB%Xp zqI1t0rE(e7M-d)9MPUIZ!K?5brAa(I5;utpE63DA6%8YOrCq=ix?+&N0yr9O0-GbSN$C()SzEXB~P zRAWtC%%c>_S2W)sSyg%GBAH**yGl1FX*m)Nid_7^1XB&`15_@qqYCj>nk8<3rb_XBnk{}ubHu-Cu46X& z9P??OV-d}F)YAgT1+>tyk@Da{-;@tf6Jj z098BBqZ;RhRO{SLb9ei?)iOjMeG)P2sT64WX_jJzU8#2r3YQ%Svy z2$EF2q;#A|$B4%EaH~usX*<105vf~}5VOXxF&%8riaB@Fax3gitIvvgiZQ=iuSaPFrzMEwNdYU@z(b?`h@1>0+Vkv^Dt3uS( z9vl*&eKssD&JDIdO$&Xlz_4h-&rEve#$j>sAn99uuJ%DLug62C@`tw$GKij}7Z5nb z2KbCCD>ef|uHEz`HE&g7w%1mOEm9aMK#e7Tz~cH5(H3kU67BfDB-nnE%IcqR-bZ@9 zV@3NQxwyUlBz2C6&fxy7fY_N8d)g5-7X}eDhsA-c0J~koqPsRLF0T;LtmwmRDPn5* zn$8Mw1%@+Y6)EHEsy$h8bi7b)bJPOt+B!S-PT-u|Pvn#ft5k^Vl~tBx#f=r>CTZS( zk^)`V*4v62!}95{iIq2i_>OVVF@TaO094IfA#Sf767M{L0N+Rbj(3P#X@G80&s*sp z`Q#V*hvEVxiiIIiDxZQyiF%d@uc*Oux|pe+v&ACyTq0`JvqfxjAh3%~;t~bl zDR#@JgB_*nIn7a~p5=}z^<3syE1!0Miux(d9Yy8s(fEW6o_rrF^jx@=`Ql~LU!hqn z(@Jp|74ToBxQB*RcAAdNF$J6gQ6YIXqIVt;je+3B!)`l?OeRJ7P!i;3*+wXm3uMLu zl{JX;w{`m5{WD8{R^@?KlU(_k{t9y)y1h)vyl)a8UnkPXWIWavpA#I@qBpXO6 z%P(;!4#_S{+^W)EKP{wrNPCNr_Nu`0Mu=e|?e&6_K49Df!G=Kjv!L@i(EkO}-XDhAErcn_XlVjhNXKE$8qhyDjpO9u!{XBbU_7ytn6GLzvb9FyB^F@FnuTV)mhe@WYW zn`W<;Zp#>>lnuJBX~$q?1Q?8tL8TO2H)`0R-X^#09Z7CUZnohA6%i0cd5Ah5D!zt_ zirA%v@(^*Gpn@n5AE+oIDx!#}h)DgPFUgvgw$R@%J@beWX6tSKm}0bCZKk!txw96;8Two9k&iVOtrSn*&xR92>A> z7i6-@Ons!!N@VP&`oaEi(i#jq!ee!Bs}*lOmbB?L#q)jHM1l*M0V{kIQ9IS|q-;Cw zr24tK-A-pHi|cEek8WNQj@#So-)llC1iIX8I%aQh61Ku(H-FvV(x0~C3A<%S+8P|R z(=F|(jAtbhOOG;8rZ9J#wcTn-SgHP&vwFALG0#AS!XbJ!>p6**n45}a(`h^9wY2e= z)tj&lm^`@MN-RydF)MMdGnkh)yF(vy+!n!)SEv%2xRdeLJ86ZQB9?Y~v*M}E>BNCU zDcft=ys@2!=6?wprS>`f*|hek!t#zO4C&6pwo+1_ukZ$(%+i%KeyT$S>xJ$FC*^o+ z719k8^_~hVsy7qMx2)sxbAp(M>PnQOHi!VKCjql&q78+i3%h0jv=52HAC5Nqe#ed2%ufqgj}>(9`0BR9qq4@J7Nno-K$X zi=(hgq#aG;o81dctX42RH%}GBu_9mv)+ii4WdtWk(XNY#LXwwGh8ammx#^3vW6urZ zM68wFlYgkLlMyaKtjjN*qA-WXuItUXiL7UzZFvJhtj}9_s=}h_Q^LS$ypUEbW@ng@ zE18r14KrrYn^`f#;iU!GCWVH+YscFHI2~sw9QhUx890;L<_S-ClXSpYl8~J^dqSD$ zx+vq>Ndp_{IXlgJU3)<7v#F&=U2Q8#4K`tOC4ahb4)1uMSxMSPn9t5 zKvbli%Stf?Ljzlxbc3>xU`42%DwP=I^U)K)d3Yzo7-s?YXhm;6j4>t;!`POvG8u}P zkhFS{D%j|g+toj{)26!21{^9=TGhG+tW~R9yRyk3E)a{hAyK@Jg(_koHPNG5eFKAZ ze}A7V#oP8`0}6*unbyTpB-W;pksy1t*4{}SGC^$5Tf2i=jTiAYH<4hvQ@e}-rhKKH z9P}>g;0eZ}=m||JYjniB@ty$Qh4+#)!4(ltr_F0vzGZUFcpu&`@;<;zGHK7i2aBQ9 ztkMYLjhbSMZ|B#uYbUYh3-lw&_o3de3Zd-Jex6anSt{sn9yEW zr*a>|$E$D^uBMf5+&6G7Gm6c*)86R?@d>Q0!gaWwl{KXoK83?&;nQ?(!tL+3Dd^y- zE?|e=q_i7wVO&ctV=2K7kI`kX>&T22N&PtQz!dIATrO6n?*QAwf!)gFOjs(g1w#9rhfXiQ@l(;d>{-03O5- z6v{Vm+7Mo2;ztUN1&A@LNsf^WUZ%(t2E@_xl<0ePx8T>wg-{ILwvqZ6I%s5LtCpYhp z3aZ(}pXm-dDdVOhRPry<_kV1!(4K<$tGMUa_#0JoGtDVZIVS$ju|ZNU?NWb_HS~zL zG|W))Kk#yZeej>fnx8LYawF)ze=GPlcOB@6C3`&iAG}(LSMXno_S_D42YU}+6yu^x zsizeEKfE5mg&3nDJDgP9-H|aB-v}nhYtM30Ea?ZATG2LOrMv74vwwCfrmKqbt1_Nf z<@8UllPUz!REEOB@l$k(3^>IJQB_J-4e%9Xswx(;V^^;>)hrq>&DTn~DTn&%o2%yN zAxh1a3ch8U^j6gY6;L(g$w?*cNw+99wIKZXpsH2#g>nHe+8eeF6%rR%j<-Sj1t-4t zpgLGB4yZ+nqxEd6R)2ESc#lhFkZiiFuRZ4yspOvw#uIeDu_-jeY%?I~`ivxA-;AHS@ssbqv|KdWS;S+rX- zVff%xW?3-QQEU)}hhBbZ@?f7|r6NbGV*+ZG;xJz66vYSCv41QeTqX0y@p6!{y*hiR z9m{%BEb4f3l1@e*t{Ev0ym~4kV#(OEJMA5M>{ch}2}Ye*>;YQ(#%#)Sl6HwLCk52W z(nt>}))G5jSK9jO`pAtEIKI!Xb28MYjxS3mUdMK#_nJ+$o`GuPbDK(Zd3@2IX$@`? zO*za+q3p~idw=b;Ug3kSoRcAKM)}-%@@NAHg9XS3n}&R@X~^dt03YdVa1fv68;CXX zd#^~0qp|U-gzhVy-HtoTp@E$ARTR@aSjnR#F2@Z}MFwR`v2gVe8L2w%_P_Hf7;!H_66 zLNj*bneN)kid*nV$k>mEnlx23VrX`TI5>xU#DBZ@6*)c-F-Nu3kQoYu3!w<-DOZ+I zG7faeDE3CT%8C8aQ9MWuhw;Pehlla#Fdoa{$%vW5FG6O-*o{tcSY=2S?rVw`Ei!tl zpQc44_(KkVs($`}S;c*`r}_nL@rwtxRKzH2HESz?*5Kv%AV$D{^XHZADMlusSHG7BX#eYRN8S#1Wn1hKLd3QhoKqJ@nb5A%l(> zRZB@Xtd`N8Pm*9C8bTE{>d1&$b`Okbq<_*MGP>yQ%A8ukU_RBk8*}+vB#c(_V}5u< zwdNF!f039O78u@#!$M_6HK#0~*d^9}_5@Mqs@Tv@J*J)o)D!CG8h=(jFVJ_D?|T1i)uLfQg?%^qKBsYkg5To%lEwuJeyeYf z#svyK;v3btK*8_z-LG+hfZ{=7by74zE?CZ zQ1JiyD>N>UxWC%JKyVF-!>3MT*}WWf|HC;3mKo@L6|=`U_XP};>xI+xe^>wCW^lMs zz!*4K znxAXnt}$FbEs;wiD)iJC%BH6=uvb(4S`3?k>M5(s9H-${feI4X(v6n!jk3}Wae02@6&yCk z4qe7RT_EI0Dc_y>R64MssA)If-iyS?ID_LrH|e%;|9txK5)K2Gk?vY5_GPyC*AP(a zP^H!*sQNKWB{AE#7IS=?FxPh;=J{f%_VuI2cQFp~ccIpQKIZ%5Sm1ZC(4RoaKd9yS z_1NM6KTt~t2v012&%_J>0J0d9;V2xF8G1#3T32g5-FUYOp1LmLsi=4(h=L+02wtYU z(`__+AlcRn(FgG@yb!?)AHataXR9J21DTmW-~0*5`^W1WfDOzDJU%>}H}2e~3~ne1 z-5ob*xpg;4<4kFpt2FWAG$hsyX_A(Bvn{O`v?;i;o!GiNEvYTl-7NBAnR%-4*lccp z$#83%S=0ELZ*{b0!M3Hh#w{h0N{Ea~B38R(ET6@CV|9JC;f2(7?}s1+Di>+T1azo0 z2`r>0@*^WdP5!NsSw_Y`PHZl5idOvQ|b+Oq~30x?JSNZJ8R}Q;Ev=1?Cq28vKWsE(J=9OP3BD zj8#xZ)xi*khcSSfg9=89YEq#8fL{qUZp!>KeOxicRjpt+3l0aPyiRjBixLM=UB0?{ z!T8EEChE_adIEZAsb^981W-!{2$TxLlxhJ00OtXd;V2xF=zA}J3w&GEdH+uIxRR_q zY{yAN0=cncVoR2tgvJgEFUJYsSb1RQfk;ZYmagqfBwe9<700{=YuGy2*3q)HNmpQW z%xq;{vw<9%LSXBFveB-4cVl!L?H(;%JGO3v4ZQz%?v*V&GIU*j`RUy6obP<+JKy*J z9>=e|_r>Rk=tJUvPC=*dzI$-%9nHg9`k0>2G$)$VBh4MnX){+avYKs}`FPIE=$J3+ zSzWVqERJbbJUynTk6ERh)tng7vXtwHSA}%V51oKatLsEaSM;t2dq2Eo--y*W@WzR&O@)wqDF@ z*{%^Vc4f_f^f6qxYv+R7A>4n3kvHtC1bw*eee``_4Qnm#)9kTc%hGehS!{1VD9F>+ zelSc+XjzC9su#5F|Dm@+jUif2^3Q-+@T?BV(a@YEe8#f9X zt$9J$q1%$unTFZLhq;t=?U2o=+1CC(o7cNzAH$S?eLJe#eOb-21U0s`SILr-+ro4S ztz|2yg2L6uD%1>z=qC)zwxq#s3e$RO4N(hSItOl!P71XNYLc@h+sJnHnb|B*2xMCd zMFj=*T*015LYkn4iXM`a=b%Oh#X}UMPOxS%!z$q1`nLANbFC4kjkJli*eq!2yfp=Z zO^vgEqI-))O`fSxcZhn}({+Zm!ze;Cvp5l^%bg1)a6v5t^f$F7=f}}DzW5b%CGQ6^ zm&{dMp=$&whP9J#7pCphT1UOqC+L>zq<7Q|n2N@5i7laSXtg$|8B@2^ylJaxGjD4~ zUe)pwU~_abbgNU{d7=P9Pkju`ojs-Mt*(sp)2-892D(HWqf@Xv@@%xN&`*)FrwNt;K4L>5R6dDlJ()NKcl`*zEL`m8s$ZHw5>k>)*VcJJGu%QMK z>I)jmwT}fem}>6FwbFhZi4b7l_P1YXkuV*kL#)b;;L94r0lJA10e#zR7-PF>+E7z} zE9{11L$+2#s#w2Cp$~`XW=2>0T$|*z9Onz0vrY{d-@+$pf_8l{R`__W$XA^~jap+D z?wc000yV`LnW*H%KDS^A+EN20AM8W`eCYb#_~tF$0UAXqkt~*;E)@-XqH8yD8q(kn zV^rsGFc4xew?s=m4S#Q{ai;5s+A?5&nq!m=(X9lHS5|A+pD&bbh|sm1LMA7Nxyn0u zyDdZoLNQu&c)LP&B_Dui&i3N~B)$;yzP7{L8ImVxB1GeKJEE#o$Y?fnSFqII&tmVS zyI7;UE8^sB_Ky|Kac!7$PC^#j9;W-~r&!2;Pgky0 zWs>bBBb(t`@-rd2pOI8Q%h8X5B&j7+reh*!dM1xn8ry`-J+1lPv<-(;O{?z0LBld^b0(UR1VV@=u8N`;aTL4QvPTk1c~vY5{T@OMubtgyQQw)>bC8P2 z{C#e3zDzG759Rd}w!1Jtwr48q%k&jye+3ok0(*_n=UQ>8l*cuhQ3$ zaTe^yIp+5lHGVaJX-+f3nepprUM+1zW(1Zc=+Yl4XF;<9xnt-a zaM!js6bZ zr7WE@tAe`PlC@1&xy;z9#ZeT{j+P3)GS&;Vx3rzoQfA$ZwXZa+1aT_v;A|$C=1C! z)QC&P1~wO-oejWhx|BuBcEHk$y`zvA7EvGs%P}B?XXA1@AmWu|bb(MsbU~D*+k;~@NbDDfu)(mn zdoC7B1#~!JkwQ|(%1u7vf6It)68eTw1c=4Yc|Cu@pRwjg_4*z9h*rwl6?)&i?KuB` zW^t6=e9PRwEB#*uDPkDqxzhaMv1ymAzA;=>myecRyBI7Pp@&3Tj3Bqpw0Gm0r5dxh z?hJ@As6&W(3W#G!t3~-R-EW3PjysSRfyk?`PHnQY3Kd4&t7B!lEH&^F`6s7;5IskKJ*ngr zZGG-4Pq(+pd+}p*akR<1IhF90Y1=6Z#Ul7!opn@HTN}oQl928gx_juB9J)&>DM1?P zW?~MiitQDZi0>zw71BTJz62zy0oapLNbzv)|eKd0H;Vm8#RS z0_g>D1HwJgM8Rd}2HM(4IdOU6_65&vXFrN47bVe&g8i7cpeu+C?eV(xlr2G(xToT> zrQj3sMzapaWMz2@Y>f##7Qd)@i=%6gS~qt-c5lLy7i>T2I3ckT-veI1bQG0Z z7T<6DqT51A4kdDq#4I1Y=6Ss&9bIg0hhx;1Z9|@Nv{K*m_D6rgc*-C=RIqjlD!&~+ zxM&r}df$Z%xt<-{Z~N`k^pJbBtZ7Jfv+XXwe?1zXlJ{3^7Thq{&0Gsky(O+EaOsk? z`%%nirGs_^GsyceiK&%`N$T`fkA1T9jz7hv_WKo??{I9KXBEh>t;VV)>V1gmAXL1d zd+Pa_vefApY#KNILR{^Z_oka+LG6vr5w~yX&8@Ha8t2piZvf%de%~#t@5iZK`=g#W zeleo!Y8^vAY%llfPt4eYM{qh?CkS|^`(`5Xg=ep~YIQVO zQ`n}~rM?g-g|#P%CLQ?Z%P!3&R9p5_Q`=p{M$WoSKv{)1n@3eRM`4I+?s%%|QZJ%` zUk=|{^_o)`C+tfY=8ack5D~JeO|d2Y#AZMb+sn2-?pli@cz&@`)yxXQ+PW?4NqT80 zWiy!OPPqf&l3BUgnPU7}IZv~=AaE|X)yFu#fGYVYa^1AkD`8pEX^tuZMEfI7nWm3N zeB{DpztvR@Q~xO}A-;FU;lbM2Bwz8scb}uLbaN+0EB@C?JA_Aj(F4a^0xbND`t4YW z(oSY3!s4seNqwUe^`+BJPfl8SZ@Bt4Re%M|hli*T#MM(fI~?ij*KYC)`BU z6OMBqe_n?_=`*hKZ5 zA;eObYVyf8Y6#XJaerxe03PSJbBL0IzfaU%jO$p~8yM3f6Wh8k$FKlY=Fv<5=Qcbu4Co2BVpYDJ^^Txpt?rMYp3v0w@6O z?>HX3Ywyf4t10GM+fV2}qm{NEjiMM@gB;k-H|INnYX-cQ6LWHBLNu_bhk6o?5Awz| zy}>5X^NtAhslf}3oN2$88t7O$>^}xA`0+On_-XY!hVXrV_`ZZr#n*Mjc9}I=BuaHt zLzEZhS?X%c8QnF{5qX-t2p{p_WJ@@%5Qg}AKw zH-05y{kV1cth>)tb8}?V$1uVM)KjQ9cvufmPTWi4k5^p=pO2qQ9bY((GjF*ieM{UL z(=nJ7=eN{r$W|(;KwfIdFX7ZAn6@y3#{;SfinKGOFG{kn2*=lmc;3+vRI_+Jm@8=jVmBW z&jkzGK3UbIE>^D4STFbOTm;}LwKDL@M;q&R_ln>@*2=CQ>_Kxp-SMnWoh3M)>B&0n zwY978sGH)_r4%dR(w~{6^8%lVMZH^8ve^p|w-GBVrk!oao_B~5JD#PnrB7Y-``%Bd zKgRvM6uvGhXT?(zOA#VO^LP>MSW=PdH4nFt)(-a3HTUltN*tqmB^Dms(u(G;b|oCm z1+o9F9TmQeFet%k1(tk=S~JYk+<6DZGUggLFpRwN z6*YV>F5PL!Att9xLvr?x^;!1u`|qlw!_B6q9f(h07_h^MiTX*3#@^U~)tOHopXT&Z zbzyG)L*EiNS~J!^p=<@$px~fz3VN52L9onsB5DcBw%;va_ayzu%zy=qBvEP> zO)_qf2j7Z^(PlN`-WAaQH2qoUoG{$d z6fKA!mplusqYO_zZgk-H)+9oO)V{#d8htG4*fE@I8hWksRa`gyTokrjwKJnX8(K~x zOR3G(|GK&4ur;=7bP6&fN=jJRN$24aqD~8YA&?((8+kRxIGj*5PU{a86Tr)2>DP=W z0%1;OCaM+tCFS~Hz)n7GI%7!i2R&QecphUdX}%-z71}AxG|%&JH_d(3p1wCO@j7TI zTFp2)7;}hoh?Ns9ltM^?Q@dj{q^1BL`RFQ4|?M$bR?|{R}{bRIbMc`>qc-tE5rZ$S>eF7 z0nwnQr9g;YyqYqSG;Ub=NHtHCNbqF2950z%tSq54^5d8J2?1&vRz=Vp>NaK<+HW*V zUCAq5NZu^9^6usW)9V2@Wf`~EzP|uLmUDOqbx)U3HF)J3b2*X-O08X4^m2&j%}S4l zRgNRmjCe!iE_kKCmxfMvaq2KL^YO=p*G0AyKGc9b7E|xykzdytonLVdY~l|ORv8z2 zrUF;tqbsjZ+ls1KZ%#ukD9~B~HzbWY;v$OT{G4QKn+ZqW`7U^78J$S`Yr;Y+;dH-7 zl`Fe|pZ}SWCP|H0AJOH5`neBS-wOwc`BC`CJc@=MBKX~8z6lz=vD^L(5lX`-IYph~ zYRH@73nq3zFEKqN$wkF#(nEjbIQO+Mx`utQ#GZ?ER;BHSfeN^cPJ-qg5 z_gC#xC0-VSt;wV=qr&=HyQepoR7R%4(Khs{Ln4Nt6yp=s_LYIJ3}k7;F>b+i(^Y4k z)Dw?3ElsZo=j-&ZRxxbZG1^R-o3e6<~BuWiS!6(#-ZY{ z4vZvfX<{0-aG)znwirmW)^l83$#F_AEz=`p@Cv1cw6H50tU4)|qdAV8mODA*cVj(f zu=Ets+wfFQB~8Uxe=i)E?vOp40~rv)#BU+W5!FyIPw~(}QxFOksa4D&dk0EU zBI@zoDaIuY$*A{NAZT`%1$A>4XK{(Ww~0InhdCMvZ;8c$xiv_t8q!ypSSe8`F&E4I zvx~7HPAO9l!}RieFht4JlfzQKxJzg`dh=#QKS#1(R8~nFNX#zS-;(!@`vS#Gv~EXC z&eQSonzW0LUx=o8$wg!ie77Z^omeXPSXxL{QPZpI`iYOe91G@l_kov~`ATqYljI2Cf>mccb zShOk>&p6A*zit<%$wLFh}3t^Q$e|D_Jv8<%XqS`y+_5pGA%wq z0b<`U9?^=vqw*5>GB{`JhF)l?4ip+)==ShilPE$aDon{OeyZI z_hyl1fc!(*Ye`X@^MmB9h-zDh^H;5)08@e{AS=r99_z~z6{5cRgaeEYOW`k?9G6AK zkHJt&b7$iWU!SSj*!%@bestNXI7^X<*eFnetDquf8y+hKTs^`=dJqDT@mh@lGkJ@u;;Y3F*t6D z!dK0Izp;}R4h}ur;IXK?#@ofskLY|0BNbIby3QzB?IvIun>cr%xcTYt`Ow+P5+o^< zG0fbATe-SOzO>w{czZ_N@4bV<1>qfLG+m(&?@P;#FUS1(licY<^%Ll-<@R}0$2*w7 z@CLJ}-Nkk4CH1S|IIW~W=_vA}A&u=1j5+I>&p#KVF{0m`3N~B|%E28@be6j8u&l9W zHi@%lUq9ncJX5GJ15B(?_TW-!|Bxlc9>qCyJ8%k7n55XmoV7)1WGB@cua+7gUgtKh zEk)qC`yUGJlGOZXL_beJAV+_VQZr}AASb8Qyu_WkA35X zt0r5c{{80_2^2RK70OZugaknEe7F0?r1IW!y)}|bDC?&?LwxJXPIS~gFC+Ze-8Y&qkM!~l?u>JUyk*}>X(WtA(&66dRHdrzMf;`EyE_-6$!&m=Q;B7Lm zo|+*2r?0xnGujwqwYvS|+SX)^@-rJl9(q0K^)fnc!p|})Y+}fwnAROa$e60ajz516 z`|MEGO+MKNz(wqQ|5PYyr!}7!k!LYss!m#kP2~+mgTAHwWwxV`M`cC7M?vFr$qTel z4cm|+y|RI=_AUr3yJ6raBh72VDc;vI+1qHLotd$S~;xnA*Z%^up!L-Wg;dFi_0v$aVjdCqNzrttVfZ*~8GsJg92ihcB+n1YKSTG@49|0?&4ABF>zRkT;vh-UZPeljA*= z{2IS-hB5*<3#P11b)h?x>h9l;JF^(8>CE>LSc~32kd38ve_?W!*!vJrN6X7Pu%+~Pmha3l_0NZuUx_L=xE5tzCkGCKQD^zh|eghq4wtrKwNoOUyt zTqg=W+FE0;`4OxU;Mrw=aDhS9v)6J#;Qb@G&-j|G!f#dG^6=?e^TW2kJTaQV2s-|;VnL~4q+A(_tyA; zYF2s!2O=9+Ny~mo%fr1~P$kWpNDd6=R^gUzNeIfXl<6zX%lLQBf4irB*X#3u}u-ycS?8AVk=dX9a=r`~t!ab;!^M_BRY zP<`9Nt4|Z6x390WJ9<)>5dD2a#u!g<2Ge6Oee|8;>?YfKJy`E8y4#buYMMlQ5%Btg zW&>~}&K1UB%D?=nwyc0XXSE;^_6YO_^P(C>8J=F7l}t>YK6 zkHFz$S($`{*)6p$f5{9yOqw7H>pVQ62P-g+!$ukaMAACC8jKnILzrPfRr=^A$~HZ2 zyA$BlSsBP7ohGd5A)`ydUy$!|AuoDHGm? zX&z4e7HSGP7K&m95RDP+kvK>K0p8SFC>Rw|?B_P?XIzd0UA8M9F!$NW7=6aGFUt*k z$y&tx7-`dM*V(G&s*Qy#D;TPP%>1Q4S)`zR*QrEovk<6@p=8IkP`SkQgOPAGSNlbD zimN4gp>4h0B@f9jZ=xke=Y58y4LQ$4S*W*{==xfzob=@0_n9=O-zK)k+=iogyXX*_ z2y=K@#oNfQyW2M=a@Zywb!3YsPwwrf+=sfs=6D86tmVq`O&70q@PlYaA$+RA6ogpj z5>Z_jEUUw0E>(g)pW~4b0~4BL-Xdq775jAVYHK8>4|X->TWh81Z7YykEc$AVgbFNT zL}L?jHMYNas}NBio`b_}WXH9Au(}1wnAz7i>Z+fft7}V4t-Q>%_S&D`&cBuR#U8tI z!Q=+X{eo;eQVX8&_(Wbtefb!F81+iM| zaiy1vqIXC?argM6s*mLyV){#6UjpC1@*4Cg(Mvp_lC?Da)RS@}Wh}VA4$DY_s1?z# z(*FodpLe}FK!;_Y`YPUpoR>y!@P%XD_cCdBNVy{(`jV`L8|gqgH%Zm;j&n$w1m-PxR9vaE%`RxaT_@U@%r2q~nR zhJs0NC?ij2GW`l&^6HR&R69%ovi$~~IuP&Ra%2;8G#Zy{IcB>s+Y?d`2K_Fvm z9S+)bzYUKLR9(T}edXlqHldc;uxT*MOwttnLu<=-Yv7aVFpdi>T{;1~UXEKDCt%`X zaL3EFfR&gN&s;4;yy(^w2$>lk$IDdfUv}|L3YHVo!ZNAjS<0vJ1sjM?khY*OlA5_* zN9wg9Z~mN&TY6&$M6WrU-Fm!&v1CC}Srdke=-oz_H?e!;Oi5I1N=7mP3|QS~z77nI zJD3v6YkQMxIpYKjZ&kEsdLL2vP-x88IK+Gwb|)7)H|d&qea>5``=MBZ%$Mm=Fp1^5 z_s>BQWzLte7sL@0v6Z93L6E*|7aaL4tsd#;;-TxK7x*{PiPGY4jK*KYc0WLm#h1`e z3x)kML#QQXJqCxjcXQUP;Hwv2&Rb5nyr-%^tcrzxw-NUVJF$kI`A@pUKIp7U+{7Dx zgDWUm#Of=SjJYRIKyI@WlhfBV&Pwsd6ih=d+Vj49%pj4SlVfR;1s|e*>MK*6v}D73 zVkKrJ5m#M}Ti5Bbj$j{*d&4jN2+Yersgw7W#W-p~0maQh3=cz&Aa*Y`4N4M)?R$ms z33Z3U8Qul&4oMmPjnwB|hk0OYWsiP;9|c4I?^$#8k8R_JlI3~=RARgMlmd3*u?@&M4` z$N&Gq#er(&r~=I^!gk}}GxRTT(PXB3Kn5-x073(BiJ&W`xX3dqw93%i9Ad;Ug1h55 zxu{SL0*c?~fOsINoHjfF6cqpvzZXQA_#c>%nBfjCx?R9Ag@d9v0D#0j7>E3CSRBPZ zgg;jms+miKxJLU=gs5D8AUNEkcLtuXGTh1Pe(OAjf54Tz2hbsU>bvevpFBUxhmSr0 z-bnafciYVO8hGWg0UH8r)ac-#HGD99_uy;Rf5Gf1cmD8D+2aH`5XRi{*7}7|1p^SFFYy;{a8Q;_r(1RymLr| zkNCHLJ;%Kis>I-+0_7hku>X$ILIMDlk|c-ji_!n?lky)2D)=>#z87jw<~ONwNByy5 z`R`4J1O`AQrD-4j%d-kPQA$nukDCWP?xTBg<&}T8P`n%QA6E$gfcqYmtO{LuO9YL7 zD**f>iT~deqtxM$G4PKhH~_$ZFN&Hr9H4@-D$(9`_iqJ5+IwJ!9vq~Et`yNw{9oV> zo;c?{#@hTYB~URRQ2OTo3UB|t9tDckpG5Yex2 zY80Y2p|T_$;;-U0A#}MTY=M(%cZq*s?CN+xQv9|t=0i-f% z{Q~l!uWW=CN21k%(4kvv0!P1zFc*kR+G6X{6ZVLqbYs5Ha{*-7!SD5Ly}D zqXd%BZd^OcvfSDU~D0AGrRW2-Tj9#AstuEo%o32G;Nm;y*R!pa}slC)5MuMIZKW89GX9r-e^P=3>QGcYfT#`APA7wjVrE$Ca zeZAZu`~inY%!!H7Q{w}$+Fc-6;z)y3*`+`j&q&Mr@i-Fm$Tos+QXYY!ftejVELA{V z!;4T^ewLK84Fu6q3y$JxoMN2eQd+txZG>3Z3aXNKulYL*;*G;29@-EW9m-&*BH<1g zp^&7=M`~x}W2$1>?@_VB28gd_Gb$+_mtKLrh)K$B=qz76g8ixQ0V>lAWZf_t344m)qaL$-6%r%d)aQ0(cIvu~PNyF0Ll zum3gzoP*C8Fp#v`>Rb3nuVvQ~S^2XRGZyUg;VTGN%~2bV3=u75_{o;4cOJn_C@Wju zFJX!8;}>Z1Pr4RbOw3xL!dc(P%VIR6k&mGF7#>jX*(ZHc<0*h_5YME2E}w@Sn)Wk_ zAmQp)bAGST;Tjh{H#-EL>uYh|v3yUEZMxn5Gx@!2W;C7B25lek6tT_tb`({R=nOz}!*bQ0S~WL5=a$R($}Dr=z%PJ?L40#NIY3~_qiYT+IEJ}gdEvcv zoOzcy?)|!dTtW{f<`}fQcz5hxFTY5%oEogFM6TkiC|lNUtcsNQ1~RrzQAQhz$jTQkSZOwRs4|1&49b{^5b#QCu)k>o>&((guBmiz@``H5 zLA1fvE2ar_2+PF!B-7txk<6PCG}LmM0vJa;OODR=(hcE3QTr+Lrm3ki@k_GAycZfj zTcnvyPTAafcOT`$MTbcn&tG1&>gwq8LV&wEg_l)UKduho-Ek5+r+o?YlJgd80D51R z(5_@-GBGp9NbA@1OgaQnps(oCNa=HjwmeTLTMPSPItqA`zbS-<$ikt4j;=qJhB> zh~8Q4^!8_x7QuPsEIM~c%)UY1$(nkTlpMkR7aU>4h`Jfgq`1ZwbOiD19mgpGikzz z9S{7^v}?}J?35Bji*k5{jA2z&=s-)t_JE}pIgRbcD9Dp{lCLW6(-iBJ+K-A@*I9{O z3gP2z(>MoEUQK+W2C>&92}E5jwb6~To=+=M8q!$L86y4oA6je3|K1vnI!CP9zh+_7#21gje+N_y9`;~qQo+Lu}f{!=4K=s%ydVMZL z{vo`8(3l^Rjf`r2LOB6d`f)XL^Icq-AlFYAX!yuIgz7rGBkfW{sF=IxaBFCUL2SRo zpl0zB)ew>~snz|avqwxc+&vJ%FKdstazi=f4IEO5*zf9RwJdF3f*+>L4Lal*1+mp1Px%Vt(i z=NpivUBH(@4k5||HYQJ=g3iuTuqL&z$=fE8s<|@1hpLjN;~$+0%kiBDuZ61g@5U?8 zp-q;zmD2ej+O0QJcD*poHLXWH3VZhd3Sh1jW1l5wXKo*DtIEJih;dlY>yX%5YA#2Vks}vj9 z$^G9F3M<-mg!~QfDu*!s9x;!kkju4$Qw!7h1^D>{eFwdCLx5(sf4{O7>ZWF+s4?7B z&qyJT7OtTfU}>3$s-b2Iu;pWWUNX>x6R3zUXlyM;Yn0el7&~q{hV;2@E^Oi<4rd$z z9{=V|;jeB0`z$ZbVOcKhE>may2L&ZG`f5vsbWl?mRajplq6KM&;js`D^&_n+6BL8A zZXW5e1Q){DML|)K1KJWp;5sy0ba`Wq6LQ>%(@yiICswyuEGo=s)Cw~^%PtfRj%0b^ zXNt5NYwRfnh0Ccr8@8n}^Mu4vDOxPVeYFNhwcB$*R=6q=C4H+aIjmIpA^;mB4G(5} zFl~}|kkoz>l3 zG3OlN{`LwANqLQl1!s>bBNR7siDy8;R0Gj%p5%$y%9bS+Ploew5>d!l=@|v*I`%AU zHKi~xr3$^B-YU+1&|b%M-^<+C8p#cnyf8tPa$8+xyu+FNp zegjPea}QCweL6^dmgbV8_>ijFD~!6F6Az8>B5xp4PQ|t*l)x>V7+TWZEn=n1M=AR= z$d^c75@g$OM4HF_-S93lt`h^a|G*MY??DI5+$<*=3i$PUqaT>Qd)ZXZJTG&De@90T__g5HxNXh|9}U+Oi9vYPX6T6PP@- z&}I^$ZvOD3BgVvTZM6@}8)}NcF?CcPWWoZ`xggKcI%9XCA~LqaTK_bAQJ}s{1A8h?6z} zYTy9B%8eLZ-N@U!7M0^%A;FxA-IM$FNJsT4%6f1oV>XbeYnH+!9{^cszEJD z6r$#y^mgTF99RR39;vM@o=ez-T-%rk2ONCA$b93Mv}Lx${e<{`9yc0*Z{9B_SgEUs z%ky!MT=2Qh?5v1r3+MBI9^G5Z_kqq)rR@;KYRkDNxrcK zE5m$Oku^NEq>;Z!>l?dsW~= ze$Q;<2cxY`HtUA?u)Dy)nKtkkAgSYe#?r1-*kmTZL#>k)p&pWmwA|K= ze-qWo>?78L1UrM{D9A2Vn%@c@Y)bEjUP~e|bkf$1KCbkt!5iLf948Mf;K#@oI#bd3 zljhcuB=jSO)TzT?r!v2$2|w?xu4acz%)IX*UujushXh=eK#m(eL1|X8OXIYg@hyPl z?lg^t^)h3~Rrhy(EIY1*O5}<+B$6sSIRsvz4>o(z8iaDIC+?|=_k(+>H6n|eJQ4Fu zLWGDiH8w;dM-t67x*Q5{^L)>Q?>n{N5-;ukh&Y+!TMI{mRPgEfdLQ521OJVKa7oLjLclH_9nzklHubkV7rRUA*#aM!{w=*|G`y<9wCwdJJp8q67M&W}kt+o8Yk`?zU3|b%HN#V2HV)9D0`C$sztEMo z|4_F-hDGbaYq4^ZuyPx4%gsAXC|)}rO@$ZIXhRunFCE$Gy9^kk*X2ULd%J~GbOV8gBBGP{b|j>#ABwv<0Fj6Gd|0Tc#$uAmB^K8m!()}V#w1f5Az6uKe#E_KG-D}w zZ9KcSvm!Rcdlwux2Y)5B;092!>gRQgGhj}FUyxbkh=G=fvVO+(0aj&pUC(gjFnWmI zux6RXuYAC@h}0w?l_KuUp*7wC=gAgXB;!W5RAS(IB!lRyX?>U`Fs)iNNDddu`E60j zkSWqECBzzzV7{=U1=ldBmgGN_yjM3ke4r0g~sCOxI8)3vQ=1!hsRw8}?^Gq*M_! zpg;fEvm3-=N~NrvclMKK&Xd#D<5Lbn4_K68!0z4XsMc#i`tfVG1N>Q3`BkZ;D*YNv z@gQ%*iG^F;FWA&R)C~-ijl=3<;1#^@HtlLPS3^IoI>{o0aKlT0*(>(T=%}KvO<*gN z?_rN}Jq`GVZgupW8VBeUmQZ&1*S&&7su4;yK0bk*HI!qiUpb61Yz?Ng5@wC8G=mIA zQ9Kg~y#`T{wwYC(#rg(iWt>uswE9TEA_V{O1PmR0ylbqtkYF64=Hd$oD2^u_^qJF_ zTfKowF^{lpVup3rsXLDcXbbfv&z#O?#+%PD_du(VtHI~{qzh!g7Ah4*6J}`s3xU!Y zoc9Y`kXNX?EIM!SXxLLQM5<1-Dr+CGtaMSJz7WIx}=_}cx2MI@bH?yR+ zhd3F4&`35t^NI9ng&_*VMV}@wQ31-9%5OTyjqRSH?&qm;y}!Srz(*?+nu;%##|Nx& ziM~-nqa91wWaqzdi?L5LHoc(DYYUsS|JhguO7Rw|N?#G)+LDC0NmWP2bvs1~v}OL$ z|DWWGAhC#7{z+a6>c8m%ib5RND~H4Q11~Xd1}q@uryOqk8KEGJwi1S@0^v8*d?m=z zG7g73FLIoq<&OF;MN$>MLSQdkS*RZvK?or9mzVJK&atQck*C?^<<}>K|MyCUXJ_A! z0&k1~9i4o+zzYGyzz2Z?O+pNJre(tva*0mCkPV`6VLM?)5l74M3FvhoL^Vw{j3~BQ zCv4GESW7dT=rQ$S`la$mu1W+f_rWe%NU3reO7sF{9WhJFCsB9DjcEZ683(-IG??+s z$#D^i2L%Sx$pKlkQa@TqyaE%~NJG?lp}1Vhh6YQH9Q^j3@r?V1AznG+Px|LD@rZL4 zu5fyVR;~rWLboLCCS4Fvs=}8IhWWbqo2vywX>)hWG&aM<_M}c?tmE+W_(fV$@3C6P zlM&7rYppQzLAum9Vv}+0_8G7Hyu05w?ix3n;**$GU$-KZsbK;|)4ZA4`f`{?4`_s~ zgVqTn7Jkpl+ShpKiXeVg13#;Feuev#I25^>&Az|U%a~m}?D6Uha3y57ovBzf@;oQ9 z(sq5|QK_epzNu*z+I$?1Hx`nG?(d8z*uf4&8kzHheW~NgY)Lz5m`;X|~xkoMA%^EKF`N%|+?u5Qu~vUS&OvtWVDQpAICJ7Z=P zf8V=tm6`!cp8|n_$1%qu^Z+%feb0S~mpBvYLt&(4N8(5pJF5``FYIN80z&R6c*L|3 z0w%zb)S)DX43-#l%O}-GdEUB-1i%p^#6GLEpMgKG@ira=MPud&awbk>NYYvqv z`t2(Znad+?5EVZGjt2;9K{xU$S!O&V;UnEoOf!rc%Q|7m7o!FMJgAyU*v*SD9PDjB zwx2f#d-ZE8<;p=9S<;on#by;y5WKMo02T{pyQNA*Ni4p#Ni}$eZ=6BhE+S0$eS=2# zvQKIaB@q=UaEkHCTN&;`)_4XLnH{z&bO!sytny{wE4~Kr!Tzd#hXaz)2`4|I`-W08 zQjp*L*F@>GxTAdkXLRBJBfSpGz29jl-F4v^>@i+Qz#4y@PTh4MN%lg z0{_3$V>&Y=V3Uz|={X1={=nQ9Pz@0(#1Rc9e3%_YZ?7-|zdk%6{gIygb}k0#m=T3gHGAeE43uP0=^JYWkhwf3~6av$FHV>)#i?`(ilb#?> zS@Nr@T#mCoT)hTuTc0({qnrEg z*qDgrVm;#>zvI|<&AiXtv!S+qtU`M;XT`;OlGbwW3s3v5NUg`S5XgD1Mfzw>6Q2YwIsm*>;s`=jl81;&&JtJm=9;(1nnDkWjSs6Zfy7Ea|B{ z5&Jr3c*j$mu?}B*PC8%!#a#^zr_y_*o9cZ6x2wJJq4M$UCT0~OV{l*zH~-|FbjP7Q z20INEjMU|Zvi;1H^R{IZ#i|$y)OgD?0|%}k{2YTkJjIU*qTUK_YXuN zgh<$Q6!s#*$X?0pLo-)l&v3CRMaoa2Kjxp?-hYPl`%{>9Qf&>7TM;z0y?bJ&!9h@! zc@q7^CS#1xi&4)2?gBUQv+9za+0)M&hge*&!^Ps?3ta~ooHp9=JF?qoNWT;u3p^zI zS?nJ7pzRnDvlQdRXHa#R0Ha2qlu&Y4MVaI zG)k!0(44U?qJk4bp`*N8L}^gQ{Svelkq+G?)Li*Hw235DrT2W_KD}S0_c*lPtd;vv zcHwI8HJdZ@rRZ(eul{m3UL~rH~j?oBWHK5v-bX3 zKqn*GeTcO~iB;wjs~MPFzS91ygIK0lS1{7_vbeE+=4exEFdBKnX&xi%#)?vPcQJ|3 zcjErR)ta{i?)<*yBBv^i3~Pf)-gRC@gR~#DkFgR}6Ek>!PSfP->g?i7{?v%@lL2z* z2i*#*IGQ@5^1qs|ER~8|ok3KUCdOs0PPH*7K043guCq%4%LM$JvybqPyH_MlO;5m0 zD%Ym&3i$arapYu7nGS)9hnW)-h0!=cE2YTQo}e^05y=htSm$Z97*+{xIfqmqDb$T| z(73rw9&@cWqO99ui=GyZ2NOh}-K}$S$04I$GJdP&+EcamU5fAY*zyy@UtV(!kb3}O zoJ9|cAlhSS9xyj8&ocuV3Z{=E>431vmOvl<(Z3BWP*hB2s_5ns4N{TGg$Cm2XmdccKmQE(EB* zW2SIN7`kYSP9;~x$c4C&i#_O~LkYK6(g%GAu2J-d5U>ETIP0V=aomB7u_>`-(>r&H z;ig-@fi@N=g`4On)_2?QG zLPYu{vzSAanS@MK8wKmT4EJ_JX5$-_VI8c7mPRmALuVOb2@Qa_B*e=FbE_o zq~;lQmcUC(xx8QUhPAcqfjaFzhfh46X#imNvUC@fm>jL+_{u(kVeFI3E|@VqgM=u& zs^VcI(on{KK%#Cr*t7x`BlzA0#~mB)WsuD`&lE~OAs3(`e!03(Pa8g&hgh>VI*QoH z0OXMP%3oi`m{0=TYmbD#=|P${UJAoO3(pWi^!JLqJ!TUB4yAO&P%5^HHu&J)m~VL+ zYp2Fh^-R8+i`RVJjAI%rKd?&1+Le*o6=M&N6yoptWu#>7|G`M*XNpaIC%JbxXP7USPp?5A136vIALlXL$g$EGN-T%o z_>8nT^_Lj8-wE*%T=Udrr?w$DMZ$W9*jU*sC@+|4jpOoGCK+ z*MG$`k9g*-4iXH^81}zeCzlZ|F{TA25s@7QxbB9g3ixzObelWXu*g*qAQ6#T$HiWs z!}bDO*MdxMlt{uZ4IQ13-O&iYiU)p{X>&XO|R4KpV}Svu+1r8 zRKK7z@p+tc#eZ?N&fW9zus;n}Y{V6Hq_eNuI&VLd{=&YtI?_whPkM;@q^RJ*;#q*p2jfCgqcsD zP1dQE+sY?GuT7PKW(u#LD$YHJn{JT^=;UO^gth$Q_k0cp2+FJ*j~TKDkeS1-$`L9$ zsB9jVt0S*qVBg+$1-J? zjyVviLZtBa%WSA@W;JSQ831TFHx5%;G(+9{m^RQDLNPCVt9t^GZbP#R=(t0i;`2ut zH&9#ta-0<;?M94ri}o{hS|gSWb(mzg4)5UPw3h4uKqeBfOo*=cl)HsdhL9LQ$eHa} zz06AiMJ70NlS~W>EC}$2V(=onE>UM!OL-xQAyJeYXlSTQTaf>*qxgf3xC_th+-(&I zDA-Fu7b#_o*gJKFN(LZNnuNAhv~7Qb&ksZT*S-dAm$%8YIk)@}Pebz%-znxAwa@F4 z3k=2rjen8Glewu4Wv=M7{m}Lfct-P!JypG))+O{!4M!;aoe!Ey2G z4tIji181H9N%Z5*!>P0%&9)kd^HoHeQ*DKeliE$PiF>8T%{C7p38Rv)Q*BC|;;HcP zC)3LCvY;9i)^sPbtSn?`2W5v9Gz2JzjHL1uDHlqHfnn|nm!Ed%d6qyWiAXLSL>n4^ z?n1(8yX+ zv1&KV_ud}m+wy`pk6*@c>q*sHF#Sf$zR$o2Vl5vMRwWC}WS7MOOob3KC&b;K&0#Nr zR%}m(7kNWCfn?cYXGK6EZnb}L} z`>&nhxK_OpY*b7MTUBgoU1V0s%?b{=XIggvleO&#X$!))!wobWI)+o zW$kplZ}(ug!l0;O=xDb~*p13P6d6``KPuKdBE4f#M4L@}pgRz`PQX9f1JB`JoMcOY zX7UZ0!D)zqd*F6yzJR|c^!WjSkdKFL&xl~@( z^x1f}DEvL&2vIdjN%Ti=WJpBdj$=n!u{FEosw_Owqo5B0G7-fy7+(?xt;ZeH#8boe z#NVgsVN8FBN`%g+VfIP#9_mH^xe@!9^5d%)DrwN#h>p2soCyk}{b-!afRTQ?z=I@` zPCQ4?V&c$jHh)x*$af$F@8}6W0sBHPins0Em2V9L2yQu5Fo>|IPAva?p?yFIpIZuFBfZ^J3_qY;5sH z6Gi!jn066b5=2I2l2Qzkt?4sDyyy%w0k`!j%k=`7?(SJ}h9h64K!LZl-ChO;+wHdk zK+FKcZi1EA+@<@}%ar?L=Ev2;I1r2`ca&jctz8wk*XVgIQHW>03fDfBiDn|nAJG<5 z-8C)kQ!w<86Ns~c9OJqh25$0ixmyu8&2=PV&uLfxtn(gBwz?G=;zlqgJE=SfwF;DBQ}? zyi+U+74tlHnB3YsY5EXJ8R#Lb@(6cPeCI6k z0dJ$?wu_~?w$kKP`8?#6EhA_uM6tr9gzha9iphzsn*0b}jK4#A&_@|7@}d-zMQS}F z?ZXZZB_`;my8`$RoT9u8jH3)ko@Cu73_&!DJW?3_c~8bTymZ=oEdde`iVQx{!kqnv zb2qDjyk@o!t)iEeO0pKV}3E8blfeT6Zl(wL9Z=DU9v?1<0RuB2iq{ zW;jA@78A|hx7|;Pvd^o#1Kb~~YBaIyAo4T=gM}F)Bjn+!gp?%meEhuwV2wk{DZqn+6}+j+*QD+{w`4L&&s`g>#ee<7y8JWD zH#SCbj5p0CbdUUM&W5lcLIHjA&m9G83kNr6S z^t*@{1l?%y8Y-u)ve@wf&$N+G>z$uDAld@|Qz!6;1#nurZ zMALGQQMqn(F{x@V7IQ2~Z~7c$Tr~2gY-uV*Cm?L_pfhD^Lqgp{a$Fbz76~313S2we zlQ1xJKCcWSZCrz$`FUb`%an(f=>4i?MKw|MXXxm7P2|{7c4T0tcL^&}|Iar)1Qu0Q zx7vs$Cbbzfjkg}i8tI0!v2RO|*yKJ`h%*PLi{4O*wEZ`<>bz5d&JDoG!wjt%A(&0` z*G=ZGIiN@jFq9pi-rl0 zqq`vVo6L>FxZ^xP0>?-skOa9ITIX;9ww^=AP;NOI`_jm>umkWv_-9T9TFOgz z+4>u0brGNJ9uNc-eK!WX5?pff>My!m>H{r3C{o7*G+VIn+snh@i#M<`4XW3D@16n6 zLmKa(L9~T->u5$h{QW5aatyY(`B{Q5oHGA^Tz*JZ@u=@#U<>{i*curzAnQ;ZrsPh$ zLoIQQ`gfvw)PZj#a{ms7_WWBLhc6yD8X79n>NtPh68b=3(*1JWfq146S^xG8HPzD9 zRn>KJ;)y`N=Nre6ZU}N}Dm~2A9Lgzz+x|VvVq#;)S$So2kp)$1^5So(Cz~|zaR({F zdF3TcLp{*Fix8UwdsSp*A&`q%I(BwcQlEeyy_(>CN&aXF{zq}rLy@UEVEAt|HKcAW za=rAm;FX|#T(oC=x4i%*OX%W;wVxRcwF{O0K}bp6;d@m{yIBr@Sveq|WqP#Lkc41$ z`-)sceIi)8bKb}p4*piW3h z3C~LLx8=)xtlWH;`a)qx#~oHE0lGS5Q=rK;+W(T`S?fJt%)i*+|1UPM!pMoShOmiOs<4Uua*RMl z`*}6=&&#=mDo1H4914}V#R3{QSz(0W$^axaP!j4=nV@JqSsl*XkmLEv?wVZukIw6% z{%j9JpVH^9qYr!f`dt)82s9vibJn*SVm0~` z;_ed`5VVD8WEpP#54TzcxQxXdG?S05Cp^6grPM&LcVjxd9jMOk)?s$(0fD3t;t>os z|AOm7$co5l!uH~y%6rLu*z{OjON7*q*sr(4A;dJnvL!Sl!Dfv}%ohD;7X`!V)b`Jp zHe32SE(L6U9!1 zcEMH9Tk;QJJj62`S*uw|2cpF8ITT4d|6mj5>S@ZI(Fs;Zbb)p{z#=w`8oc6({AmI)&X1TPEFr;NV z208iK>T}I`TZCM~_xD2UM$_->X^&)35&S&O6dNmK$Ri=M7lO;Q5WP+K5GVr$-FL}U z;DRW?WqxYw^Y`b?1G#@2adTv@_1@2m?7^u{QeWo)iZMNYe84UQJo%Bn9g@_ zxJSYQ2UZ^R6)Z7wb`!Uq8e(${WO|VoVZEi}o2q;MSTM48@I*?>mrY}33L)fBqM&+z zTSo1Oco<+it)S`0pz_KzbIN?@JabR5 zS3uVd)s}`;M;XAuR+tyk{?_Y+5}N2)5h*z;~>_ka6-e=ns-&hw3Oe+=PQx`zZurn#Rcu)w#E6z3aXnF&TJG?l{#~# z%~WHnIhPyBc_HLrQ7xo96e;sYG!TGgXw&vmSrKjHFpklsMTa+ft21!#U5SkJfb|g+ zoP0C?8r^BC_-FE3f`B$8i_Mm>(6WTGowiU~2R&9CCjUl4%EsD0$N+JyJ~0*an~}En zhpP!!N(zr@_)5${TV`CHrTK6(ZuXg8($x9pXlE))vpM#Lvk90gqHTsx25{JBcW}&! z6;bxG`aGOQRf&8Wolbav1BLG@P0c3zSPaW*NM`+h2utg}UdJLiPYJoITp^bVHdjyd zM^jU&7_qRpmPh1gO6SkhHiNewK^%Rh*?)Ny+EN(BjU#=cJ*66 z7uLd_3>Z7s*?WNGuruPYkp(Ypb8A)%t#`L_sUT)MhDGb(j9zxuScaO^%;=V4Zb7!( zlzUi~QP_#OcGiWTl01pw{WGoCsNZa+eFcX4$gg}v!D&wDiq>=LS>Wujg1%8C81%@` zMoesD#;d;9VunuCt;DzpLBz#f{LA@?F;ysri5Ul){RK+FIPMWEWB}KfaRC_qoCz;^ z{H~LdRQI?-QRosX6&YiZ0VG`d0sl}#3diFEF%;Tw#o4HzUpv_fo`HN8_wl0;_h^Pm zgwyldP+ioe1#iq+O~Bdqz-%cFPk&JMw8bmfm(?S8mcgS!h?Liu!#7(3#|K`vzEN;H z^bugrj0-I9>fJ3^9yk##V>`yo7t{^B&#;8kCk&|nFt?6r=CAxhW7IUh5s@VNd{?k{ zCjsA|`43{+zhPbA$^W+&dBZt9KKi#)MS=SNhiQp$qUeb$s*FG%Tve>E9us!%O*_KX z=76Hc7{a_ZxA}FJ0HH)ZLKwn~LOR-|(aUkO^vyI=Gd7rHuU~rp5#qF}ik(yuYp|Ov zBDq$U7|0?wBBFzDd7XI1|1=u0 ztlSuaNp|TQ+ud|t36XHl>`rVHib@%i1tDa#p&pGW zXMep=J@3D*;9k0ER46BwhFVrll*A;TP9TOJqyuGtf~GWnC6V6Z9?0nQVD474(^iuU zF7Bpp(Bm5w;Qelyx76fX;mGxdalHA}i-2zUY!Fx~#2O^sFgos3f5+rcvYapXx58Y5 zYy2sBeK4E{HlBZP!|HgSuM))@r#8i=`M#F)*11|IRLW`DI0zHprm$;ZtA=E5BNUSp z9D8&m3D(T`!6)%Z8Gdau*bF6^8nC2FAJ+!8x1}~uPec7A*q1Nrux~}+qe0ZI1xWvj zEd)Lq;PjV=OgP?JhGMSQ&BM_DM5wam)A2_bROjw5N?H%H;<0r|;A87%wMA02D^u*) zex9LBn2n}`Z!JT-WqQ7KMD_ywRFvskC`mw1(nBd@c$FYg zbU!UV?6(VjGzwj+!jaR9FIqN^)mY8YRRmTN66o#y-8vq4ZD(Pp&_oaA_*45kj2n?O zyD;eahx5roozmhR+OZFX?H5kQ{#&a8-+;qt+e0=BC&y?@tf;4y$7;}r3KBQERR!bf z++mW@ZymB_NePApIvdxkxV%^@2)OLU63>4N)irBB#J>IXqNqd4&UmiPIMX5_N)+Hd zUm_0bgyv?Sot$NakPb`QI0Cv{FB8__icyq7rdLIr{Sh_CpC4Kj>&IldCoJsBFy-0v zMOi`J8<9aCP!F|fK~sjl7`hr{E%mG-_@mP6n%cGjHA7W;8-dGl0;E5!6=hhtI(`DI zjt+eJmS)SXvD^IF5;&OFI87+LC5D0D?0>sba@F1MxG8aZySEsnyTA>SbjH)=wBgcP zvZA03ewoo3ZyQ4-ED1nHMM)Gj$ z8D(?52lr8Z4ibGZ0PwH6M6YYYa;S9OqfCmLCH^SyE{=#;1uVFJSK+SFX6-)T1LR{7 zR6aVVC%xSfV-@0K$R;w16MUdg0(@epwK1Lxfbkj9Y}3P28a)lhVI%S_e$-4&0$no9 zFlgwb(Bj~fuZVoqQ?3!adu_+%nTp=&nS-{4?A$jXPo_MVgQ?dTV;|jHc)en9`mS_EDUQ+;p@$*w z?InYu!NM$GMgWPsg>tA!#h6#RISxT>{9 zK%c6t<~;4HOo@_9!#t^YqobG9$nw3r((VTZJHi^-!KM;_v9L(82#ahD0Uh?#5{G2b zr*X*u>;q3$=Uv0!KPY2-IwbEz+M0Rs2b_B~7J)O9am6HU!P`Iua5ScdXKr&v#(ZJa z&tGOpZ@&vrKSkvISy4Y_p2U+^6->t#Rm~bc^b?;bcWaUqgWBU&Dmk%Ke|;gCEKK0O zvA^q*4DnmU*cA=@v`6>Ka4kxN*f_y>;#r#GIm#n1Krl7RFRWo=TwRSjlERtu5w8ta zlZG>X#x#6Wkl_Iew7OwS6JI2@QUoO{w?^d^*uk?Rx*Ib4LSo6~6QZ7G_Hls_*<57} znftLMD(@S;jr+}1%4SUPQQC#%X$!@oW)*oIRo>sbqRC@LzW|88=JSDeKdTYoq< z${BkXcG;nJSjFzAClAlY_co!iJrTL=x6?e)28R>tu|@+OL?lLXd$MM?B+Q}NZAN#B zWUCSLWiJt-Go-A}&(xuHzPaa`pq|w|S|W|LSAlncI$F38;-YWfeWp#I0_)8Fx(5AhvhP3;eYiJgMa z*d~O}?_cC(jJxF1vSLKCbYCjavCsUv?>{c5cV>ZPEniW8_^*g~l>UAR{SN!aUSKK@ zE&pQ?4eqDC(_2qUFMDdo)9fvp31OLj5BJV3Q2UxMd3wB_M%yMPnG;lCPEb=*g}^mr ze%%j8ZZXXvs2vP(P@wz_XV*`NgFm#%)(P{p>Ja!&v{SHP7YWNJ*`@HOTw-+iL`b*2O&e?izBFAnsgTdwWp=5aOKNp=0pw>|MY+){t~0M)@sN^3xYt#9g9PhZuo(2rbCCTyJ5B)qd%Fspl~f_ocDM zkOIdIh?E;R%nnJ#T#NZy^-;BE*fiANY7hd2R+uV_c3qDImP6&3j*_-V=4&ORh?KcE zhV7Wte&|yp3$-prWy2oTCIZO)7?bLU-+l|A{e_nHYr%~^;TlHpV z|KLSkpxpSaXeA?OPXx3r%X0%ac`A^ptQ-l<{vGrzbv>I@4kdxft#ND#mr*QW3ReX3 zDO;=d*_(!|f4FL$#0mL1ToWidl)O|S_mi9mELAQ#S-D7+a2+=an87R;9t|U~1&sgF z{`AZ#ZsOL+=sb67WmeBetKkl#Bs>oln5q1;_yX>Yl#3;3$mekh_XV=g`LVN$408Oz z1ZU^F@kv7gMcyAWTE+yQfcY<&di4?0VpTKD>zJ}q`gPseM* zHL?Dh`kI)L8cHNJGhw7dDI>09J)>xHkZoQg!{E*RBSy?JCKOX7n%2$6-dzz8T10-8&ZG00yi<2%x`4@L z8oj$ZXP|WgZ7E%-(h>@kqIJqt!{ou4J@Anf#HcEwPSv)TmeUHAmeK2Am3|mkpvQlirs`m1x>+~W?)6eVg;c7e2H48xBw;iPnvFX(a}Y+nn8^W#;6K4q zA&N3hg$HYE=n|Dy)1^$6Gxud`0!yZ0d*p;(03ud^y^hvb&{_%?^-|c8>2fAn_!5YC zX`?Ov6`*x_BAqZdP7`m!E4|c0ttvHBo2}NJT1J0Qn_lV=1e$5HO|)A}>0a7uufbmK z{SDV?ndJ&?hXXVWWefy|nb5Neb%C#pK9tl%P-U{v%DOV=mf@tF5qHo|q4_JBR-PLX zOPn6T zUrT=`jU&D3LuunkddHA(cz6xNL$0BN9>83Sw*iIvU^kn1C|EKWK_mS%Ah;Pks|+@@OxM8{T4o@Zf(mvI55b=nM5d)6kW5m_Lx%`#@%0J~ zAt8s1=`iJf)}P0CE6_pa-@`H5WIHbP7t4>QJLNX9vAkd8^)UWbAP6 z$@LZXWxAVbOYkgCYh!Pi4lzTy1%7|-QR#j3AH}3-*{;*nGg_ZWZvV-oB*dF(WQ0^x z71UW+hk8Cp_g2sc=tD&+CHpenk8FnaqFX;|TH%e*9ifj@(1+=xs1s>xxwM`XyvIu) zrw0VwCz$GAQ(yL@$J9)4{viA{r49G#c+Z$S3LaiI8H1fq(Zeb|M4x7oLLq;JPBMjF z^SG9N2w2ERGL4D=I9HuNqS6>W3ax}f`>ts|P^Zvm@RHI@6xXbm9v9ry(J7RMY_2a` zaPR71XW4B1S$a}He-4?~NS8>v_Z&;WYl>KnqBJ7-hpw*<(4p-DB;Erm4B)LPDS{#kCnL(dCtzl#E4aVwa$czprcYdPwIDCcme z_C!|1U))PSuuI$zk*W(Ap#uWp$Ho58;-{sE*^$YJfcvRRKNF?1B4&T2O*Ep}?fS5n zel8lSJLrFy&YLbuYc7$Di~9RZ6dwe@uT*+bv?gxRf2UDHLuJLEg$yM9E&WcA_+R7? z)37(a^as(%yhwk9vCtzREf&@5r9ab0gl1l{v<@{6C3O?M!(VOl{tcWYF5S0uLlA=ITXc%%=t#%CEQy}tA$F9uq*m#a*;VLVCYq}0 z1z~b$gO_DiRCcpRC=`mm{9L?aMmCsiFW8H!z;l>hcWyW`&qG3pOe@HR0(&Pf@bG-D zEH=)i05VspTrF}nH!FPJEICoc3S)q%V+;_aFop)lP;Po#SxA4=vzGmmT+T}wqs1MJ z(W0uHR%OPB;l?2?$s`KN)CwvpIWi|N=M^e1V@wxwhcbE=o-@%8PA~qV;Cea8wH_!I zhzYwbn5$wpk6J5C&4Yq?v$=2kh3PLE*5<>qWp_Sb&NfdNz}9rhH)r2Br^t)MeQA%TY4kA4{q7j(jMtJ*xS>w z>)_TMT^(L-L2JjGxOJj&ZV-)ggVi{5yFFtT>@y74Jg0vY0Htr{Eh09yg6#A&72XCL zgRGuD?B$3Jh}mU9;ruBh4ewxD7AzgZW*I&BN(>mhiz!$}F_R7^NNhzIC6VZOw|xa* zNB`8Izi`@_wbT62%UAIpm3#SWG=pW%ix>j~;()!P=$FqnQ0g1I2ytdXZ*Umet4f>|~#*s~lrgJ~te{KY{96l8>ex)n>uu zGMb%`c#snwpktC*Tn4EfgILng;xZ@8J7YPjGNU7ziy8fhkvX(Gk4luczopwj%<+s`80do~2D`Ae3vs%C2 zn@N8#EuG~;W`gvc{0^aDj8k(=qot>B`xmPR?nWM%F_Tp@8f$^zMC-xxq5eR4y{vI3_c*+I&2E>TUd_f zzE&@Pkna^rKrwaahT_Qipb*^GDr(jJ{9%7VbEH`9(A^I?}1Z(f$4(T18(_hnK5l-&KgXm zo>nd-3e?K(mCc5>6~3tQ)BGjdE37LV)Q^&pwQ#S)&+u1NlKHDJYC|%1Na3%+nyEu^ zjPYK6&d&RoKPnRF@-yfpj11b3Z`ptA7&^|Mq_``WHjyW%v=QIIjMQf2l5wjwh-Gwm zTwut$YYW7S)B^oRCLq)v5C#Y+jB#TgxNhmo8p)ig+m?O7x>V%vtNgs^JCwARHbhpo z8tiRe{t^FJ)aIYKNc@@Cy2(NO%_oXe2h_a_mDEVtmb7j{8H0tCIim0{RsMg4sK%;L z)u5J6>nIZ!1*crg#_ZLsWwQbZRQGHCjX?b^(~`4-%8a=}HZ#K!NGa0IY^23L=>CEK zsPgamPfQ#BAATw`rjrHMokCmE$m&;$>$>FdWOl&m)`l3}takOU{5O^V!Y`N18@mT# zHk8i4BUNORx;`YLf13b*mCt{u{0|AUi!%lf^-2;U9Xu^Lie6DxK3T%#A{V~ncqJJ# zj^vgU*fE*tQzR9Izl^818it9apbd#{E7lZ_VRf}Ec~xnS$S$5Fa)vkpeqLJ|acM0j zlw*p5vTxcoxin9j54VyQ6lcuBR|hLNBB)YOqvR9U!GXe8h=^BOD87GGER)12GA*2n z7=9$tiDqrej<}AS5rg&?cv&o6pi1XUOT5%!|GH4fvaj?*$t>7b&`TGoQk8_MWDe?v z2r}Dt(=V&+RUEinS|JRG@uWH{KKj7Hj+!Oxo*$h3JSiyE3UmxBOJT8wLQ9;~a_QJ0 z+H$+Y7xq%5dSM}87BYX)iq~k(3%N;ZkQ#*^Fy;8l+=R>08U>@C^*y3XHwO(!x~UB1 zeKROeJu9R4i#yRqn*t8KOlnf8LRwpLV^InvOY4y&6Y0aoAta#nWk$@|ua--OGHHW! zxhjPv3`wq-h()h-g$Rf$X%kb&Wa>o&%jl;Juf;h@YL`0DJV={S3<~|QxVKlNt>PnLnaimuw=2>%bOF+K zrp5q#4}8Z1N3?_qAS?S%)arm{Ww3y0Sj8X=>X^3NqTq|)7_lk>iEJQee_T8ouuaPZ`ZGo<5HsR>A7m?9YOlD%ISXt1 z1#1V2EoPx>=owC%+R@3XD;+F;=(T8c8;0RJTsnVl-?&Ly@v_B&nSvZcHW#06 zQG>Wc4M@NZjXq_R6tyGE%uPgmQ2 zBjdC;x_^Iv_b453o+Qon7}Z6ij>=e%vr_NLQ=+o&BpJok>#>>@t9yzoIjkHJE78hf z09L;KB)w^jj*Zi;(XexzZjXje(A)F$&QZE+l#Y+n`=Vi2$nPAb_di1SF@@cJ_apQ% zrsI6t?-IX1$@BzBhvht-IL`O`<;uJelNOBA7;t|D>iEc+XR!WQo}M^PexS)v&gcE| z!8|>kr>}-xBWE7K{@1Mi2C+ZCIZxkg5`fhJ{k9ES?Q&jg{rY^Kz9*250O|V{Qa~U% zCqezPdlGEt!}O!OX%T>bVgb8HsA8Oc79FMkJ{1BQAj1lz_A7b%#c`?fbv*SH~U@V^kUTSIavAYQTk1uexIj5iM^*Gbe{floP0$=Z8l#0q8~3Whh45F zrCRYrU9aBz>Pf$=T5(=0B&}8~QNxNwRw*HCGxKs7Abuqb0wZTm!A@E!voDKNVzcs9 z0B98$d1mpu$?pVH>>OjYdz|h7=c8Ovnah9k+!O4}^TJ7MQ)h{-eY_~oi=$1-J+wg3 z^YM~AU$kfB%yWKA6u<1KR)jRN^V))`t?f_yozajua%E*q=!xg(Q{=;$gM(CgBtI%caf_(Rsq{@aD+#S}=pC86ka~*GGN4VU#aFW&hkLem;N9 zZF_v&F~*%Z>oir1(1J)V;P~B;pF%#~KE~a%?9Q`RT%aOCGZYoCbw1uX$~|Kog$!cB z?q~!dDf0Qo*L&^G+IB-%c7$kALW4)e5h-jQveUupWrMk zF~&y@j`9uT{Dx>3B5#~;1W8xjD8GL>G|IOCKH7bPZxi%s6BzdKTl4((Xp?-8aO}B$ zceSl^VLKn+QQT7@lRQFm{BB3JY*{801(`8^XP)m0D?Wbj7{5On_W1Gh19`qL&mS4* zkHL?eO-i0WS*?JlPt9MR=TBSiCFAu3oJ*WezdvZZSy&eKQ%>+G2tl=09#DV%uCQkW zZi1CZ#ESIpy09nYSNtA9DI^G;;Ll9Z5|JT@L8pS6=LDaMhSef9kKYv$QmRE_E9?E9 zx+#R7EG1O<>7Jl@f=`e0)6s|@lKP$XQ0bTR{H&FQqg^6St}cX+CEqrS#MdXVu^sKs z^EdCN)gfU|nuEu;t&|cN=jVT;0=NF4kH05EkAG0a`{60><}kwSr&av3l#hRYOk3;X zuMV}FV=&DU*-9CmLvT++WizQMWlnqEBL#Bo<24v@d&Bg z{c`sRFGPy!hJDXGw0(p%#G{63F=LblwcdY3eAs2VmpQhd8QdM++1Q6AEX;GK+F4-R9ZGBt;ETo9?DCrv0D+1IDFD2JwEADtgpk0jFnYAjJJ(@@>0vEgx;*> z?T$KtwXGVHwg{EYV4i=wPZf0xMB-JR}1JR|NM z)^oS}8td8T9<-isb{~^l@jT|f(}I7e`!4a6Tjeh6xl``3p1tyb^}J5LNj%ZV^y9w< z+HUnW>q(-WYZ0p$a#Po zoH1&29;1t$_t9$S2(58GNS8RjOP4xdqRX7GP!mS(wXR*|w9XZx^{$I4?CPWqt{rr_ zD@Dz&!?e*gOjo$xOPgE|Qj5EaTHR}@&3zZOyYHqB_w%$_-a=dCx6@YnYt$*fK-=U$ zL01^rp)ZLX{|8V@2MEVi07E4e007Dl72CN4SZWw760F)&3k=)`)Ip%OZU}v z8+2{cZiAK)#$a?zDy58dql691Yx0`DEy*j%%esLeDk35XBB;Gfd{H}O(scKrycgSqW!_6&EPWa&fCW$&p$cj~v_-Go8k@t6OP* zQwc94tvyya8J7_iSkRWok$f46`*Ts1hik z&{O=T)GTNle}?3pp6i5yc>)u{rnAa_;Dbz`*5vHQtfxAT!Lb_VqefursK^e7bMCaH z6$zPf1+^OLSiM5x+Ks3=-h%XU66Qk#3u~lEa|~i30bk9b3lH6!QAHvaVKHkvj+}3> zH>zk7P#rtHO2-MTpbkp}=H@-YF{CrInzJq(Is6Ei$m@>o^(9c=i;3GS^D5 z6dlXcL#GK$B4?L(C+tYlF;^K*uZ|UI?@kw}JbX$h_yk=@BN#Ljl#vT5C&M*I%%K10 z#Su2o%g`1E8j4*jKB?ghoGEbZQEpOj7FnBKc!nLN0G!PU*^X6XV4`D7!ZD)?R#W86 zINj^=gJ!QHD;=`cG@@j|8mujULI=*JJKkehk!0LFi{fB}DP>CYCCqsUu(tCFDe?$Z zu%42xj|U=z2<7=wi4OTw=+bZjE~H}&5db^nMR)obgOogUj4cr(ksuXgl2#6q2_|~@ zc7^i?E#GBUV39GosMgVIEN*JLJWHmgUyH6 zM_!nlNp?a|QWCQ#NF zMQDW8lf;sm1?$FR!6o=K>$^028dA#gc-)ZU6?{g+<%|PvBNQ5U92pSeTlG17p4VML zIWX211y|B}SdK|yv?+;yD#lpbni(fMuELj!@kLxs4jnqL;2KH_s;}+lW=F?Yu&fx@ z;yMDym>l>j=JLP|6vv1i4x6NCdcHfKB0%?BN$jrZYx-uUBm(MaRxj3>Fn7BzOyNMv8 z`tY?PdsB2gh!K{5@(_8O)p}a8r^k$&q1C1#>(#?_PT9HESYI*&C)w#ovb8Q_aLy71 zkL5WiSxA1O;c+}6P`Gx@O5YL{PYTqIF3gc}*i!VghDWi7ap>T-v`LxypK92JpV1W| zDWNv%{B%6WA=`zYliFa!PSD6NxEa`mUy_S0b}|yGirG$oRS$zq72S#6DgqtK*%v73 z^JHo^F%@^5EXx-lFpeGx5+Vw z!0ni$YBb1yq_^<4Mm6f4Y=ukX6DKyQ{;Pm%ZO6fCl`}^>-^JgH@Hf0Swl+$+3jRq3 zId+@fPt}6n0HX%w%E)Wb2l$tU_wjFXuiuJ=?EZv`|4^i;A$ANaMqoWX*SD5lBi>H5cAM^eL6t!+EmN|1((8FNb=q?HrwRH2Y# zTrQ269ka+@d2L0JYY&`u$+}#9;ioa)kV3e(8Lrmm8uDumUGSM66bWYx%W>OUQx-LrjIFPBs6L`4m&?n z6SHK0KRrJ&Kc))$^7P1Afu(uUXx(9Reym{9TrK93Y%z}&EE$t0l;3o%6>%&9c;
irPMAS;~ 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 19a6bdeb84..c61a118f7d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index faf93008b7..739907dfd1 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,8 +210,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a21834..e509b2dd8f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,94 +1,93 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 336680fbfd304d09d8bece67c60ea37e8489362c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:40:18 -0700 Subject: [PATCH 25/29] Bump org.jetbrains.changelog from 2.2.0 to 2.5.0 (#8930) Bumps org.jetbrains.changelog from 2.2.0 to 2.5.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.jetbrains.changelog&package-manager=gradle&previous-version=2.2.0&new-version=2.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f4af5fae10..dd67122e46 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ junit-jupiter = "5.11.4" junit-platform = "1.11.4" intellij-platform-plugin = "2.12.0" kotlin = "2.2.0" -changelog = "2.2.0" +changelog = "2.5.0" kover = "0.9.4" [libraries] From 335dd2b12c7fa77dba6d092d44da055890e0d684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:40:47 -0700 Subject: [PATCH 26/29] Bump org.junit.platform:junit-platform-launcher from 1.11.4 to 6.0.3 (#8929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.junit.platform:junit-platform-launcher](https://github.com/junit-team/junit-framework) from 1.11.4 to 6.0.3.
Release notes

Sourced from org.junit.platform:junit-platform-launcher's releases.

JUnit 6.0.3 = Platform 6.0.3 + Jupiter 6.0.3 + Vintage 6.0.3

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.2...r6.0.3

JUnit 6.0.2 = Platform 6.0.2 + Jupiter 6.0.2 + Vintage 6.0.2

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.1...r6.0.2

JUnit 6.0.1 = Platform 6.0.1 + Jupiter 6.0.1 + Vintage 6.0.1

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.0...r6.0.1

JUnit 6.0.0 = Platform 6.0.0 + Jupiter 6.0.0 + Vintage 6.0.0

See Release Notes.

New Contributors

Full Changelog: https://github.com/junit-team/junit-framework/compare/r5.14.0...r6.0.0

JUnit 6.0.0-RC3 = Platform 6.0.0-RC3 + Jupiter 6.0.0-RC3 + Vintage 6.0.0-RC3

See Release Notes.

New Contributors

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.0-RC2...r6.0.0-RC3

JUnit 6.0.0-RC2 = Platform 6.0.0-RC2 + Jupiter 6.0.0-RC2 + Vintage 6.0.0-RC2

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.0-RC1...r6.0.0-RC2

JUnit 6.0.0-RC1 = Platform 6.0.0-RC1 + Jupiter 6.0.0-RC1 + Vintage 6.0.0-RC1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.junit.platform:junit-platform-launcher&package-manager=gradle&previous-version=1.11.4&new-version=6.0.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dd67122e46..fad8cdfe03 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ junit = "4.13.2" kodein-di = "7.26.1" kotlinx-coroutines = "1.9.0" junit-jupiter = "5.11.4" -junit-platform = "1.11.4" +junit-platform = "6.0.3" intellij-platform-plugin = "2.12.0" kotlin = "2.2.0" changelog = "2.5.0" From 57a24cafca9d45db581b777340670ae7aaeed5c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:41:30 -0700 Subject: [PATCH 27/29] Bump com.google.guava:guava from 32.0.1-android to 33.6.0-android (#8928) Bumps [com.google.guava:guava](https://github.com/google/guava) from 32.0.1-android to 33.6.0-android.
Release notes

Sourced from com.google.guava:guava's releases.

33.6.0

Maven

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>33.6.0-jre</version>
  <!-- or, for Android: -->
  <version>33.6.0-android</version>
</dependency>

Jar files

Guava requires one runtime dependency, which you can download here:

Javadoc

JDiff

Changelog

  • Migrated some classes from finalize() to PhantomReference in preparation for the removal of finalization. (786b619dd6, 7c6b17c, aeef90988d)
  • cache: Deprecated CacheBuilder APIs that use TimeUnit in favor of those that use Duration. (73f8b0bb84)
  • collect: Added toImmutableSortedMap collectors that use the natural comparator. (64d70b9f94)
  • collect: Changed ConcurrentHashMultiset, ImmutableMap and TreeMultiset deserialization to avoid mutating final fields. In extremely unlikely scenarios in which an instance of that type contains an object that refers back to that instance, this could lead to a broken instance that throws NullPointerException when used. (8240c7e596, 046468055f)
  • graph: Removed @Beta from all APIs in the package. (dae9566b73)
  • graph: Added support to Graphs.transitiveClosure() for different strategies for adding self-loops. (2e13df25b2)
  • graph: Added an asNetwork() view to Graph and ValueGraph. (909c593c61)
  • hash: Added BloomFilter.serializedSize(). (df9bcc251a)
  • net: Added HttpHeaders.CDN_CACHE_CONTROL. (75331b5030)

33.5.0

Maven

<dependency>
</tr></table>

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.guava:guava&package-manager=gradle&previous-version=32.0.1-android&new-version=33.6.0-android)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fad8cdfe03..5a3910ae83 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,8 +4,8 @@ [versions] jetbrains-annotations = "24.0.0" -guava-android = "32.0.1-android" -guava-jre = "32.0.1-jre" +guava-android = "33.6.0-android" +guava-jre = "33.6.0-android" gson = "2.10.1" junit = "4.13.2" kodein-di = "7.26.1" From f2bdbff9c956d1d1674c39a2bb911d725e63198b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 01:53:23 +0000 Subject: [PATCH 28/29] Bump org.junit.jupiter:junit-jupiter from 5.11.4 to 6.0.3 (#8927) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit-framework) from 5.11.4 to 6.0.3.
Release notes

Sourced from org.junit.jupiter:junit-jupiter's releases.

JUnit 6.0.3 = Platform 6.0.3 + Jupiter 6.0.3 + Vintage 6.0.3

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.2...r6.0.3

JUnit 6.0.2 = Platform 6.0.2 + Jupiter 6.0.2 + Vintage 6.0.2

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.1...r6.0.2

JUnit 6.0.1 = Platform 6.0.1 + Jupiter 6.0.1 + Vintage 6.0.1

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.0...r6.0.1

JUnit 6.0.0 = Platform 6.0.0 + Jupiter 6.0.0 + Vintage 6.0.0

See Release Notes.

New Contributors

Full Changelog: https://github.com/junit-team/junit-framework/compare/r5.14.0...r6.0.0

JUnit 6.0.0-RC3 = Platform 6.0.0-RC3 + Jupiter 6.0.0-RC3 + Vintage 6.0.0-RC3

See Release Notes.

New Contributors

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.0-RC2...r6.0.0-RC3

JUnit 6.0.0-RC2 = Platform 6.0.0-RC2 + Jupiter 6.0.0-RC2 + Vintage 6.0.0-RC2

See Release Notes.

Full Changelog: https://github.com/junit-team/junit-framework/compare/r6.0.0-RC1...r6.0.0-RC2

JUnit 6.0.0-RC1 = Platform 6.0.0-RC1 + Jupiter 6.0.0-RC1 + Vintage 6.0.0-RC1

... (truncated)

Commits
  • 36e3253 Release 6.0.3
  • 295561f Finalize 6.0.3 release notes
  • ea18076 Fix deadlock in NamespacedHierarchicalStore.computeIfAbsent() (#5348)
  • 869e232 Add 5.14.3 release notes
  • d4b34c4 Fix links to User Guide
  • 5c8fb0f Reliably support JRE.OTHER with @⁠EnabledOnJre and @⁠DisabledOnJre
  • febb13f Check out entire repo so switching to main branch works in last step
  • 71fba90 Install poppler-utils for pdfinfo
  • 740e9e0 Update API baseline
  • 2ba535f Use release branch of examples repo
  • Additional commits viewable in compare view

--- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5a3910ae83..b866f33984 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ gson = "2.10.1" junit = "4.13.2" kodein-di = "7.26.1" kotlinx-coroutines = "1.9.0" -junit-jupiter = "5.11.4" +junit-jupiter = "6.0.3" junit-platform = "6.0.3" intellij-platform-plugin = "2.12.0" kotlin = "2.2.0" From 739933c469d46120791b64190f5211d10a5acc19 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Mon, 27 Apr 2026 12:40:33 -0700 Subject: [PATCH 29/29] [docs] changelog update for 92.0.0 (#8931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates for upcoming release. --- Review the contribution guidelines below: - [x] I’ve reviewed the contributor guide and applied the relevant portions to this PR. - [x] I've included the required information in the description above. - [x] My up-to-date information is in the `AUTHORS` file. - [x] I've updated `CHANGELOG.md` if appropriate.
Contribution guidelines:
- See our [contributor guide](../CONTRIBUTING.md) and the [Flutter organization contributor guide]([https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md) for general expectations for PRs. - Larger or significant changes should be discussed in an issue before creating a PR. - Dart contributions to our repos should follow the [Dart style guide](https://dart.dev/guides/language/effective-dart) and use `dart format`. - Java and Kotlin contributions should strive to follow Java and Kotlin best practices ([discussion](https://github.com/flutter/flutter-intellij/issues/8098)).
--------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f75b61c19..ad0b4b8c0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ### Fixed - Silent failure when opening Flutter projects without `.idea` directory in IntelliJ IDEA, by removing `FlutterProjectOpenProcessor` and migrating configuration logic to `FlutterInitializer`. (#8903) +- IDE focus loss when running in full screen mode. (#8906) +- Excessive toolbar updates causing exceptions in Android Studio, by making device selector updates targeted instead of global. (#8891) ## 91.0.0