From 3d7102d3a55f9dfa70909f34f5f08e325b82732a Mon Sep 17 00:00:00 2001 From: hrajwade96 Date: Sat, 12 Apr 2025 21:55:26 +0530 Subject: [PATCH 001/107] added mime checks, minor logic improvements in recording --- .../src/screens/network/har_data_entry.dart | 11 ++++++++- .../screens/network/network_controller.dart | 10 ++++---- .../src/shared/http/http_request_data.dart | 23 +++++++++++++++++-- .../lib/src/shared/primitives/utils.dart | 15 ++++++++++++ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/network/har_data_entry.dart b/packages/devtools_app/lib/src/screens/network/har_data_entry.dart index 2a2ba7d4d69..6cb72d9d44f 100644 --- a/packages/devtools_app/lib/src/screens/network/har_data_entry.dart +++ b/packages/devtools_app/lib/src/screens/network/har_data_entry.dart @@ -122,6 +122,9 @@ class HarDataEntry { }; }).toList(); + final isBinary = !isTextMimeType(e.type); + final responseBodyBytes = e.encodedResponse; + return { NetworkEventKeys.startedDateTime.name: e.startTimestamp.toUtc().toIso8601String(), @@ -155,8 +158,14 @@ class HarDataEntry { NetworkEventKeys.content.name: { NetworkEventKeys.size.name: e.responseBody?.length, NetworkEventKeys.mimeType.name: e.type, - NetworkEventKeys.text.name: e.responseBody, + if (responseBodyBytes != null && isBinary) ...{ + NetworkEventKeys.text.name: base64.encode(responseBodyBytes), + 'encoding': 'base64', + } else if (e.responseBody != null) ...{ + NetworkEventKeys.text.name: e.responseBody, + }, }, + NetworkEventKeys.redirectURL.name: '', NetworkEventKeys.headersSize.name: calculateHeadersSize( e.responseHeaders, diff --git a/packages/devtools_app/lib/src/screens/network/network_controller.dart b/packages/devtools_app/lib/src/screens/network/network_controller.dart index 0145ba75b67..6f8157e719a 100644 --- a/packages/devtools_app/lib/src/screens/network/network_controller.dart +++ b/packages/devtools_app/lib/src/screens/network/network_controller.dart @@ -77,9 +77,8 @@ class NetworkController extends DevToolsScreenController debugPrint('No valid request data to export'); return ''; } - + // Build the HAR object try { - // Build the HAR object final har = HarNetworkData(_httpRequests!); return ExportController().downloadFile( json.encode(har.toJson()), @@ -205,8 +204,11 @@ class NetworkController extends DevToolsScreenController shouldLoad: (data) => !data.isEmpty, loadData: (data) => loadOfflineData(data), ); - } - if (serviceConnection.serviceManager.connectedState.value.connected) { + } else if (serviceConnection + .serviceManager + .connectedState + .value + .connected) { await startRecording(); } } diff --git a/packages/devtools_app/lib/src/shared/http/http_request_data.dart b/packages/devtools_app/lib/src/shared/http/http_request_data.dart index b417ce0bb17..de03023d517 100644 --- a/packages/devtools_app/lib/src/shared/http/http_request_data.dart +++ b/packages/devtools_app/lib/src/shared/http/http_request_data.dart @@ -102,8 +102,27 @@ class DartIOHttpRequestData extends NetworkRequest { ); _request = updated; final fullRequest = _request as HttpProfileRequest; - _responseBody = utf8.decode(fullRequest.responseBody!); - _requestBody = utf8.decode(fullRequest.requestBody!); + final responseMime = + responseHeaders?['content-type']?.toString().split(';').first; + final requestMime = + requestHeaders?['content-type']?.toString().split(';').first; + + if (fullRequest.responseBody != null) { + if (isTextMimeType(responseMime)) { + _responseBody = utf8.decode(fullRequest.responseBody!); + } else { + _responseBody = base64.encode(fullRequest.responseBody!); + } + } + + if (fullRequest.requestBody != null) { + if (isTextMimeType(requestMime)) { + _requestBody = utf8.decode(fullRequest.requestBody!); + } else { + _requestBody = base64.encode(fullRequest.requestBody!); + } + } + notifyListeners(); } } finally { diff --git a/packages/devtools_app/lib/src/shared/primitives/utils.dart b/packages/devtools_app/lib/src/shared/primitives/utils.dart index 45558fd8a10..3fe1d11a50e 100644 --- a/packages/devtools_app/lib/src/shared/primitives/utils.dart +++ b/packages/devtools_app/lib/src/shared/primitives/utils.dart @@ -1126,3 +1126,18 @@ String devtoolsAssetsBasePath({required String origin, required String path}) { pathParts.removeLast(); return '$trimmedOrigin${pathParts.join(separator)}'; } + +/// Returns `true` if the given [mimeType] is considered textual and can be +/// safely decoded as UTF-8 without base64 encoding. +/// +/// This function is useful for determining whether the content of an HTTP +/// request or response can be directly included in a HAR or JSON file as +/// human-readable text. +bool isTextMimeType(String? mimeType) { + if (mimeType == null) return false; + return mimeType.startsWith('text/') || + mimeType == 'application/json' || + mimeType == 'application/javascript' || + mimeType == 'application/xml' || + mimeType == 'application/x-www-form-urlencoded'; +} From b7a531058bcab967ffc8d69c833e0fe97a32d0d0 Mon Sep 17 00:00:00 2001 From: Hrishikesh Date: Sat, 24 May 2025 19:11:59 +0530 Subject: [PATCH 002/107] mime fixes --- .../lib/src/shared/http/http_request_data.dart | 14 +++++++++++++- .../lib/src/shared/primitives/utils.dart | 13 ++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/devtools_app/lib/src/shared/http/http_request_data.dart b/packages/devtools_app/lib/src/shared/http/http_request_data.dart index de03023d517..1d45371e0a4 100644 --- a/packages/devtools_app/lib/src/shared/http/http_request_data.dart +++ b/packages/devtools_app/lib/src/shared/http/http_request_data.dart @@ -102,12 +102,14 @@ class DartIOHttpRequestData extends NetworkRequest { ); _request = updated; final fullRequest = _request as HttpProfileRequest; - final responseMime = + var responseMime = responseHeaders?['content-type']?.toString().split(';').first; final requestMime = requestHeaders?['content-type']?.toString().split(';').first; if (fullRequest.responseBody != null) { + responseMime = normalizeContentType(responseHeaders?['content-type']); + if (isTextMimeType(responseMime)) { _responseBody = utf8.decode(fullRequest.responseBody!); } else { @@ -130,6 +132,16 @@ class DartIOHttpRequestData extends NetworkRequest { } } + //TODO check if all cases are handled correctly + String? normalizeContentType(dynamic header) { + if (header is List && header.isNotEmpty) { + return header.first.toString().split(';').first.trim().toLowerCase(); + } else if (header is String) { + return header.split(';').first.trim().toLowerCase(); + } + return null; + } + static List _parseCookies(List? cookies) { if (cookies == null) return []; return cookies.map((cookie) => Cookie.fromSetCookieValue(cookie)).toList(); diff --git a/packages/devtools_app/lib/src/shared/primitives/utils.dart b/packages/devtools_app/lib/src/shared/primitives/utils.dart index 3fe1d11a50e..4429db8ac88 100644 --- a/packages/devtools_app/lib/src/shared/primitives/utils.dart +++ b/packages/devtools_app/lib/src/shared/primitives/utils.dart @@ -1135,9 +1135,12 @@ String devtoolsAssetsBasePath({required String origin, required String path}) { /// human-readable text. bool isTextMimeType(String? mimeType) { if (mimeType == null) return false; - return mimeType.startsWith('text/') || - mimeType == 'application/json' || - mimeType == 'application/javascript' || - mimeType == 'application/xml' || - mimeType == 'application/x-www-form-urlencoded'; + + // Strip charset if present + final cleanedMime = mimeType.split(';').first.trim().toLowerCase(); + + return cleanedMime.startsWith('text/') || + cleanedMime == 'application/json' || + cleanedMime == 'application/javascript' || + cleanedMime == 'application/xml'; } From e94558c17ddf9173a1d9b0bd0a3097d7b931ad08 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 14 Apr 2025 13:43:46 -0700 Subject: [PATCH 003/107] Prevent web apps from freezing after hot-restarts triggered from DevTools (#9125) --- .../screens/debugger/breakpoint_manager.dart | 4 +++ .../release_notes/NEXT_RELEASE_NOTES.md | 34 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart b/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart index a18c39d24b2..89e887d99b6 100644 --- a/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart +++ b/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart @@ -93,6 +93,10 @@ class BreakpointManager with DisposerMixin { if ([ EventKind.kPauseStart, EventKind.kPausePostRequest, + // We check for a resume event because package:dwds sends a resume event + // after a hot-restart. See: + // https://github.com/dart-lang/webdev/issues/2610 + EventKind.kResume, ].contains(pauseEventKind)) { await serviceConnection.serviceManager.isolateManager.resumeIsolate( isolateRef, diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index 9c55b86fedf..f326bdafe67 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -15,7 +15,39 @@ To learn more about DevTools, check out the ## General updates -TODO: Remove this section if there are not any general updates. +* Prevent web apps from remaining paused after triggering a hot-restart from +DevTools. - [#9125](https://github.com/flutter/devtools/pull/9125) + +* Added a memory pressure warning that allows you to reduce the memory usage of +DevTools in order to avoid an OOM crash. - +[#8989](https://github.com/flutter/devtools/pull/8989), +[#8997](https://github.com/flutter/devtools/pull/8997), +[#8998](https://github.com/flutter/devtools/pull/8998) + +* Fixed various memory leaks and lifecycle issues. - +[#8901](https://github.com/flutter/devtools/pull/8901), +[#8902](https://github.com/flutter/devtools/pull/8902), +[#8907](https://github.com/flutter/devtools/pull/8907), +[#8917](https://github.com/flutter/devtools/pull/8917), +[#8932](https://github.com/flutter/devtools/pull/8932), +[#8933](https://github.com/flutter/devtools/pull/8933), +[#8934](https://github.com/flutter/devtools/pull/8934), +[#8935](https://github.com/flutter/devtools/pull/8935), +[#8937](https://github.com/flutter/devtools/pull/8937), +[#8953](https://github.com/flutter/devtools/pull/8953), +[#8969](https://github.com/flutter/devtools/pull/8969), +[#8970](https://github.com/flutter/devtools/pull/8970), +[#8975](https://github.com/flutter/devtools/pull/8975) + +* Fix a bug with the review history on disconnect experience. - +[#8985](https://github.com/flutter/devtools/pull/8985) + +* Fixed bug where DevTools would automatically resume instead of +pausing on breakpoint on connection. - +[#8991](https://github.com/flutter/devtools/pull/8991) + +* Prevented text inputs from stealing focus from the IDE. - +[#9091](https://github.com/flutter/devtools/pull/9091) ## Inspector updates From 7b0d352924656dc5d491ed9e674b557ad6fe10b5 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:11:52 -0700 Subject: [PATCH 004/107] Prepare cherry-pick release - DevTools 2.45.1 --- packages/devtools_app/lib/devtools.dart | 2 +- packages/devtools_app/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devtools_app/lib/devtools.dart b/packages/devtools_app/lib/devtools.dart index 9d450e5f61f..637ab28fbf6 100644 --- a/packages/devtools_app/lib/devtools.dart +++ b/packages/devtools_app/lib/devtools.dart @@ -10,4 +10,4 @@ /// Note: a regexp in the `dt update-version' command logic matches the constant /// declaration `const version =`. If you change the declaration you must also /// modify the regex in the `dt update-version' command logic. -const version = '2.46.0-dev.0'; +const version = '2.46.0-dev.1'; diff --git a/packages/devtools_app/pubspec.yaml b/packages/devtools_app/pubspec.yaml index 7220b4a1fa3..da76c9c0860 100644 --- a/packages/devtools_app/pubspec.yaml +++ b/packages/devtools_app/pubspec.yaml @@ -7,7 +7,7 @@ publish_to: none # Note: this version should only be updated by running the 'dt update-version' # command that updates the version here and in 'devtools.dart'. -version: 2.46.0-dev.0 +version: 2.46.0-dev.1 repository: https://github.com/flutter/devtools/tree/master/packages/devtools_app From a0c48b17f0890901612cb4d86a970eaa10b794fe Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 10 Apr 2025 12:12:06 -0700 Subject: [PATCH 005/107] Re-enable `discarded_futures` lint (#9117) --- analysis_options.yaml | 2 +- .../lib/src/framework/home_screen.dart | 3 ++- .../screens/debugger/debugger_controller.dart | 7 +++--- .../inspector/inspector_controller.dart | 15 +++++++----- .../inspector_v2/inspector_controller.dart | 15 +++++++----- .../inspector_v2/inspector_screen_body.dart | 3 ++- .../enhance_tracing/enhance_tracing.dart | 11 ++++++--- .../lib/src/service/vm_service_wrapper.dart | 13 ++++++---- .../lib/src/shared/managers/survey.dart | 2 +- .../preferences/_extension_preferences.dart | 8 ++++--- .../preferences/_inspector_preferences.dart | 8 ++++--- .../preferences/_logging_preferences.dart | 12 ++++++---- .../preferences/_memory_preferences.dart | 16 +++++++++---- .../preferences/_performance_preferences.dart | 16 ++++++++----- .../src/shared/preferences/preferences.dart | 24 ++++++++++++------- .../lib/src/shared/utils/utils.dart | 13 +++++++++- .../vm_developer_common_widgets_test.dart | 4 ++-- .../fixtures/networking_app/bin/main.dart | 8 +++---- .../test/ui/split_pane_test.dart | 8 +++++-- .../lib/src/service/service.dart | 16 ++++++------- 20 files changed, 130 insertions(+), 74 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 866a2b7d3d0..3fa6d9df9dc 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -71,7 +71,7 @@ linter: # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204 - control_flow_in_finally - directives_ordering - # - discarded_futures # TODO(https://github.com/flutter/devtools/issues/9102): Re-enable. + - discarded_futures - empty_catches - empty_constructor_bodies - empty_statements diff --git a/packages/devtools_app/lib/src/framework/home_screen.dart b/packages/devtools_app/lib/src/framework/home_screen.dart index 540cf09bdd5..6e9b7ed2877 100644 --- a/packages/devtools_app/lib/src/framework/home_screen.dart +++ b/packages/devtools_app/lib/src/framework/home_screen.dart @@ -22,6 +22,7 @@ import '../shared/primitives/blocking_action_mixin.dart'; import '../shared/primitives/utils.dart'; import '../shared/title.dart'; import '../shared/ui/vm_flag_widgets.dart'; +import '../shared/utils/utils.dart'; import 'framework_core.dart'; class HomeScreen extends Screen { @@ -259,7 +260,7 @@ class _ConnectInputState extends State with BlockingActionMixin { } assert(() { - storage.setValue(_debugVmServiceUriKey, uri); + safeUnawaited(storage.setValue(_debugVmServiceUriKey, uri)); return true; }()); diff --git a/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart b/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart index 3c60d941933..d69ebc1ee42 100644 --- a/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart +++ b/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart @@ -26,6 +26,7 @@ import '../../shared/framework/screen_controllers.dart'; import '../../shared/globals.dart'; import '../../shared/primitives/message_bus.dart'; import '../../shared/primitives/utils.dart'; +import '../../shared/utils/utils.dart'; import 'codeview_controller.dart'; import 'debugger_model.dart'; @@ -399,9 +400,9 @@ class DebuggerController extends DevToolsScreenController /// This method ensures that the source for the script is populated in our /// cache, in order to reduce flashing in the editor view. void _populateScriptAndShowLocation(ScriptRef scriptRef) { - unawaited( - scriptManager.getScript(scriptRef).then((script) { - codeViewController.showScriptLocation(ScriptLocation(scriptRef)); + safeUnawaited( + scriptManager.getScript(scriptRef).then((script) async { + await codeViewController.showScriptLocation(ScriptLocation(scriptRef)); }), ); } diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart index 99a23166cce..2716ef3393e 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart @@ -34,6 +34,7 @@ import '../../shared/diagnostics/primitives/instance_ref.dart'; import '../../shared/globals.dart'; import '../../shared/primitives/query_parameters.dart'; import '../../shared/primitives/utils.dart'; +import '../../shared/utils/utils.dart'; import '../inspector_shared/inspector_screen.dart'; import 'inspector_tree_controller.dart'; @@ -105,12 +106,14 @@ class InspectorController extends DisposableController // won't interfere with users. addAutoDisposeListener(_supportsToggleSelectWidgetMode, () { if (_supportsToggleSelectWidgetMode.value) { - serviceConnection.serviceManager.serviceExtensionManager - .setServiceExtensionState( - extensions.enableOnDeviceInspector.extension, - enabled: true, - value: true, - ); + safeUnawaited( + serviceConnection.serviceManager.serviceExtensionManager + .setServiceExtensionState( + extensions.enableOnDeviceInspector.extension, + enabled: true, + value: true, + ), + ); } }); } diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart index 83b3305a50f..a66cffff278 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart @@ -35,6 +35,7 @@ import '../../shared/globals.dart'; import '../../shared/managers/notifications.dart'; import '../../shared/primitives/query_parameters.dart'; import '../../shared/primitives/utils.dart'; +import '../../shared/utils/utils.dart'; import '../inspector_shared/inspector_screen.dart'; import 'inspector_data_models.dart'; import 'inspector_tree_controller.dart'; @@ -112,12 +113,14 @@ class InspectorController extends DisposableController // won't interfere with users. addAutoDisposeListener(_supportsToggleSelectWidgetMode, () { if (_supportsToggleSelectWidgetMode.value) { - serviceConnection.serviceManager.serviceExtensionManager - .setServiceExtensionState( - extensions.enableOnDeviceInspector.extension, - enabled: true, - value: true, - ); + safeUnawaited( + serviceConnection.serviceManager.serviceExtensionManager + .setServiceExtensionState( + extensions.enableOnDeviceInspector.extension, + enabled: true, + value: true, + ), + ); } }); diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart index 074ce7fce14..91903f21b1e 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart @@ -19,6 +19,7 @@ import '../../shared/managers/error_badge_manager.dart'; import '../../shared/primitives/blocking_action_mixin.dart'; import '../../shared/ui/common_widgets.dart'; import '../../shared/ui/search.dart'; +import '../../shared/utils/utils.dart'; import '../inspector_shared/inspector_controls.dart'; import '../inspector_shared/inspector_screen.dart'; import 'inspector_controller.dart'; @@ -97,7 +98,7 @@ class InspectorScreenBodyState extends State addAutoDisposeListener(preferences.inspector.pubRootDirectories, () { if (serviceConnection.serviceManager.connectedState.value.connected && controller.firstInspectorTreeLoadCompleted) { - controller.refreshInspector(); + safeUnawaited(controller.refreshInspector()); } }); diff --git a/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart b/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart index 575d910decc..68776c60de0 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart @@ -14,6 +14,7 @@ import '../../../../../service/service_extensions.dart' as extensions; import '../../../../../shared/globals.dart'; import '../../../../../shared/primitives/utils.dart'; import '../../../../../shared/ui/common_widgets.dart'; +import '../../../../../shared/utils/utils.dart'; import '../performance_controls.dart'; import 'enhance_tracing_controller.dart'; @@ -142,7 +143,7 @@ class _TraceWidgetBuildsSettingState extends State for (final type in TraceWidgetBuildsScope.values) { final extension = _traceWidgetBuildsExtensions[type]!; - unawaited( + safeUnawaited( serviceConnection.serviceManager.serviceExtensionManager .waitForServiceExtensionAvailable(extension.extension) .then((isServiceAvailable) { @@ -154,9 +155,13 @@ class _TraceWidgetBuildsSettingState extends State .serviceExtensionManager .getServiceExtensionState(extension.extension); - _updateForServiceExtensionState(state.value, type); + safeUnawaited( + _updateForServiceExtensionState(state.value, type), + ); addAutoDisposeListener(state, () { - _updateForServiceExtensionState(state.value, type); + safeUnawaited( + _updateForServiceExtensionState(state.value, type), + ); }); } }), diff --git a/packages/devtools_app/lib/src/service/vm_service_wrapper.dart b/packages/devtools_app/lib/src/service/vm_service_wrapper.dart index d5ec53cc73e..4da7282b238 100644 --- a/packages/devtools_app/lib/src/service/vm_service_wrapper.dart +++ b/packages/devtools_app/lib/src/service/vm_service_wrapper.dart @@ -25,6 +25,7 @@ import '../screens/vm_developer/vm_service_private_extensions.dart'; import '../shared/feature_flags.dart'; import '../shared/globals.dart'; import '../shared/primitives/utils.dart'; +import '../shared/utils/utils.dart'; import 'json_to_service_cache.dart'; final _log = Logger('vm_service_wrapper'); @@ -188,8 +189,8 @@ class VmServiceWrapper extends VmService { } @override - Future streamCancel(String streamId) { - _activeStreams.remove(streamId); + Future streamCancel(String streamId) async { + await _activeStreams.remove(streamId); return super.streamCancel(streamId); } @@ -380,9 +381,11 @@ class VmServiceWrapper extends VmService { } } - localFuture.then( - (value) => futureComplete(), - onError: (error) => futureComplete(), + safeUnawaited( + localFuture.then( + (value) => futureComplete(), + onError: (error) => futureComplete(), + ), ); return localFuture; } diff --git a/packages/devtools_app/lib/src/shared/managers/survey.dart b/packages/devtools_app/lib/src/shared/managers/survey.dart index 6ac83fccd16..d7554937e03 100644 --- a/packages/devtools_app/lib/src/shared/managers/survey.dart +++ b/packages/devtools_app/lib/src/shared/managers/survey.dart @@ -95,7 +95,7 @@ class SurveyService { allowDuplicates: false, ); if (didPush) { - server.incrementSurveyShownCount(); + safeUnawaited(server.incrementSurveyShownCount()); } }); } diff --git a/packages/devtools_app/lib/src/shared/preferences/_extension_preferences.dart b/packages/devtools_app/lib/src/shared/preferences/_extension_preferences.dart index b96210a1010..42c80f0183e 100644 --- a/packages/devtools_app/lib/src/shared/preferences/_extension_preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/_extension_preferences.dart @@ -15,9 +15,11 @@ class ExtensionsPreferencesController extends DisposableController @override Future init() async { addAutoDisposeListener(showOnlyEnabledExtensions, () { - storage.setValue( - _showOnlyEnabledExtensionsId, - showOnlyEnabledExtensions.value.toString(), + safeUnawaited( + storage.setValue( + _showOnlyEnabledExtensionsId, + showOnlyEnabledExtensions.value.toString(), + ), ); ga.select( gac.DevToolsExtensionEvents.extensionScreenId.name, diff --git a/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart b/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart index ff279aa1815..261af777c7b 100644 --- a/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart @@ -168,9 +168,11 @@ class InspectorPreferencesController extends DisposableController await _updateInspectorDetailsViewSelection(); addAutoDisposeListener(_defaultDetailsView, () { - storage.setValue( - _defaultDetailsViewStorageId, - _defaultDetailsView.value.name.toString(), + safeUnawaited( + storage.setValue( + _defaultDetailsViewStorageId, + _defaultDetailsView.value.name.toString(), + ), ); }); } diff --git a/packages/devtools_app/lib/src/shared/preferences/_logging_preferences.dart b/packages/devtools_app/lib/src/shared/preferences/_logging_preferences.dart index c4d5f8638bd..713c6ece0ed 100644 --- a/packages/devtools_app/lib/src/shared/preferences/_logging_preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/_logging_preferences.dart @@ -39,9 +39,11 @@ class LoggingPreferencesController extends DisposableController int.tryParse(await storage.getValue(_retentionLimitStorageId) ?? '') ?? _defaultRetentionLimit; addAutoDisposeListener(retentionLimit, () { - storage.setValue( - _retentionLimitStorageId, - retentionLimit.value.toString(), + safeUnawaited( + storage.setValue( + _retentionLimitStorageId, + retentionLimit.value.toString(), + ), ); ga.select( gac.logging, @@ -59,7 +61,9 @@ class LoggingPreferencesController extends DisposableController ) ?? _defaultDetailsFormat; addAutoDisposeListener(detailsFormat, () { - storage.setValue(detailsFormatStorageId, detailsFormat.value.name); + safeUnawaited( + storage.setValue(detailsFormatStorageId, detailsFormat.value.name), + ); ga.select( gac.logging, gac.LoggingEvents.changeDetailsFormat.name, diff --git a/packages/devtools_app/lib/src/shared/preferences/_memory_preferences.dart b/packages/devtools_app/lib/src/shared/preferences/_memory_preferences.dart index 5c55b5445e9..da641573d20 100644 --- a/packages/devtools_app/lib/src/shared/preferences/_memory_preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/_memory_preferences.dart @@ -26,9 +26,11 @@ class MemoryPreferencesController extends DisposableController @override Future init() async { addAutoDisposeListener(androidCollectionEnabled, () { - storage.setValue( - _androidCollectionEnabledStorageId, - androidCollectionEnabled.value.toString(), + safeUnawaited( + storage.setValue( + _androidCollectionEnabledStorageId, + androidCollectionEnabled.value.toString(), + ), ); if (androidCollectionEnabled.value) { ga.select(gac.memory, gac.MemoryEvents.androidChart.name); @@ -40,7 +42,9 @@ class MemoryPreferencesController extends DisposableController ); addAutoDisposeListener(showChart, () { - storage.setValue(_showChartStorageId, showChart.value.toString()); + safeUnawaited( + storage.setValue(_showChartStorageId, showChart.value.toString()), + ); ga.select( gac.memory, @@ -55,7 +59,9 @@ class MemoryPreferencesController extends DisposableController ); addAutoDisposeListener(refLimit, () { - storage.setValue(_refLimitStorageId, refLimit.value.toString()); + safeUnawaited( + storage.setValue(_refLimitStorageId, refLimit.value.toString()), + ); ga.select(gac.memory, gac.MemoryEvents.browseRefLimit.name); }); diff --git a/packages/devtools_app/lib/src/shared/preferences/_performance_preferences.dart b/packages/devtools_app/lib/src/shared/preferences/_performance_preferences.dart index 2eed61e53db..32d1abafd88 100644 --- a/packages/devtools_app/lib/src/shared/preferences/_performance_preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/_performance_preferences.dart @@ -22,9 +22,11 @@ class PerformancePreferencesController extends DisposableController @override Future init() async { addAutoDisposeListener(showFlutterFramesChart, () { - storage.setValue( - _showFlutterFramesChartId, - showFlutterFramesChart.value.toString(), + safeUnawaited( + storage.setValue( + _showFlutterFramesChartId, + showFlutterFramesChart.value.toString(), + ), ); ga.select( gac.performance, @@ -38,9 +40,11 @@ class PerformancePreferencesController extends DisposableController ); addAutoDisposeListener(includeCpuSamplesInTimeline, () { - storage.setValue( - _includeCpuSamplesInTimelineId, - includeCpuSamplesInTimeline.value.toString(), + safeUnawaited( + storage.setValue( + _includeCpuSamplesInTimelineId, + includeCpuSamplesInTimeline.value.toString(), + ), ); ga.select( gac.performance, diff --git a/packages/devtools_app/lib/src/shared/preferences/preferences.dart b/packages/devtools_app/lib/src/shared/preferences/preferences.dart index 1602dfd0d76..4f4b436de35 100644 --- a/packages/devtools_app/lib/src/shared/preferences/preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/preferences.dart @@ -135,9 +135,11 @@ class PreferencesController extends DisposableController ga.impression(gac.devToolsMain, gac.startingTheme(darkMode: useDarkMode)); toggleDarkModeTheme(useDarkMode); addAutoDisposeListener(darkModeEnabled, () { - storage.setValue( - _UiPreferences.darkMode.storageKey, - '${darkModeEnabled.value}', + safeUnawaited( + storage.setValue( + _UiPreferences.darkMode.storageKey, + '${darkModeEnabled.value}', + ), ); }); } @@ -149,9 +151,11 @@ class PreferencesController extends DisposableController ); toggleVmDeveloperMode(vmDeveloperModeValue); addAutoDisposeListener(vmDeveloperModeEnabled, () { - storage.setValue( - _UiPreferences.vmDeveloperMode.storageKey, - '${vmDeveloperModeEnabled.value}', + safeUnawaited( + storage.setValue( + _UiPreferences.vmDeveloperMode.storageKey, + '${vmDeveloperModeEnabled.value}', + ), ); }); } @@ -237,9 +241,11 @@ class PreferencesController extends DisposableController ); toggleVerboseLogging(verboseLoggingEnabledValue); addAutoDisposeListener(verboseLoggingEnabled, () { - storage.setValue( - _GeneralPreferences.verboseLogging.name, - verboseLoggingEnabled.value.toString(), + safeUnawaited( + storage.setValue( + _GeneralPreferences.verboseLogging.name, + verboseLoggingEnabled.value.toString(), + ), ); }); } diff --git a/packages/devtools_app/lib/src/shared/utils/utils.dart b/packages/devtools_app/lib/src/shared/utils/utils.dart index 8308a32e7f2..f41bf23af67 100644 --- a/packages/devtools_app/lib/src/shared/utils/utils.dart +++ b/packages/devtools_app/lib/src/shared/utils/utils.dart @@ -20,6 +20,7 @@ import 'package:vm_service/vm_service.dart'; import '../../../devtools.dart' as devtools; import '../../service/connected_app/connected_app.dart'; +import '../framework/app_error_handling.dart'; import '../globals.dart'; import '../primitives/query_parameters.dart'; import '../primitives/utils.dart'; @@ -343,7 +344,7 @@ class InterruptableChunkWorker { } progressCallback(0.0); - doChunkWork(0); + safeUnawaited(doChunkWork(0)); return completer.future; } @@ -354,3 +355,13 @@ class InterruptableChunkWorker { } String get devToolsVersion => devtools.version; + +/// Unawaits the given [future] and catches any errors thrown. +void safeUnawaited( + Future future, { + void Function(Object?, StackTrace)? onError, +}) { + onError ??= + (e, st) => reportError('Error in unawaited Future: $e', stack: st); + unawaited(future.catchError(onError)); +} diff --git a/packages/devtools_app/test/screens/vm_developer/object_inspector/vm_developer_common_widgets_test.dart b/packages/devtools_app/test/screens/vm_developer/object_inspector/vm_developer_common_widgets_test.dart index e886f590d66..f2fe081c20e 100644 --- a/packages/devtools_app/test/screens/vm_developer/object_inspector/vm_developer_common_widgets_test.dart +++ b/packages/devtools_app/test/screens/vm_developer/object_inspector/vm_developer_common_widgets_test.dart @@ -193,8 +193,8 @@ void main() { RetainingPathWidget( controller: testObjectInspectorViewController, retainingPath: mockClassObject.retainingPath, - onExpanded: (bool _) { - mockClassObject.requestRetainingPath(); + onExpanded: (bool _) async { + await mockClassObject.requestRetainingPath(); }, ), ), diff --git a/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart b/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart index 29b525d1e51..48dd5da9214 100644 --- a/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart +++ b/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart @@ -21,10 +21,10 @@ void main() async { /// This server can receive requests, and responds to them. Future _bindTestServer() async { final server = await io.HttpServer.bind(io.InternetAddress.loopbackIPv4, 0); - server.listen((request) { + server.listen((request) async { request.response.write('fallthrough'); if (request.uri.path.contains('complete/')) { - request.response.close(); + await request.response.close(); } }); return server; @@ -39,7 +39,7 @@ Future _bindControlServer(io.HttpServer testServer) async { final server = await io.HttpServer.bind(io.InternetAddress.loopbackIPv4, 0); print(json.encode({'controlPort': server.port})); - server.listen((request) { + server.listen((request) async { request.response.headers ..add('Access-Control-Allow-Origin', '*') ..add('Access-Control-Allow-Methods', 'POST,GET,DELETE,PUT,OPTIONS'); @@ -69,7 +69,7 @@ Future _bindControlServer(io.HttpServer testServer) async { client.close(); io.exit(0); } - request.response.close(); + await request.response.close(); }); return server; } diff --git a/packages/devtools_app_shared/test/ui/split_pane_test.dart b/packages/devtools_app_shared/test/ui/split_pane_test.dart index 62a512cd02a..326d3c477e9 100644 --- a/packages/devtools_app_shared/test/ui/split_pane_test.dart +++ b/packages/devtools_app_shared/test/ui/split_pane_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. +import 'dart:async'; + import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; import 'package:flutter/material.dart'; @@ -1161,7 +1163,8 @@ void main() { wrap( Builder( builder: (context) { - expectLater(SplitPane.axisFor(context, 1.0), Axis.horizontal); + unawaited(expectLater( + SplitPane.axisFor(context, 1.0), Axis.horizontal)); return Container(); }, ), @@ -1177,7 +1180,8 @@ void main() { wrap( Builder( builder: (context) { - expectLater(SplitPane.axisFor(context, 1.0), Axis.vertical); + unawaited(expectLater( + SplitPane.axisFor(context, 1.0), Axis.vertical)); return Container(); }, ), diff --git a/packages/devtools_shared/lib/src/service/service.dart b/packages/devtools_shared/lib/src/service/service.dart index d8719b5a9cc..91db01f0514 100644 --- a/packages/devtools_shared/lib/src/service/service.dart +++ b/packages/devtools_shared/lib/src/service/service.dart @@ -34,9 +34,9 @@ Future _connectWithSse({ ); unawaited( - client.sink!.done.whenComplete(() { + client.sink!.done.whenComplete(() async { finishedCompleter.complete(); - service.dispose(); + await service.dispose(); }), ); serviceCompleter.complete(service); @@ -70,9 +70,9 @@ Future _connectWithWebSocket({ } unawaited( ws.sink.done.then( - (_) { + (_) async { finishedCompleter.complete(); - service.dispose(); + await service.dispose(); }, onError: onError, ), @@ -113,15 +113,15 @@ Future connect({ return service; } - connectHelper().then( + unawaited(connectHelper().then( (service) => connectedCompleter.safeComplete(service), onError: onError, - ); - finishedCompleter.future.then((_) { + )); + unawaited(finishedCompleter.future.then((_) { // It is an error if we finish before we are connected. if (!connectedCompleter.isCompleted) { onError(null); } - }); + })); return connectedCompleter.future; } From db827d60a5a93489a2d66f4a68913f77c1b1039f Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Fri, 11 Apr 2025 11:23:33 -0700 Subject: [PATCH 006/107] Update DevTools to next `dev` version: `2.46.0-dev.0` (#9133) --- tool/RELEASE_INSTRUCTIONS.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tool/RELEASE_INSTRUCTIONS.md b/tool/RELEASE_INSTRUCTIONS.md index 4e316c98429..588241af225 100644 --- a/tool/RELEASE_INSTRUCTIONS.md +++ b/tool/RELEASE_INSTRUCTIONS.md @@ -215,16 +215,24 @@ to add DevTools release notes to Flutter website and test them in DevTools. the new release notes. ### Prepare DevTools for the next beta release -1. Update the DevTools version for the next release: + +**The `daily-dev-bump` workflow is currently broken: [#8558](https://github.com/flutter/devtools/issues/8558). Until it's fixed, manually update the DevTools version for the next release and open a PR with the changes:** +```shell +dt update-version auto --type minor +dt update-version auto --type dev +``` + +1. ~~Update the DevTools version for the next release:~~ ```shell gh workflow run daily-dev-bump.yaml -f updateType=minor+dev ``` - This will kick off a workflow that will automatically create a PR with a - `minor` + `dev` version bump. That PR should then be auto-submitted. -2. Make sure that the release PR goes through without issue: - - See the workflow run [here](https://github.com/flutter/devtools/actions/workflows/daily-dev-bump.yaml) - - Go to https://github.com/flutter/devtools/pulls to see the pull request that - ends up being created + ~~This will kick off a workflow that will automatically create a PR with a + `minor` + `dev` version bump. That PR should then be auto-submitted.~~ + +2. ~~Make sure that the release PR goes through without issue:~~ + - ~~See the workflow run [here](https://github.com/flutter/devtools/actions/workflows/daily-dev-bump.yaml)~~ + - ~~Go to https://github.com/flutter/devtools/pulls to see the pull request that + ends up being created~~ ## Dev release into the Dart SDK master branch From 76c27497dee66d5c25733666d063593ca6de724d Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 14 Apr 2025 13:43:46 -0700 Subject: [PATCH 007/107] Prevent web apps from freezing after hot-restarts triggered from DevTools (#9125) --- .../release_notes/NEXT_RELEASE_NOTES.md | 33 +------------------ 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index f326bdafe67..aae3a2f89c1 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -15,40 +15,9 @@ To learn more about DevTools, check out the ## General updates -* Prevent web apps from remaining paused after triggering a hot-restart from +- Prevent web apps from remaining paused after triggering a hot-restart from DevTools. - [#9125](https://github.com/flutter/devtools/pull/9125) -* Added a memory pressure warning that allows you to reduce the memory usage of -DevTools in order to avoid an OOM crash. - -[#8989](https://github.com/flutter/devtools/pull/8989), -[#8997](https://github.com/flutter/devtools/pull/8997), -[#8998](https://github.com/flutter/devtools/pull/8998) - -* Fixed various memory leaks and lifecycle issues. - -[#8901](https://github.com/flutter/devtools/pull/8901), -[#8902](https://github.com/flutter/devtools/pull/8902), -[#8907](https://github.com/flutter/devtools/pull/8907), -[#8917](https://github.com/flutter/devtools/pull/8917), -[#8932](https://github.com/flutter/devtools/pull/8932), -[#8933](https://github.com/flutter/devtools/pull/8933), -[#8934](https://github.com/flutter/devtools/pull/8934), -[#8935](https://github.com/flutter/devtools/pull/8935), -[#8937](https://github.com/flutter/devtools/pull/8937), -[#8953](https://github.com/flutter/devtools/pull/8953), -[#8969](https://github.com/flutter/devtools/pull/8969), -[#8970](https://github.com/flutter/devtools/pull/8970), -[#8975](https://github.com/flutter/devtools/pull/8975) - -* Fix a bug with the review history on disconnect experience. - -[#8985](https://github.com/flutter/devtools/pull/8985) - -* Fixed bug where DevTools would automatically resume instead of -pausing on breakpoint on connection. - -[#8991](https://github.com/flutter/devtools/pull/8991) - -* Prevented text inputs from stealing focus from the IDE. - -[#9091](https://github.com/flutter/devtools/pull/9091) - ## Inspector updates TODO: Remove this section if there are not any general updates. From b7c4aaf14641f2e48d53644e4c1d754b1052a05a Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Tue, 15 Apr 2025 11:05:21 -0700 Subject: [PATCH 008/107] Update Flutter and min sdk versions (#9140) --- flutter-candidate.txt | 2 +- packages/devtools_app/pubspec.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flutter-candidate.txt b/flutter-candidate.txt index 3dd922d589a..61f6f6d653e 100644 --- a/flutter-candidate.txt +++ b/flutter-candidate.txt @@ -1 +1 @@ -ceec33f16beaccf5e7a86099f0544ea52a327b28 +a7f820163c5d7d5321872c60f22fa047fb94bd7b diff --git a/packages/devtools_app/pubspec.yaml b/packages/devtools_app/pubspec.yaml index da76c9c0860..dc888a41e21 100644 --- a/packages/devtools_app/pubspec.yaml +++ b/packages/devtools_app/pubspec.yaml @@ -12,8 +12,8 @@ version: 2.46.0-dev.1 repository: https://github.com/flutter/devtools/tree/master/packages/devtools_app environment: - sdk: ">=3.7.0-160.0.dev <4.0.0" - flutter: ">=3.27.0-1.0.pre.563" + sdk: ">=3.8.0-265.0.dev <4.0.0" + flutter: ">=3.32.0-1.0.pre.73" resolution: workspace From 20a0f032495880103eaf871dda8a9a65f1cc538c Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:24:18 -0700 Subject: [PATCH 009/107] DevTools colors match IDE theme (#9144) --- .../screens/debugger/program_explorer.dart | 2 +- .../panes/chart/widgets/chart_pane.dart | 3 +-- .../memory/panes/chart/widgets/legend.dart | 3 +-- .../service/service_extension_widgets.dart | 3 +-- .../lib/src/shared/charts/flame_chart.dart | 2 +- .../lib/src/shared/ui/colors.dart | 14 +++----------- .../lib/src/shared/ui/search.dart | 2 +- .../goldens/codeview_scrollbars.png | Bin 26824 -> 25971 bytes .../memory/load_offline_data_profile_tab.png | Bin 28821 -> 31964 bytes .../memory/load_offline_data_trace_tab.png | Bin 55939 -> 55839 bytes 10 files changed, 9 insertions(+), 20 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart b/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart index d1d66a63075..e0efbc2741a 100644 --- a/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart +++ b/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart @@ -255,7 +255,7 @@ class ProgramStructureIcon extends StatelessWidget { style: TextStyle( height: 1, fontFamily: theme.fixedFontStyle.fontFamily, - color: theme.colorScheme.defaultBackgroundColor, + color: theme.colorScheme.surface, fontSize: smallFontSize, ), // Required to center the individual character within the diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart index dab5ec7b814..a5f6b48ec89 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart @@ -10,7 +10,6 @@ import 'package:flutter/services.dart'; import '../../../../../shared/charts/chart_controller.dart'; import '../../../../../shared/globals.dart'; import '../../../../../shared/primitives/utils.dart'; -import '../../../../../shared/ui/colors.dart'; import '../../../../../shared/ui/common_widgets.dart'; import '../../../../../shared/utils/utils.dart'; import '../../../shared/primitives/painting.dart'; @@ -298,7 +297,7 @@ class _MemoryChartPaneState extends State child: Container( padding: const EdgeInsets.only(top: 5, bottom: 8), decoration: BoxDecoration( - color: colorScheme.defaultBackgroundColor, + color: colorScheme.surface, border: Border.all( color: focusColor, width: _hoverCardBorderWidth, diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart index 61982592ef2..fa94584ae01 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart @@ -5,7 +5,6 @@ import 'package:devtools_app_shared/ui.dart'; import 'package:flutter/material.dart'; -import '../../../../../shared/ui/colors.dart'; import '../../../shared/primitives/painting.dart'; import '../controller/chart_pane_controller.dart'; import '../controller/charts/android_chart_controller.dart'; @@ -85,7 +84,7 @@ class MemoryChartLegend extends StatelessWidget { height: isAndroidVisible ? _legendHeight2Charts : _legendHeight1Chart, padding: const EdgeInsets.only(top: densePadding, right: densePadding), decoration: BoxDecoration( - color: colorScheme.defaultBackgroundColor, + color: colorScheme.surface, border: Border.all(color: theme.focusColor), borderRadius: defaultBorderRadius, ), diff --git a/packages/devtools_app/lib/src/service/service_extension_widgets.dart b/packages/devtools_app/lib/src/service/service_extension_widgets.dart index 15f0b734a0a..22823a646cb 100644 --- a/packages/devtools_app/lib/src/service/service_extension_widgets.dart +++ b/packages/devtools_app/lib/src/service/service_extension_widgets.dart @@ -23,7 +23,6 @@ import '../shared/constants.dart'; import '../shared/globals.dart'; import '../shared/primitives/message_bus.dart'; import '../shared/primitives/utils.dart'; -import '../shared/ui/colors.dart'; import '../shared/ui/common_widgets.dart'; import '../shared/ui/hover.dart'; import 'service_extensions.dart'; @@ -891,7 +890,7 @@ class _ServiceExtensionCheckboxGroupOverlay extends StatelessWidget { width: width, padding: const EdgeInsets.all(defaultSpacing), decoration: BoxDecoration( - color: theme.colorScheme.defaultBackgroundColor, + color: theme.colorScheme.surface, border: Border.all( color: theme.focusColor, width: hoverCardBorderSize, diff --git a/packages/devtools_app/lib/src/shared/charts/flame_chart.dart b/packages/devtools_app/lib/src/shared/charts/flame_chart.dart index bec744b1695..5cc26b7066e 100644 --- a/packages/devtools_app/lib/src/shared/charts/flame_chart.dart +++ b/packages/devtools_app/lib/src/shared/charts/flame_chart.dart @@ -1337,7 +1337,7 @@ class TimelineGridPainter extends FlameChartPainter { constraints.maxWidth, math.min(constraints.maxHeight, chartRowHeight), ), - Paint()..color = colorScheme.defaultBackgroundColor, + Paint()..color = colorScheme.surface, ); // Paint the timeline grid lines and corresponding timestamps in the flame diff --git a/packages/devtools_app/lib/src/shared/ui/colors.dart b/packages/devtools_app/lib/src/shared/ui/colors.dart index 504d88f36ef..2232fd6d282 100644 --- a/packages/devtools_app/lib/src/shared/ui/colors.dart +++ b/packages/devtools_app/lib/src/shared/ui/colors.dart @@ -107,20 +107,12 @@ extension SyntaxHighlightingExtension on ColorScheme { isLight ? const Color(0xFF098658) : const Color(0xFFB5CEA8); } -// TODO(kenz): try to get rid of these colors and replace with something from -// the light and dark DevTools color schemes. extension DevToolsColorExtension on ColorScheme { - // TODO(jacobr): replace this with Theme.of(context).scaffoldBackgroundColor, but we use - // this in places where we do not have access to the context. - // remove. - // TODO(kenz): get rid of this. - Color get defaultBackgroundColor => - isLight ? Colors.grey[50]! : const Color(0xFF1B1B1F); - Color get grey => const Color.fromARGB(255, 128, 128, 128); Color get green => isLight ? const Color(0xFF006B5F) : const Color(0xFF54DBC8); - Color get overlayShadowColor => const Color.fromRGBO(0, 0, 0, 0.5); - Color get deeplinkTableHeaderColor => isLight ? Colors.white : Colors.black; + // Deep link header is slightly darker than the default surface color. See + // comment at: https://github.com/flutter/devtools/pull/7443/files#r1538361768 + Color get deeplinkTableHeaderColor => surface.darken(); } diff --git a/packages/devtools_app/lib/src/shared/ui/search.dart b/packages/devtools_app/lib/src/shared/ui/search.dart index 4949f0429ce..2107561794c 100644 --- a/packages/devtools_app/lib/src/shared/ui/search.dart +++ b/packages/devtools_app/lib/src/shared/ui/search.dart @@ -405,7 +405,7 @@ class AutoCompleteState extends State with AutoDisposeMixin { controller: controller, onTap: autoComplete.onTap, highlightColor: colorScheme.autoCompleteHighlightColor, - defaultColor: colorScheme.defaultBackgroundColor, + defaultColor: colorScheme.surface, ), ); } diff --git a/packages/devtools_app/test/test_infra/goldens/codeview_scrollbars.png b/packages/devtools_app/test/test_infra/goldens/codeview_scrollbars.png index d9611e57e16f100ee90a95049bd4ab7b2206a89b..7a128d4bb0409b57259ab5d9ea850ea8470c834a 100644 GIT binary patch literal 25971 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 diff --git a/packages/devtools_app/test/test_infra/goldens/memory/load_offline_data_profile_tab.png b/packages/devtools_app/test/test_infra/goldens/memory/load_offline_data_profile_tab.png index 7ee3a2273c5ebb243a05647fb94e140147259c2a..f3ff3691f1da8dccd449309c52e5c02f1f2bb994 100644 GIT binary patch literal 31964 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 YA~V*eCE3e5#+{4lDGTGglg_{Y2V>Ev(*OVf literal 28821 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%0A*b~* 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 From 78aafaecc6f3d5a5d626789386223bf4df324847 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Thu, 17 Apr 2025 08:58:28 -0700 Subject: [PATCH 010/107] Do not show release notes for standalone screens (#9147) --- .../devtools_app/lib/src/framework/release_notes.dart | 9 ++++----- .../lib/src/standalone_ui/standalone_screen.dart | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/devtools_app/lib/src/framework/release_notes.dart b/packages/devtools_app/lib/src/framework/release_notes.dart index 12cc5604dcb..be9243f6caf 100644 --- a/packages/devtools_app/lib/src/framework/release_notes.dart +++ b/packages/devtools_app/lib/src/framework/release_notes.dart @@ -65,15 +65,14 @@ class ReleaseNotesController extends SidePanelController { } void _maybeShowReleaseNotes() async { - // Do not show release notes in embedded sidebar. + // Do not show release notes in standalone screens. The fact that these + // screens are hosted by DevTools is an implementation detail, but from the + // user's perspective, these tools are part of the IDE. if (isEmbedded()) { final currentUrl = getWebUrl(); final currentPage = currentUrl != null ? extractCurrentPageFromUrl(currentUrl) : null; - if (currentPage == StandaloneScreenType.vsCodeFlutterPanel.name || - currentPage == StandaloneScreenType.editorSidebar.name) { - return; - } + if (StandaloneScreenType.includes(currentPage)) return; } SemanticVersion previousVersion = SemanticVersion(); diff --git a/packages/devtools_app/lib/src/standalone_ui/standalone_screen.dart b/packages/devtools_app/lib/src/standalone_ui/standalone_screen.dart index e129e528b59..b1e1bfaff3d 100644 --- a/packages/devtools_app/lib/src/standalone_ui/standalone_screen.dart +++ b/packages/devtools_app/lib/src/standalone_ui/standalone_screen.dart @@ -56,6 +56,9 @@ enum StandaloneScreenType { ), }; } + + static bool includes(String? screenName) => + values.any((value) => value.name == screenName); } /// Widget that returns a [CenteredCircularProgressIndicator] while it waits for From e74fb2f8ddbb63898846a9eb0d90c0cf2070f8fd Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Thu, 17 Apr 2025 10:05:25 -0700 Subject: [PATCH 011/107] Dismiss banner messages on connection changes by default (#9148) --- .../src/extensions/embedded/_view_web.dart | 2 + .../framework/observer/memory_observer.dart | 1 + .../src/shared/managers/banner_messages.dart | 52 ++++++++++++------- .../release_notes/NEXT_RELEASE_NOTES.md | 1 + .../observer/memory_observer_test.dart | 1 + .../memory/framework/memory_screen_test.dart | 2 +- .../performance/performance_screen_test.dart | 1 + .../shared/managers/banner_messages_test.dart | 34 ++++++++++++ .../scenes/cpu_profiler/default.dart | 2 +- .../test_infra/scenes/memory/default.dart | 2 +- packages/devtools_extensions/CHANGELOG.md | 2 + .../lib/src/api/model.dart | 10 ++++ 12 files changed, 88 insertions(+), 22 deletions(-) diff --git a/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart b/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart index 02c0cf1740f..47cce6525b5 100644 --- a/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart +++ b/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart @@ -314,6 +314,8 @@ class _ExtensionIFrameController extends DisposableController '${showBannerMessageEvent.messageId}', ), screenId: '${showBannerMessageEvent.extensionName}_ext', + dismissOnConnectionChanges: + showBannerMessageEvent.dismissOnConnectionChanges, buildTextSpans: (_) => [ TextSpan( diff --git a/packages/devtools_app/lib/src/framework/observer/memory_observer.dart b/packages/devtools_app/lib/src/framework/observer/memory_observer.dart index fa251a28b8d..148f86686cc 100644 --- a/packages/devtools_app/lib/src/framework/observer/memory_observer.dart +++ b/packages/devtools_app/lib/src/framework/observer/memory_observer.dart @@ -151,6 +151,7 @@ class _MemoryPressureBannerMessage extends banner_messages.BannerWarning { : super( screenId: banner_messages.universalScreenId, key: _messageKey, + dismissOnConnectionChanges: false, buildTextSpans: (context) { final limitAsBytes = convertBytes( MemoryObserver._memoryPressureLimitGb, diff --git a/packages/devtools_app/lib/src/shared/managers/banner_messages.dart b/packages/devtools_app/lib/src/shared/managers/banner_messages.dart index 627c540b8e1..5d468e4e6db 100644 --- a/packages/devtools_app/lib/src/shared/managers/banner_messages.dart +++ b/packages/devtools_app/lib/src/shared/managers/banner_messages.dart @@ -30,7 +30,33 @@ const _cpuSamplingRateDocsUrl = /// every screen from the [BannerMessages] widget. const universalScreenId = 'universal'; -class BannerMessagesController { +class BannerMessagesController extends DisposableController + with AutoDisposeControllerMixin { + BannerMessagesController() { + previouslyConnected = + serviceConnection.serviceManager.connectedState.value.connected; + addAutoDisposeListener(serviceConnection.serviceManager.connectedState, () { + final connected = + serviceConnection.serviceManager.connectedState.value.connected; + if (previouslyConnected != connected) { + for (final messageList in _messages.values) { + for (final message in messageList.value) { + if (message.dismissOnConnectionChanges) { + bannerMessages.removeMessage(message); + } + } + } + } + previouslyConnected = connected; + }); + } + + /// Tracks the previous app connection state for the purpose of dismissing + /// messages upon connection changes. + /// + /// See [BannerMessage.dismissOnConnectionChanges]. + bool previouslyConnected = false; + final _messages = >{}; final _dismissedMessageKeys = {}; @@ -165,6 +191,7 @@ class BannerMessage extends StatelessWidget { required this.buildTextSpans, required this.screenId, required this.messageType, + this.dismissOnConnectionChanges = true, this.buildActions, }); @@ -173,6 +200,9 @@ class BannerMessage extends StatelessWidget { final String screenId; final BannerMessageType messageType; + /// Whether this message should be dismissed on app connection changes. + final bool dismissOnConnectionChanges; + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -284,6 +314,7 @@ class BannerWarning extends BannerMessage { required super.key, required super.buildTextSpans, required super.screenId, + super.dismissOnConnectionChanges = true, super.buildActions, }) : super(messageType: BannerMessageType.warning); } @@ -293,6 +324,7 @@ class BannerInfo extends BannerMessage { required super.key, required super.buildTextSpans, required super.screenId, + super.dismissOnConnectionChanges = true, super.buildActions, }) : super(messageType: BannerMessageType.info); } @@ -322,23 +354,6 @@ class DebugModePerformanceMessage extends BannerWarning { ); } -class ProviderUnknownErrorBanner extends _BannerError { - ProviderUnknownErrorBanner({required super.screenId}) - : super( - key: Key('ProviderUnknownErrorBanner - $screenId'), - buildTextSpans: - (_) => [ - TextSpan( - text: ''' -DevTools failed to connect with package:provider. - -This could be caused by an older version of package:provider; please make sure that you are using version >=5.0.0.''', - style: TextStyle(fontSize: defaultFontSize), - ), - ], - ); -} - class ShaderJankMessage extends _BannerError { ShaderJankMessage({ required super.screenId, @@ -520,7 +535,6 @@ class WelcomeToNewInspectorMessage extends BannerInfo { WelcomeToNewInspectorMessage({required super.screenId}) : super( key: Key('WelcomeToNewInspectorMessage - $screenId'), - buildTextSpans: (context) => [ const TextSpan( diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index aae3a2f89c1..5673a98406e 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -17,6 +17,7 @@ To learn more about DevTools, check out the - Prevent web apps from remaining paused after triggering a hot-restart from DevTools. - [#9125](https://github.com/flutter/devtools/pull/9125) +- Dismiss stale banner messages when the connected app state changes. - [#9148](https://github.com/flutter/devtools/pull/9148) ## Inspector updates diff --git a/packages/devtools_app/test/framework/observer/memory_observer_test.dart b/packages/devtools_app/test/framework/observer/memory_observer_test.dart index fba17a54b54..0679976c6e5 100644 --- a/packages/devtools_app/test/framework/observer/memory_observer_test.dart +++ b/packages/devtools_app/test/framework/observer/memory_observer_test.dart @@ -46,6 +46,7 @@ void main() { debugMeasureUsageInBytes: testMeasureMemoryUsage, pollingDuration: const Duration(milliseconds: 1), ); + setGlobal(ServiceConnectionManager, FakeServiceConnectionManager()); setGlobal(BannerMessagesController, BannerMessagesController()); offlineDataController = MockOfflineDataController(); offlineDataController.showingOfflineData.value = false; diff --git a/packages/devtools_app/test/screens/memory/framework/memory_screen_test.dart b/packages/devtools_app/test/screens/memory/framework/memory_screen_test.dart index e47552fb7da..79befb2bf5c 100644 --- a/packages/devtools_app/test/screens/memory/framework/memory_screen_test.dart +++ b/packages/devtools_app/test/screens/memory/framework/memory_screen_test.dart @@ -87,10 +87,10 @@ void main() { setGlobal(OfflineDataController, OfflineDataController()); setGlobal(IdeTheme, IdeTheme()); setGlobal(NotificationService, NotificationService()); - setGlobal(BannerMessagesController, BannerMessagesController()); setGlobal(DTDManager, MockDTDManager()); setGlobal(ScriptManager, MockScriptManager()); setUpServiceManagerForMemory(); + setGlobal(BannerMessagesController, BannerMessagesController()); }); testWidgets('builds its tab', (WidgetTester tester) async { diff --git a/packages/devtools_app/test/screens/performance/performance_screen_test.dart b/packages/devtools_app/test/screens/performance/performance_screen_test.dart index 20c02224080..8c93288bb13 100644 --- a/packages/devtools_app/test/screens/performance/performance_screen_test.dart +++ b/packages/devtools_app/test/screens/performance/performance_screen_test.dart @@ -37,6 +37,7 @@ void main() { setGlobal(PreferencesController, PreferencesController()); setGlobal(OfflineDataController, OfflineDataController()); setGlobal(NotificationService, NotificationService()); + setGlobal(ServiceConnectionManager, FakeServiceConnectionManager()); setGlobal(BannerMessagesController, BannerMessagesController()); }); diff --git a/packages/devtools_app/test/shared/managers/banner_messages_test.dart b/packages/devtools_app/test/shared/managers/banner_messages_test.dart index 8bbc62ea0c2..dedf7e206cb 100644 --- a/packages/devtools_app/test/shared/managers/banner_messages_test.dart +++ b/packages/devtools_app/test/shared/managers/banner_messages_test.dart @@ -160,6 +160,32 @@ void main() { expect(find.byKey(k1), findsOneWidget); }, ); + + testWidgets('messages dismiss on connection changes', ( + WidgetTester tester, + ) async { + expect( + fakeServiceConnection.serviceManager.connectedState.value.connected, + true, + ); + await tester.pumpWidget(buildBannerMessages()); + expect(find.byKey(k1), findsNothing); + expect(find.byKey(k2), findsNothing); + + // Add a message that should dismiss on connection changes. + bannerMessages.addMessage(testMessage1); + // Add a message that should not dismiss on connection changes. + bannerMessages.addMessage(testMessageNoDismiss); + await pumpTestFrame(tester); + expect(find.byKey(k1), findsOneWidget); + expect(find.byKey(k2), findsOneWidget); + + // Simulate a connection loss. + await fakeServiceConnection.serviceManager.manuallyDisconnect(); + await pumpTestFrame(tester); + expect(find.byKey(k1), findsNothing); + expect(find.byKey(k2), findsOneWidget); + }); }); } @@ -184,6 +210,14 @@ final testMessage2 = BannerMessage( messageType: BannerMessageType.warning, ); +final testMessageNoDismiss = BannerMessage( + key: k2, + buildTextSpans: (_) => const [TextSpan(text: 'Test Message 2')], + screenId: testMessage2ScreenId, + messageType: BannerMessageType.warning, + dismissOnConnectionChanges: false, +); + final universalMessage = BannerMessage( key: kUniversal, buildTextSpans: (_) => const [TextSpan(text: 'Universal Message')], diff --git a/packages/devtools_app/test/test_infra/scenes/cpu_profiler/default.dart b/packages/devtools_app/test/test_infra/scenes/cpu_profiler/default.dart index 7c8bb9435a4..3bced37f561 100644 --- a/packages/devtools_app/test/test_infra/scenes/cpu_profiler/default.dart +++ b/packages/devtools_app/test/test_infra/scenes/cpu_profiler/default.dart @@ -41,7 +41,6 @@ class CpuProfilerDefaultScene extends Scene { setGlobal(IdeTheme, IdeTheme()); setGlobal(NotificationService, NotificationService()); setGlobal(PreferencesController, PreferencesController()); - setGlobal(BannerMessagesController, BannerMessagesController()); fakeServiceConnection = FakeServiceConnectionManager( service: FakeServiceManager.createFakeService( @@ -59,6 +58,7 @@ class CpuProfilerDefaultScene extends Scene { fakeServiceConnection.errorBadgeManager.errorCountNotifier('profiler'), ).thenReturn(ValueNotifier(0)); setGlobal(ServiceConnectionManager, fakeServiceConnection); + setGlobal(BannerMessagesController, BannerMessagesController()); final mockScriptManager = MockScriptManager(); when( diff --git a/packages/devtools_app/test/test_infra/scenes/memory/default.dart b/packages/devtools_app/test/test_infra/scenes/memory/default.dart index 7562a661d33..2ce1ef5db17 100644 --- a/packages/devtools_app/test/test_infra/scenes/memory/default.dart +++ b/packages/devtools_app/test/test_infra/scenes/memory/default.dart @@ -106,7 +106,6 @@ class MemoryDefaultScene extends Scene { setGlobal(OfflineDataController, OfflineDataController()); setGlobal(IdeTheme, IdeTheme()); setGlobal(NotificationService, NotificationService()); - setGlobal(BannerMessagesController, BannerMessagesController()); setGlobal( PreferencesController, PreferencesController()..memory.showChart.value = false, @@ -138,6 +137,7 @@ class MemoryDefaultScene extends Scene { fakeServiceConnection.serviceManager.vm.operatingSystem, ).thenReturn('ios'); setGlobal(ServiceConnectionManager, fakeServiceConnection); + setGlobal(BannerMessagesController, BannerMessagesController()); setGlobal(OfflineDataController, OfflineDataController()); final showAllFilter = ClassFilter( diff --git a/packages/devtools_extensions/CHANGELOG.md b/packages/devtools_extensions/CHANGELOG.md index b6e27c08e50..bdb1090cd4d 100644 --- a/packages/devtools_extensions/CHANGELOG.md +++ b/packages/devtools_extensions/CHANGELOG.md @@ -5,6 +5,8 @@ found in the LICENSE file or at https://developers.google.com/open-source/licens --> ## 0.3.2 (not released) * Bump `devtools_app_shared` dependency to `0.4.0`. +* Add `ShowBannerMessageExtensionEvent.dismissOnConnectionChanges` field. This +value is set from an optional parameter in the constructor (defaults to `true`). ## 0.3.1 * Bump `vm_service` dependency to `>=13.0.0 <16.0.0`. diff --git a/packages/devtools_extensions/lib/src/api/model.dart b/packages/devtools_extensions/lib/src/api/model.dart index 7280f83e7cb..7dd9c1fc4f1 100644 --- a/packages/devtools_extensions/lib/src/api/model.dart +++ b/packages/devtools_extensions/lib/src/api/model.dart @@ -92,6 +92,7 @@ class ShowBannerMessageExtensionEvent extends DevToolsExtensionEvent { required String message, required String extensionName, bool ignoreIfAlreadyDismissed = true, + bool dismissOnConnectionChanges = true, }) : assert(bannerMessageType == 'warning' || bannerMessageType == 'error'), super( DevToolsExtensionEventType.showBannerMessage, @@ -101,6 +102,7 @@ class ShowBannerMessageExtensionEvent extends DevToolsExtensionEvent { _messageKey: message, _extensionNameKey: extensionName, _ignoreIfAlreadyDismissedKey: ignoreIfAlreadyDismissed, + _dismissOnConnectionChangesKey: dismissOnConnectionChanges, }, ); @@ -113,12 +115,15 @@ class ShowBannerMessageExtensionEvent extends DevToolsExtensionEvent { final extensionName = eventData.checkValid(_extensionNameKey); final ignoreIfAlreadyDismissed = (eventData[_ignoreIfAlreadyDismissedKey] as bool?) ?? true; + final dismissOnConnectionChanges = + (eventData[_dismissOnConnectionChangesKey] as bool?) ?? true; return ShowBannerMessageExtensionEvent( id: id, bannerMessageType: type, message: message, extensionName: extensionName, ignoreIfAlreadyDismissed: ignoreIfAlreadyDismissed, + dismissOnConnectionChanges: dismissOnConnectionChanges, ); } @@ -127,6 +132,7 @@ class ShowBannerMessageExtensionEvent extends DevToolsExtensionEvent { static const _bannerMessageTypeKey = 'bannerMessageType'; static const _extensionNameKey = 'extensionName'; static const _ignoreIfAlreadyDismissedKey = 'ignoreIfAlreadyDismissed'; + static const _dismissOnConnectionChangesKey = 'dismissOnConnectionChanges'; String get messageId => data![_idKey] as String; String get bannerMessageType => data![_bannerMessageTypeKey] as String; @@ -134,6 +140,10 @@ class ShowBannerMessageExtensionEvent extends DevToolsExtensionEvent { String get extensionName => data![_extensionNameKey] as String; bool get ignoreIfAlreadyDismissed => (data![_ignoreIfAlreadyDismissedKey] as bool?) ?? true; + + /// Whether this message should be dismissed on app connection changes. + bool get dismissOnConnectionChanges => + (data![_dismissOnConnectionChangesKey] as bool?) ?? true; } /// An extension event of type [DevToolsExtensionEventType.copyToClipboard] From 99447af8fb3387fe647d0e5697afb9c21cde9df9 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:03:24 -0700 Subject: [PATCH 012/107] Skip simple_items_test.dart for customer tests (#9150) --- .../shared/primitives/simple_items_test.dart | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/devtools_app/test/shared/primitives/simple_items_test.dart b/packages/devtools_app/test/shared/primitives/simple_items_test.dart index 2dc161fae64..0426182aaa3 100644 --- a/packages/devtools_app/test/shared/primitives/simple_items_test.dart +++ b/packages/devtools_app/test/shared/primitives/simple_items_test.dart @@ -3,18 +3,25 @@ // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. import 'package:devtools_app/src/shared/primitives/simple_items.dart'; +import 'package:devtools_test/helpers.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../test_infra/utils/test_utils.dart'; void main() { for (final link in DocLinks.values) { - test('$link is not broken', () async { - final content = await loadPageHtmlContent(link.value); - final hash = link.hash; - if (hash != null) { - expect(content, contains('href="#$hash"')); - } - }); + test( + '$link is not broken', + () async { + final content = await loadPageHtmlContent(link.value); + final hash = link.hash; + if (hash != null) { + expect(content, contains('href="#$hash"')); + } + }, + // This test hits the network, which is a violation of Flutter customer + // tests policy: https://github.com/flutter/tests?tab=readme-ov-file#adding-more-tests. + tags: skipForCustomerTestsTag, + ); } } From 06a7ccf443f049d0510613740929472bd8ea4f90 Mon Sep 17 00:00:00 2001 From: Brian Quinlan Date: Mon, 21 Apr 2025 15:26:28 -0700 Subject: [PATCH 013/107] Remove reference to removed `NodeGlue` (#9151) --- .../src/shared/config_specific/import_export/_export_web.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/shared/config_specific/import_export/_export_web.dart b/packages/devtools_app/lib/src/shared/config_specific/import_export/_export_web.dart index 7b6e865ac47..d78708747ce 100644 --- a/packages/devtools_app/lib/src/shared/config_specific/import_export/_export_web.dart +++ b/packages/devtools_app/lib/src/shared/config_specific/import_export/_export_web.dart @@ -5,7 +5,7 @@ import 'dart:js_interop'; import 'dart:typed_data'; -import 'package:web/web.dart' hide NodeGlue; +import 'package:web/web.dart'; import 'import_export.dart'; From 3e85371e87c1599b6609dba9f931335bb036a32b Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Thu, 1 May 2025 12:04:23 -0700 Subject: [PATCH 014/107] Do not await service extension call in the performance screen (#9162) --- .../flutter_frames/flutter_frames_chart.dart | 63 +++++++++++-------- .../performance/performance_controller.dart | 22 +++++-- .../release_notes/NEXT_RELEASE_NOTES.md | 3 +- .../flutter_frames_chart_test.dart | 2 +- 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart index 0ed3c6f5d9a..1a42f8bcf2d 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart @@ -7,6 +7,7 @@ import 'dart:math' as math; import 'package:devtools_app_shared/ui.dart'; import 'package:devtools_app_shared/utils.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import '../../../../shared/analytics/analytics.dart' as ga; @@ -39,7 +40,7 @@ class FlutterFramesChart extends StatelessWidget { final bool showingOfflineData; - final bool impellerEnabled; + final ValueListenable impellerEnabled; @override Widget build(BuildContext context) { @@ -86,7 +87,7 @@ class _FlutterFramesChart extends StatefulWidget { final bool showingOfflineData; - final bool impellerEnabled; + final ValueListenable impellerEnabled; static double get frameNumberSectionHeight => scaleByFontFactor(20.0); @@ -203,7 +204,7 @@ class FramesChart extends StatefulWidget { final BoxConstraints constraints; - final bool impellerEnabled; + final ValueListenable impellerEnabled; @override State createState() => _FramesChartState(); @@ -346,13 +347,18 @@ class _FramesChartState extends State with AutoDisposeMixin { chartAxisPainter, Padding(padding: EdgeInsets.only(left: _yAxisUnitsSpace), child: chart), fpsLinePainter, - Positioned( - right: denseSpacing, - top: densePadding, - child: Text( - 'Engine: ${widget.impellerEnabled ? 'Impeller' : 'Skia'}', - style: themeData.subtleChartTextStyle, - ), + ValueListenableBuilder( + valueListenable: widget.impellerEnabled, + builder: (context, impellerEnabled, child) { + return Positioned( + right: denseSpacing, + top: densePadding, + child: Text( + 'Engine: ${impellerEnabled ? 'Impeller' : 'Skia'}', + style: themeData.subtleChartTextStyle, + ), + ); + }, ), ], ); @@ -382,7 +388,7 @@ class FramesChartControls extends StatelessWidget { final bool showingOfflineData; - final bool impellerEnabled; + final ValueListenable impellerEnabled; @override Widget build(BuildContext context) { @@ -408,21 +414,26 @@ class FramesChartControls extends StatelessWidget { ); }, ), - Legend( - dense: true, - entries: [ - LegendEntry(terse ? 'UI' : 'Frame Time (UI)', mainUiColor), - LegendEntry( - terse ? 'Raster' : 'Frame Time (Raster)', - mainRasterColor, - ), - LegendEntry(terse ? 'Jank' : 'Jank (slow frame)', uiJankColor), - if (!impellerEnabled) - LegendEntry( - 'Shader Compilation', - shaderCompilationColor.background, - ), - ], + ValueListenableBuilder( + valueListenable: impellerEnabled, + builder: (context, impellerEnabled, child) { + return Legend( + dense: true, + entries: [ + LegendEntry(terse ? 'UI' : 'Frame Time (UI)', mainUiColor), + LegendEntry( + terse ? 'Raster' : 'Frame Time (Raster)', + mainRasterColor, + ), + LegendEntry(terse ? 'Jank' : 'Jank (slow frame)', uiJankColor), + if (!impellerEnabled) + LegendEntry( + 'Shader Compilation', + shaderCompilationColor.background, + ), + ], + ); + }, ), AverageFPS( frames: frames, diff --git a/packages/devtools_app/lib/src/screens/performance/performance_controller.dart b/packages/devtools_app/lib/src/screens/performance/performance_controller.dart index e097bf052b9..c15d9311494 100644 --- a/packages/devtools_app/lib/src/screens/performance/performance_controller.dart +++ b/packages/devtools_app/lib/src/screens/performance/performance_controller.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'package:devtools_app_shared/service.dart'; import 'package:devtools_app_shared/utils.dart'; +import 'package:flutter/foundation.dart'; import 'package:vm_service/vm_service.dart'; import '../../service/service_registrations.dart' as registrations; @@ -83,8 +84,8 @@ class PerformanceController extends DevToolsScreenController /// any selection modifications that occur while the data is displayed. OfflinePerformanceData? offlinePerformanceData; - bool get impellerEnabled => _impellerEnabled; - bool _impellerEnabled = false; + ValueListenable get impellerEnabled => _impellerEnabled; + final _impellerEnabled = ValueNotifier(false); Future get initialized => _initialized.future; final _initialized = Completer(); @@ -124,11 +125,19 @@ class PerformanceController extends DevToolsScreenController if (serviceConnection.serviceManager.connectedApp?.isFlutterAppNow ?? false) { - final impellerEnabledResponse = await serviceConnection.serviceManager - .callServiceExtensionOnMainIsolate(registrations.isImpellerEnabled); - _impellerEnabled = impellerEnabledResponse.json?['enabled'] == true; + // Do not await this future because this will hang if the app is paused + // upon connection. + unawaited( + serviceConnection.serviceManager + .callServiceExtensionOnMainIsolate( + registrations.isImpellerEnabled, + ) + .then((response) { + _impellerEnabled.value = response.json?['enabled'] == true; + }), + ); } else { - _impellerEnabled = false; + _impellerEnabled.value = false; } enhanceTracingController.init(); @@ -264,6 +273,7 @@ class PerformanceController extends DevToolsScreenController _applyToFeatureControllers((c) => c.dispose()); enhanceTracingController.dispose(); rebuildCountModel.dispose(); + _impellerEnabled.dispose(); super.dispose(); } diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index 5673a98406e..a2f41894e59 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -25,7 +25,8 @@ TODO: Remove this section if there are not any general updates. ## Performance updates -TODO: Remove this section if there are not any general updates. +- Fixes a bug where the Performance page would hang when connected to a paused +Flutter app. - [#9162](https://github.com/flutter/devtools/pull/9162) ## CPU profiler updates diff --git a/packages/devtools_app/test/screens/performance/flutter_frames/flutter_frames_chart_test.dart b/packages/devtools_app/test/screens/performance/flutter_frames/flutter_frames_chart_test.dart index a7440db23fa..b0d63ca2370 100644 --- a/packages/devtools_app/test/screens/performance/flutter_frames/flutter_frames_chart_test.dart +++ b/packages/devtools_app/test/screens/performance/flutter_frames/flutter_frames_chart_test.dart @@ -29,7 +29,7 @@ void main() { FlutterFramesChart( framesController, showingOfflineData: showingOfflineData, - impellerEnabled: impellerEnabled, + impellerEnabled: FixedValueListenable(impellerEnabled), ), ), ); From aba3d4ab370dd183de00d27fd147f8928dff5a0f Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Thu, 1 May 2025 15:44:32 -0700 Subject: [PATCH 015/107] Bump flutter candidate and update formatting. (#9165) --- .github/workflows/build.yaml | 2 +- flutter-candidate.txt | 2 +- .../benchmark/devtools_benchmarks_test.dart | 7 +- .../benchmark/scripts/run_benchmarks.dart | 7 +- .../test_infra/client/client_shared.dart | 19 +- .../benchmark/test_infra/common.dart | 9 +- .../integration_test/run_tests.dart | 4 +- .../devtools_extensions_test.dart | 18 +- .../test_infra/run/_test_app_driver.dart | 27 +- .../test_infra/run/run_test.dart | 9 +- packages/devtools_app/lib/src/app.dart | 86 +++--- .../extensions/embedded/_controller_web.dart | 18 +- .../src/extensions/embedded/_view_web.dart | 27 +- .../lib/src/extensions/extension_screen.dart | 6 +- .../extensions/extension_screen_controls.dart | 4 +- .../lib/src/extensions/extension_service.dart | 44 +-- .../src/extensions/extension_settings.dart | 51 ++-- .../lib/src/framework/home_screen.dart | 29 +- .../lib/src/framework/initializer.dart | 7 +- .../lib/src/framework/notifications_view.dart | 29 +- .../src/framework/observer/_memory_web.dart | 6 +- .../observer/disconnect_observer.dart | 57 ++-- .../framework/observer/memory_observer.dart | 58 ++-- .../lib/src/framework/release_notes.dart | 9 +- .../src/framework/scaffold/about_dialog.dart | 13 +- .../lib/src/framework/scaffold/scaffold.dart | 71 +++-- .../framework/scaffold/settings_dialog.dart | 16 +- .../src/framework/scaffold/status_line.dart | 91 +++--- .../screens/app_size/app_size_controller.dart | 28 +- .../src/screens/app_size/app_size_screen.dart | 145 +++++----- .../src/screens/app_size/app_size_table.dart | 19 +- .../app_size/code_size_attribution.dart | 27 +- .../screens/debugger/breakpoint_manager.dart | 16 +- .../lib/src/screens/debugger/breakpoints.dart | 7 +- .../lib/src/screens/debugger/call_stack.dart | 20 +- .../lib/src/screens/debugger/codeview.dart | 148 +++++----- .../screens/debugger/codeview_controller.dart | 9 +- .../lib/src/screens/debugger/controls.dart | 63 ++-- .../screens/debugger/debugger_controller.dart | 31 +- .../src/screens/debugger/debugger_screen.dart | 27 +- .../lib/src/screens/debugger/file_search.dart | 71 ++--- .../screens/debugger/program_explorer.dart | 126 ++++---- .../debugger/program_explorer_controller.dart | 64 ++--- .../debugger/program_explorer_model.dart | 45 ++- .../lib/src/screens/debugger/span_parser.dart | 42 ++- .../lib/src/screens/debugger/variables.dart | 5 +- .../deep_link_list_view.dart | 91 +++--- .../deep_links_controller.dart | 109 ++++--- .../deep_links_model.dart | 36 ++- .../deep_links_services.dart | 44 ++- .../project_root_selection/root_selector.dart | 18 +- .../select_project_view.dart | 4 +- .../validation_details_view.dart | 217 +++++++------- .../inspector/inspector_breadcrumbs.dart | 90 +++--- .../inspector/inspector_controller.dart | 54 ++-- .../inspector/inspector_data_models.dart | 103 ++++--- .../inspector/inspector_screen_body.dart | 53 ++-- .../inspector/inspector_tree_controller.dart | 126 ++++---- .../inspector/layout_explorer/box/box.dart | 12 +- .../inspector/layout_explorer/flex/flex.dart | 159 +++++------ .../inspector/layout_explorer/flex/utils.dart | 22 +- .../inspector/layout_explorer/ui/arrow.dart | 53 ++-- .../layout_explorer/ui/dimension.dart | 7 +- .../ui/overflow_indicator_painter.dart | 17 +- .../inspector/layout_explorer/ui/utils.dart | 68 +++-- .../ui/widget_constraints.dart | 12 +- .../inspector_shared/inspector_controls.dart | 20 +- .../inspector_settings_dialog.dart | 28 +- .../inspector_v2/inspector_controller.dart | 55 ++-- .../inspector_v2/inspector_data_models.dart | 132 +++++---- .../inspector_v2/inspector_screen_body.dart | 58 ++-- .../inspector_tree_controller.dart | 169 ++++++----- .../inspector_v2/layout_explorer/box/box.dart | 12 +- .../layout_explorer/flex/flex.dart | 159 +++++------ .../layout_explorer/flex/utils.dart | 22 +- .../layout_explorer/ui/arrow.dart | 53 ++-- .../layout_explorer/ui/dimension.dart | 7 +- .../ui/overflow_indicator_painter.dart | 17 +- .../layout_explorer/ui/utils.dart | 111 ++++---- .../ui/widget_constraints.dart | 12 +- .../widget_properties/properties_view.dart | 24 +- .../lib/src/screens/logging/_log_details.dart | 49 ++-- .../lib/src/screens/logging/_when_column.dart | 22 +- .../screens/logging/logging_controller.dart | 34 +-- .../src/screens/logging/logging_controls.dart | 24 +- .../src/screens/logging/logging_screen.dart | 7 +- .../lib/src/screens/logging/metadata.dart | 21 +- .../memory/framework/memory_controller.dart | 12 +- .../controller/chart_pane_controller.dart | 9 +- .../chart/controller/memory_tracker.dart | 9 +- .../memory/panes/chart/data/charts.dart | 5 +- .../chart/widgets/chart_control_pane.dart | 24 +- .../panes/chart/widgets/chart_pane.dart | 108 ++++--- .../chart/widgets/interval_dropdown.dart | 9 +- .../memory/panes/chart/widgets/legend.dart | 26 +- .../panes/control/widgets/control_pane.dart | 17 +- .../diff/controller/diff_pane_controller.dart | 40 ++- .../memory/panes/diff/data/classes_diff.dart | 22 +- .../panes/diff/data/heap_diff_data.dart | 22 +- .../panes/diff/data/heap_diff_store.dart | 19 +- .../screens/memory/panes/diff/diff_pane.dart | 5 +- .../diff/widgets/class_details/path.dart | 49 ++-- .../diff/widgets/class_details/paths.dart | 9 +- .../diff/widgets/classes_table_diff.dart | 35 +-- .../diff/widgets/classes_table_single.dart | 7 +- .../memory/panes/diff/widgets/instances.dart | 51 ++-- .../diff/widgets/snapshot_control_pane.dart | 79 ++--- .../panes/diff/widgets/snapshot_list.dart | 77 +++-- .../panes/diff/widgets/snapshot_view.dart | 13 +- .../memory/panes/profile/instances.dart | 16 +- .../screens/memory/panes/profile/model.dart | 16 +- .../memory/panes/profile/profile_view.dart | 18 +- .../memory/panes/tracing/tracing_data.dart | 20 +- .../memory/panes/tracing/tracing_tree.dart | 22 +- .../memory/shared/heap/class_filter.dart | 22 +- .../screens/memory/shared/heap/sampler.dart | 5 +- .../shared/primitives/memory_timeline.dart | 19 +- .../memory/shared/primitives/painting.dart | 7 +- .../memory/shared/widgets/class_filter.dart | 11 +- .../src/screens/network/har_data_entry.dart | 112 ++++---- .../src/screens/network/har_network_data.dart | 7 +- .../screens/network/network_controller.dart | 14 +- .../src/screens/network/network_model.dart | 25 +- .../network/network_request_inspector.dart | 34 +-- .../network_request_inspector_views.dart | 72 ++--- .../src/screens/network/network_screen.dart | 40 ++- .../src/screens/network/network_service.dart | 8 +- .../screens/network/offline_network_data.dart | 10 +- .../src/screens/network/utils/http_utils.dart | 19 +- .../enhance_tracing/enhance_tracing.dart | 28 +- .../enhance_tracing_controller.dart | 5 +- .../flutter_frames/flutter_frame_model.dart | 7 +- .../flutter_frames/flutter_frames_chart.dart | 97 +++---- .../flutter_frames_controller.dart | 7 +- .../frame_analysis/frame_analysis_model.dart | 12 +- .../panes/frame_analysis/frame_hints.dart | 95 +++---- .../frame_analysis/frame_time_visualizer.dart | 42 ++- .../panes/rebuild_stats/rebuild_stats.dart | 5 +- .../rebuild_stats/rebuild_stats_model.dart | 4 +- .../perfetto/_perfetto_controller_web.dart | 11 +- .../perfetto/tracing/model.dart | 7 +- .../timeline_event_processor.dart | 4 +- .../timeline_events_controller.dart | 25 +- .../timeline_events/timeline_events_view.dart | 56 ++-- .../performance/performance_controller.dart | 15 +- .../performance/performance_model.dart | 11 +- .../performance/performance_screen.dart | 6 +- .../performance/tabbed_performance_view.dart | 37 ++- .../screens/profiler/cpu_profile_model.dart | 134 ++++----- .../screens/profiler/cpu_profile_service.dart | 17 +- .../src/screens/profiler/cpu_profiler.dart | 19 +- .../profiler/cpu_profiler_controller.dart | 30 +- .../src/screens/profiler/panes/bottom_up.dart | 10 +- .../panes/controls/cpu_profiler_controls.dart | 28 +- .../controls/profiler_screen_controls.dart | 27 +- .../panes/method_table/method_table.dart | 20 +- .../method_table/method_table_controller.dart | 16 +- .../src/screens/profiler/profiler_screen.dart | 11 +- .../profiler/profiler_screen_controller.dart | 11 +- .../isolate_statistics_view.dart | 60 ++-- .../class_hierarchy_explorer.dart | 9 +- .../class_hierarchy_explorer_controller.dart | 9 +- .../object_inspector_view.dart | 15 +- .../object_inspector/object_viewport.dart | 7 +- .../object_inspector/vm_field_display.dart | 5 +- .../object_inspector/vm_ic_data_display.dart | 19 +- .../object_inspector/vm_instance_display.dart | 11 +- .../object_inspector/vm_library_display.dart | 5 +- .../object_inspector/vm_object_model.dart | 29 +- .../vm_simple_list_display.dart | 13 +- .../process_memory_tree_columns.dart | 4 +- .../process_memory/process_memory_view.dart | 5 +- .../vm_developer_common_widgets.dart | 101 ++++--- .../vm_service_private_extensions.dart | 104 +++---- .../vm_statistics/vm_statistics_view.dart | 9 +- .../vm_statistics_view_controller.dart | 5 +- .../src/service/json_to_service_cache.dart | 5 +- .../service/service_extension_widgets.dart | 89 +++--- .../lib/src/service/service_extensions.dart | 45 ++- .../lib/src/service/service_manager.dart | 63 ++-- .../lib/src/service/timeline_streams.dart | 7 +- .../lib/src/service/vm_flags.dart | 13 +- .../lib/src/service/vm_service_wrapper.dart | 11 +- .../src/shared/analytics/_analytics_web.dart | 269 ++++++++---------- .../shared/analytics/analytics_common.dart | 7 +- .../lib/src/shared/analytics/prompt.dart | 12 +- .../lib/src/shared/charts/chart.dart | 130 ++++----- .../src/shared/charts/chart_controller.dart | 12 +- .../lib/src/shared/charts/chart_trace.dart | 21 +- .../lib/src/shared/charts/flame_chart.dart | 93 +++--- .../lib/src/shared/charts/treemap.dart | 97 +++---- .../drag_and_drop/drag_and_drop.dart | 25 +- .../lib/src/shared/console/console.dart | 5 +- .../shared/console/eval/auto_complete.dart | 9 +- .../src/shared/console/eval/eval_service.dart | 10 +- .../shared/console/widgets/console_pane.dart | 10 +- .../shared/console/widgets/description.dart | 111 ++++---- .../console/widgets/display_provider.dart | 23 +- .../src/shared/console/widgets/evaluate.dart | 62 ++-- .../lib/src/shared/development_helpers.dart | 5 +- .../shared/diagnostics/dart_object_node.dart | 12 +- .../shared/diagnostics/inspector_service.dart | 81 +++--- .../src/shared/diagnostics/references.dart | 66 +++-- .../src/shared/diagnostics/tree_builder.dart | 8 +- .../lib/src/shared/editor/api_classes.dart | 45 ++- .../lib/src/shared/editor/editor_client.dart | 24 +- .../environment_parameters_external.dart | 15 +- .../shared/framework/app_error_handling.dart | 12 +- .../lib/src/shared/framework/screen.dart | 25 +- .../shared/framework/screen_controllers.dart | 21 +- .../lib/src/shared/http/_http_exception.dart | 7 +- .../src/shared/http/http_request_data.dart | 38 ++- .../src/shared/managers/banner_messages.dart | 189 ++++++------ .../src/shared/managers/notifications.dart | 21 +- .../lib/src/shared/managers/survey.dart | 44 +-- .../lib/src/shared/memory/class_name.dart | 5 +- .../lib/src/shared/memory/classes.dart | 24 +- .../lib/src/shared/memory/retainers.dart | 25 +- .../preferences/_inspector_preferences.dart | 28 +- .../custom_pointer_scroll_view.dart | 49 ++-- .../primitives/diagnostics_text_styles.dart | 5 +- .../lib/src/shared/primitives/encoding.dart | 9 +- .../primitives/extent_delegate_list.dart | 20 +- .../linked_scroll_controller.dart | 7 +- .../lib/src/shared/primitives/trees.dart | 5 +- .../lib/src/shared/primitives/utils.dart | 42 +-- .../lib/src/shared/server/server.dart | 5 +- .../src/shared/server/server_api_client.dart | 7 +- .../lib/src/shared/table/_flat_table.dart | 20 +- .../lib/src/shared/table/_table_column.dart | 28 +- .../lib/src/shared/table/_table_row.dart | 79 +++-- .../lib/src/shared/table/_tree_table.dart | 7 +- .../lib/src/shared/table/column_widths.dart | 23 +- .../lib/src/shared/table/table.dart | 35 +-- .../lib/src/shared/table/table_data.dart | 14 +- .../devtools_app/lib/src/shared/title.dart | 4 +- .../lib/src/shared/ui/common_widgets.dart | 121 ++++---- .../lib/src/shared/ui/dialogs.dart | 28 +- .../lib/src/shared/ui/drop_down_button.dart | 5 +- .../lib/src/shared/ui/editable_list.dart | 24 +- .../lib/src/shared/ui/file_import.dart | 80 +++--- .../lib/src/shared/ui/filter.dart | 116 ++++---- .../lib/src/shared/ui/history_viewport.dart | 139 +++++---- .../devtools_app/lib/src/shared/ui/hover.dart | 7 +- .../lib/src/shared/ui/search.dart | 200 +++++++------ .../lib/src/shared/ui/side_panel.dart | 11 +- .../lib/src/shared/ui/tree_view.dart | 26 +- .../devtools_app/lib/src/shared/ui/utils.dart | 7 +- .../lib/src/shared/ui/vm_flag_widgets.dart | 23 +- .../lib/src/shared/utils/utils.dart | 4 +- .../lib/src/shared/utils/vm_utils.dart | 18 +- .../property_editor_controller.dart | 64 ++--- .../property_editor_inputs.dart | 17 +- .../property_editor_messages.dart | 10 +- .../property_editor_panel.dart | 7 +- .../property_editor_types.dart | 11 +- .../property_editor/property_editor_view.dart | 34 ++- .../property_editor/utils/utils.dart | 11 +- .../standalone_ui/vs_code/debug_sessions.dart | 33 +-- .../src/standalone_ui/vs_code/devices.dart | 18 +- .../vs_code/devtools/devtools_view.dart | 44 ++- .../vs_code/devtools/shared.dart | 44 +-- .../sidebar_extensions_controller.dart | 32 +-- .../standalone_ui/vs_code/flutter_panel.dart | 7 +- .../extensions/extension_settings_test.dart | 72 +++-- .../observer/memory_observer_test.dart | 52 ++-- .../cpu_profiler_controller_test.dart | 36 +-- .../cpu_profiler/cpu_profiler_test.dart | 14 +- .../method_table/method_table_model_test.dart | 28 +- .../debugger_screen_call_stack_test.dart | 7 +- .../screens/debugger/eval_field_test.dart | 5 +- .../screens/debugger/file_search_test.dart | 8 +- .../screens/debugger/span_parser_test.dart | 14 +- .../deep_links_screen_test.dart | 5 +- .../screens/inspector/diagnostics_test.dart | 17 +- .../inspector/inspector_tree_test.dart | 27 +- .../inspector_data_models_test.dart | 12 +- .../inspector/utils/inspector_tree.dart | 17 +- .../inspector_v2/diagnostics_test.dart | 17 +- .../inspector_integration_test.dart | 5 +- .../inspector_v2/inspector_screen_test.dart | 7 +- .../inspector_v2/inspector_tree_test.dart | 22 +- .../inspector_data_models_test.dart | 12 +- .../inspector_v2/utils/inspector_tree.dart | 17 +- .../logging/logging_screen_data_test.dart | 11 +- .../test/screens/logging/metadata_test.dart | 17 +- .../controller/diff_pane_controller_test.dart | 8 +- .../diff/controller/heap_diff_test.dart | 26 +- .../diff/widgets/class_filter_test.dart | 7 +- .../framework/memory_controller_test.dart | 7 +- .../shared/heap/heap_analyzer_test.dart | 162 +++++------ .../screens/memory/shared/heap/heap_test.dart | 82 +++--- .../memory/tracing/tracing_view_test.dart | 21 +- .../network/network_controller_test.dart | 41 +-- .../network/network_profiler_test.dart | 4 +- .../timeline_event_processor_test.dart | 22 +- .../test/shared/analytics/analytics_test.dart | 5 +- .../test/shared/ansi_output_test.dart | 13 +- .../test/shared/charts/flame_chart_test.dart | 23 +- .../test/shared/charts/treemap_test.dart | 9 +- .../diagnostics/inspector_service_test.dart | 52 ++-- .../test/shared/eval_integration_test.dart | 24 +- .../test/shared/framework/screens_test.dart | 19 +- .../framework/visible_screens_test.dart | 11 +- .../test/shared/import_export_test.dart | 17 +- .../shared/memory/retaining_path_test.dart | 20 +- .../preferences_controller_test.dart | 20 +- .../test/shared/primitives/trees_test.dart | 58 ++-- .../test/shared/primitives/utils_test.dart | 91 +++--- .../test/shared/table/table_test.dart | 59 ++-- .../test/shared/ui/filter_test.dart | 5 +- .../test/shared/ui/hover_test.dart | 15 +- .../test/shared/ui/ui_utils_test.dart | 15 +- .../test/shared/ui/vm_flag_widgets_test.dart | 20 +- .../standalone_ui/vs_code/devtools_test.dart | 21 +- .../fixtures/networking_app/bin/main.dart | 9 +- .../test/test_infra/flutter_test_driver.dart | 12 +- .../memory/load_offline_data_profile_tab.png | Bin 31964 -> 28761 bytes .../memory/load_offline_data_trace_tab.png | Bin 55839 -> 55838 bytes .../goldens/settings_dialog_default.png | Bin 12488 -> 12476 bytes .../goldens/settings_dialog_modified.png | Bin 12726 -> 12716 bytes .../test_infra/scenes/memory/default.dart | 26 +- .../editor_service/simulated_editor.dart | 9 +- .../standalone_ui/mock_editor_widget.dart | 131 ++++----- .../property_editor_sidebar.dart | 21 +- .../test_data/cpu_profiler/cpu_profile.dart | 255 +++++++++-------- .../debugger/vm_service_object_tree.dart | 25 +- .../test_data/memory/heap/heap_data.dart | 5 +- .../performance/sample_performance_data.dart | 209 +++++++------- .../test/test_infra/utils/ansi.dart | 11 +- .../test_infra/utils/rendering_tester.dart | 8 +- .../test/test_infra/utils/test_utils.dart | 5 +- .../test_driver/integration_test.dart | 146 +++++----- .../lib/src/service/service_manager.dart | 6 +- .../lib/src/ui/text_field.dart | 26 +- 335 files changed, 5632 insertions(+), 6196 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index dd3190e9d7d..a65ca853937 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -74,7 +74,7 @@ jobs: wget -qO- https://dcm.dev/pgp-key.public | sudo gpg --dearmor -o /usr/share/keyrings/dcm.gpg echo 'deb [signed-by=/usr/share/keyrings/dcm.gpg arch=amd64] https://dcm.dev/debian stable main' | sudo tee /etc/apt/sources.list.d/dart_stable.list sudo apt-get update - sudo apt-get install dcm=1.24.2-1 # To avoid errors add `-1` (build number) to the version + sudo apt-get install dcm=1.28.0-1 # To avoid errors add `-1` (build number) to the version sudo chmod +x /usr/bin/dcm echo "$(dcm --version)" - name: Setup Dart SDK diff --git a/flutter-candidate.txt b/flutter-candidate.txt index 61f6f6d653e..a50a5ca0e41 100644 --- a/flutter-candidate.txt +++ b/flutter-candidate.txt @@ -1 +1 @@ -a7f820163c5d7d5321872c60f22fa047fb94bd7b +80d0409d137acdd55af4124b7622915c062c9d21 diff --git a/packages/devtools_app/benchmark/devtools_benchmarks_test.dart b/packages/devtools_app/benchmark/devtools_benchmarks_test.dart index aa7cc2640b8..7cabd140ae3 100644 --- a/packages/devtools_app/benchmark/devtools_benchmarks_test.dart +++ b/packages/devtools_app/benchmark/devtools_benchmarks_test.dart @@ -53,10 +53,9 @@ Future _runBenchmarks({bool useWasm = false}) async { final taskResult = await serveWebBenchmark( benchmarkAppDirectory: projectRootDirectory(), entryPoint: generateBenchmarkEntryPoint(useWasm: useWasm), - compilationOptions: - useWasm - ? const CompilationOptions.wasm() - : const CompilationOptions.js(), + compilationOptions: useWasm + ? const CompilationOptions.wasm() + : const CompilationOptions.js(), treeShakeIcons: false, benchmarkPath: benchmarkPath(useWasm: useWasm), ); diff --git a/packages/devtools_app/benchmark/scripts/run_benchmarks.dart b/packages/devtools_app/benchmark/scripts/run_benchmarks.dart index bc0dd115e78..797821a024d 100644 --- a/packages/devtools_app/benchmark/scripts/run_benchmarks.dart +++ b/packages/devtools_app/benchmark/scripts/run_benchmarks.dart @@ -56,10 +56,9 @@ Future runBenchmarks({ await serveWebBenchmark( benchmarkAppDirectory: projectRootDirectory(), entryPoint: generateBenchmarkEntryPoint(useWasm: useWasm), - compilationOptions: - useWasm - ? const CompilationOptions.wasm() - : const CompilationOptions.js(), + compilationOptions: useWasm + ? const CompilationOptions.wasm() + : const CompilationOptions.js(), treeShakeIcons: false, benchmarkPath: benchmarkPath(useWasm: useWasm), headless: !useBrowser, diff --git a/packages/devtools_app/benchmark/test_infra/client/client_shared.dart b/packages/devtools_app/benchmark/test_infra/client/client_shared.dart index 3e33cbdf969..be919a56e9a 100644 --- a/packages/devtools_app/benchmark/test_infra/client/client_shared.dart +++ b/packages/devtools_app/benchmark/test_infra/client/client_shared.dart @@ -10,16 +10,11 @@ import '../devtools_recorder.dart'; typedef RecorderFactory = Recorder Function(); final benchmarks = { - DevToolsBenchmark.navigateThroughOfflineScreens.id: - () => DevToolsRecorder( - benchmark: DevToolsBenchmark.navigateThroughOfflineScreens, - ), - DevToolsBenchmark.offlineCpuProfilerScreen.id: - () => DevToolsRecorder( - benchmark: DevToolsBenchmark.offlineCpuProfilerScreen, - ), - DevToolsBenchmark.offlinePerformanceScreen.id: - () => DevToolsRecorder( - benchmark: DevToolsBenchmark.offlinePerformanceScreen, - ), + DevToolsBenchmark.navigateThroughOfflineScreens.id: () => DevToolsRecorder( + benchmark: DevToolsBenchmark.navigateThroughOfflineScreens, + ), + DevToolsBenchmark.offlineCpuProfilerScreen.id: () => + DevToolsRecorder(benchmark: DevToolsBenchmark.offlineCpuProfilerScreen), + DevToolsBenchmark.offlinePerformanceScreen.id: () => + DevToolsRecorder(benchmark: DevToolsBenchmark.offlinePerformanceScreen), }; diff --git a/packages/devtools_app/benchmark/test_infra/common.dart b/packages/devtools_app/benchmark/test_infra/common.dart index d6b9dcb2fb1..2915822c626 100644 --- a/packages/devtools_app/benchmark/test_infra/common.dart +++ b/packages/devtools_app/benchmark/test_infra/common.dart @@ -12,11 +12,10 @@ const _benchmarkInitialPage = ''; const _wasmQueryParameters = {'wasm': 'true'}; -String benchmarkPath({required bool useWasm}) => - Uri( - path: _benchmarkInitialPage, - queryParameters: useWasm ? _wasmQueryParameters : null, - ).toString(); +String benchmarkPath({required bool useWasm}) => Uri( + path: _benchmarkInitialPage, + queryParameters: useWasm ? _wasmQueryParameters : null, +).toString(); String generateBenchmarkEntryPoint({required bool useWasm}) { return 'benchmark/test_infra/client/client_${useWasm ? 'wasm' : 'js'}.dart'; diff --git a/packages/devtools_app/integration_test/run_tests.dart b/packages/devtools_app/integration_test/run_tests.dart index d2a4d978c95..e5dee8cb64b 100644 --- a/packages/devtools_app/integration_test/run_tests.dart +++ b/packages/devtools_app/integration_test/run_tests.dart @@ -55,8 +55,8 @@ void main(List args) async { testRunnerArgs: testRunnerArgs, runTest: _runTest, newArgsGenerator: (args) => DevToolsAppTestRunnerArgs(args), - testIsSupported: - (testFile) => testRunnerArgs.testAppDevice.supportsTest(testFile.path), + testIsSupported: (testFile) => + testRunnerArgs.testAppDevice.supportsTest(testFile.path), debugLogging: debugTestScript, ); } diff --git a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart index b1350535f41..c80a3c0861b 100644 --- a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart @@ -268,11 +268,10 @@ Future _verifyExtensionsSettingsMenu( await _openExtensionSettingsMenu(tester); expect(find.byType(ExtensionSetting), findsNWidgets(enabledStates.length)); - final toggleButtonGroups = - tester - .widgetList(find.byType(DevToolsToggleButtonGroup)) - .cast() - .toList(); + final toggleButtonGroups = tester + .widgetList(find.byType(DevToolsToggleButtonGroup)) + .cast() + .toList(); for (int i = 0; i < toggleButtonGroups.length; i++) { logStatus('verify extension settings toggle button states (index $i)'); final group = toggleButtonGroups[i]; @@ -313,11 +312,10 @@ Future _changeExtensionSetting( 'changing the extension setting at index $extensionIndex to value $settingValue', ); await _openExtensionSettingsMenu(tester); - final extensionSetting = - tester - .widgetList(find.byType(DevToolsToggleButtonGroup)) - .cast() - .toList()[extensionIndex]; + final extensionSetting = tester + .widgetList(find.byType(DevToolsToggleButtonGroup)) + .cast() + .toList()[extensionIndex]; await tester.tap( find.descendant( of: find.byWidget(extensionSetting), diff --git a/packages/devtools_app/integration_test/test_infra/run/_test_app_driver.dart b/packages/devtools_app/integration_test/test_infra/run/_test_app_driver.dart index 917b0ede36d..21305bf5624 100644 --- a/packages/devtools_app/integration_test/test_infra/run/_test_app_driver.dart +++ b/packages/devtools_app/integration_test/test_infra/run/_test_app_driver.dart @@ -133,10 +133,9 @@ class TestFlutterApp extends IntegrationTestApp { return _timeoutWithMessages>( () => response.future, timeout: timeout, - message: - event != null - ? 'Did not receive expected $event event.' - : 'Did not receive response to request "$id".', + message: event != null + ? 'Did not receive expected $event event.' + : 'Did not receive response to request "$id".', ).whenComplete(() => sub.cancel()); } @@ -350,8 +349,8 @@ abstract class IntegrationTestApp with IOMixin { _debugPrint('Waiting for process to end'); return runProcess!.exitCode.timeout( IOMixin.killTimeout, - onTimeout: - () => killGracefully(runProcess!, debugLogging: debugTestScript), + onTimeout: () => + killGracefully(runProcess!, debugLogging: debugTestScript), ); } @@ -387,8 +386,9 @@ abstract class IntegrationTestApp with IOMixin { String _debugPrint(String msg) { const maxLength = 500; - final truncatedMsg = - msg.length > maxLength ? '${msg.substring(0, maxLength)}...' : msg; + final truncatedMsg = msg.length > maxLength + ? '${msg.substring(0, maxLength)}...' + : msg; _allMessages.add(truncatedMsg); debugLog('_TestApp - $truncatedMsg'); return msg; @@ -404,12 +404,11 @@ Uri convertToWebSocketUrl({required Uri serviceProtocolUrl}) { serviceProtocolUrl.isScheme('https'); final scheme = isSecure ? 'wss' : 'ws'; - final path = - serviceProtocolUrl.path.endsWith('/ws') - ? serviceProtocolUrl.path - : (serviceProtocolUrl.path.endsWith('/') - ? '${serviceProtocolUrl.path}ws' - : '${serviceProtocolUrl.path}/ws'); + final path = serviceProtocolUrl.path.endsWith('/ws') + ? serviceProtocolUrl.path + : (serviceProtocolUrl.path.endsWith('/') + ? '${serviceProtocolUrl.path}ws' + : '${serviceProtocolUrl.path}/ws'); return serviceProtocolUrl.replace(scheme: scheme, path: path); } diff --git a/packages/devtools_app/integration_test/test_infra/run/run_test.dart b/packages/devtools_app/integration_test/test_infra/run/run_test.dart index bdb72236dc1..4ac52746efe 100644 --- a/packages/devtools_app/integration_test/test_infra/run/run_test.dart +++ b/packages/devtools_app/integration_test/test_infra/run/run_test.dart @@ -89,11 +89,10 @@ Future runFlutterIntegrationTest( class DevToolsAppTestRunnerArgs extends IntegrationTestRunnerArgs { DevToolsAppTestRunnerArgs(super.args, {super.verifyValidTarget = true}) : super(addExtraArgs: _addExtraArgs) { - testAppDevice = - TestAppDevice.fromArgName( - argResults.option(_testAppDeviceArg) ?? - TestAppDevice.flutterTester.argName, - )!; + testAppDevice = TestAppDevice.fromArgName( + argResults.option(_testAppDeviceArg) ?? + TestAppDevice.flutterTester.argName, + )!; } /// The type of device for the test app to run on. diff --git a/packages/devtools_app/lib/src/app.dart b/packages/devtools_app/lib/src/app.dart index e78679344ac..612aa313508 100644 --- a/packages/devtools_app/lib/src/app.dart +++ b/packages/devtools_app/lib/src/app.dart @@ -87,16 +87,17 @@ class DevToolsAppState extends State with AutoDisposeMixin { if (FeatureFlags.devToolsExtensions) { // TODO(https://github.com/flutter/devtools/issues/6273): stop special // casing the package:provider extension. - final containsProviderExtension = - extensionService.currentExtensions.value.visibleExtensions - .where((e) => e.name == 'provider') - .isNotEmpty; - final devToolsScreens = - containsProviderExtension - ? _originalScreens - .where((s) => s.screenId != ScreenMetaData.provider.id) - .toList() - : _originalScreens; + final containsProviderExtension = extensionService + .currentExtensions + .value + .visibleExtensions + .where((e) => e.name == 'provider') + .isNotEmpty; + final devToolsScreens = containsProviderExtension + ? _originalScreens + .where((s) => s.screenId != ScreenMetaData.provider.id) + .toList() + : _originalScreens; return [...devToolsScreens, ..._extensionScreens]; } return _originalScreens; @@ -287,16 +288,15 @@ class DevToolsAppState extends State with AutoDisposeMixin { extensionService.currentExtensions, ], builder: (_, _, child) { - final screensInScaffold = - _visibleScreens() - .where( - (s) => maybeIncludeOnlyEmbeddedScreen( - s, - page: page, - embedMode: embedMode, - ), - ) - .toList(); + final screensInScaffold = _visibleScreens() + .where( + (s) => maybeIncludeOnlyEmbeddedScreen( + s, + page: page, + embedMode: embedMode, + ), + ) + .toList(); removeHiddenScreens(screensInScaffold, queryParams); @@ -354,26 +354,25 @@ class DevToolsAppState extends State with AutoDisposeMixin { embedMode: embedMode, page: page, screens: screensInScaffold, - actions: - isEmbedded() - ? [] - : [ - if (paramsContainVmServiceUri) ...[ - // Hide the hot reload button for Dart web apps, where the - // hot reload service extension is not avilable and where the - // [service.reloadServices] RPC is not implemented. - // TODO(https://github.com/flutter/devtools/issues/6441): find - // a way to show this for Dart web apps when supported. - if (!connectedToDartWebApp) - HotReloadButton( - callOnVmServiceDirectly: !connectedToFlutterApp, - ), - // This button will hide itself based on whether the - // hot restart service is available for the connected app. - const HotRestartButton(), - ], - ...DevToolsScaffold.defaultActions(), + actions: isEmbedded() + ? [] + : [ + if (paramsContainVmServiceUri) ...[ + // Hide the hot reload button for Dart web apps, where the + // hot reload service extension is not avilable and where the + // [service.reloadServices] RPC is not implemented. + // TODO(https://github.com/flutter/devtools/issues/6441): find + // a way to show this for Dart web apps when supported. + if (!connectedToDartWebApp) + HotReloadButton( + callOnVmServiceDirectly: !connectedToFlutterApp, + ), + // This button will hide itself based on whether the + // hot restart service is available for the connected app. + const HotRestartButton(), ], + ...DevToolsScaffold.defaultActions(), + ], ); } return scaffold; @@ -657,8 +656,8 @@ class ScreenUnavailable extends StatelessWidget { if (embedMode == EmbedMode.none) ...[ const SizedBox(height: defaultSpacing), ElevatedButton( - onPressed: - () => routerDelegate.navigateHome(clearScreenParam: true), + onPressed: () => + routerDelegate.navigateHome(clearScreenParam: true), child: const Text('Go to Home screen'), ), ], @@ -702,9 +701,8 @@ List defaultScreens({ ), DevToolsScreen( DebuggerScreen(), - createController: - (routerDelegate) => - DebuggerController(routerDelegate: routerDelegate), + createController: (routerDelegate) => + DebuggerController(routerDelegate: routerDelegate), ), DevToolsScreen( NetworkScreen(), diff --git a/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart b/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart index 9d349d94cc2..388fe7ab9d8 100644 --- a/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart +++ b/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart @@ -61,10 +61,9 @@ class EmbeddedExtensionControllerImpl extends EmbeddedExtensionController ); final queryParams = { ...DevToolsQueryParams.load().params, - ExtensionEventParameters.theme: - isDarkThemeEnabled() - ? ExtensionEventParameters.themeValueDark - : ExtensionEventParameters.themeValueLight, + ExtensionEventParameters.theme: isDarkThemeEnabled() + ? ExtensionEventParameters.themeValueDark + : ExtensionEventParameters.themeValueLight, if (dtdManager.uri != null) 'dtdUri': dtdManager.uri.toString(), }; return Uri.parse(baseUri).replace(queryParameters: queryParams).toString(); @@ -89,12 +88,11 @@ class EmbeddedExtensionControllerImpl extends EmbeddedExtensionController ); _initialized = true; - _extensionIFrame = - HTMLIFrameElement() - // This url is safe because we built it ourselves and it does not include - // any user input. - ..src = extensionUrl - ..allow = 'usb'; + _extensionIFrame = HTMLIFrameElement() + // This url is safe because we built it ourselves and it does not include + // any user input. + ..src = extensionUrl + ..allow = 'usb'; _extensionIFrame.style ..border = 'none' ..height = '100%' diff --git a/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart b/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart index 47cce6525b5..7174fea5a82 100644 --- a/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart +++ b/packages/devtools_app/lib/src/extensions/embedded/_view_web.dart @@ -148,10 +148,9 @@ class _ExtensionIFrameController extends DisposableController addAutoDisposeListener(preferences.darkModeEnabled, () { updateTheme( - theme: - isDarkThemeEnabled() - ? ExtensionEventParameters.themeValueDark - : ExtensionEventParameters.themeValueLight, + theme: isDarkThemeEnabled() + ? ExtensionEventParameters.themeValueDark + : ExtensionEventParameters.themeValueLight, ); }); } @@ -184,10 +183,9 @@ class _ExtensionIFrameController extends DisposableController if (extensionEvent != null) { onEventReceived( extensionEvent, - onUnknownEvent: - () => notificationService.push( - 'Unknown event received from extension: $extensionEvent}', - ), + onUnknownEvent: () => notificationService.push( + 'Unknown event received from extension: $extensionEvent}', + ), ); } } @@ -316,13 +314,12 @@ class _ExtensionIFrameController extends DisposableController screenId: '${showBannerMessageEvent.extensionName}_ext', dismissOnConnectionChanges: showBannerMessageEvent.dismissOnConnectionChanges, - buildTextSpans: - (_) => [ - TextSpan( - text: showBannerMessageEvent.message, - style: TextStyle(fontSize: defaultFontSize), - ), - ], + buildTextSpans: (_) => [ + TextSpan( + text: showBannerMessageEvent.message, + style: TextStyle(fontSize: defaultFontSize), + ), + ], ); bannerMessages.addMessage( bannerMessage, diff --git a/packages/devtools_app/lib/src/extensions/extension_screen.dart b/packages/devtools_app/lib/src/extensions/extension_screen.dart index b6bd80c1c0c..e54cb646f41 100644 --- a/packages/devtools_app/lib/src/extensions/extension_screen.dart +++ b/packages/devtools_app/lib/src/extensions/extension_screen.dart @@ -106,10 +106,8 @@ class ExtensionView extends StatelessWidget { children: [ EmbeddedExtensionHeader( ext: ext, - onForceReload: - () => controller.postMessage( - DevToolsExtensionEventType.forceReload, - ), + onForceReload: () => + controller.postMessage(DevToolsExtensionEventType.forceReload), ), const SizedBox(height: intermediateSpacing), Expanded( diff --git a/packages/devtools_app/lib/src/extensions/extension_screen_controls.dart b/packages/devtools_app/lib/src/extensions/extension_screen_controls.dart index b77d3d36dae..39e6c948e8b 100644 --- a/packages/devtools_app/lib/src/extensions/extension_screen_controls.dart +++ b/packages/devtools_app/lib/src/extensions/extension_screen_controls.dart @@ -64,8 +64,8 @@ class EmbeddedExtensionHeader extends StatelessWidget { url: ext.issueTrackerLink, gaScreenName: gac.DevToolsExtensionEvents.extensionScreenId.name, - gaSelectedItemDescription: gac - .DevToolsExtensionEvents.extensionFeedback(ext), + gaSelectedItemDescription: + gac.DevToolsExtensionEvents.extensionFeedback(ext), ), context: context, ), diff --git a/packages/devtools_app/lib/src/extensions/extension_service.dart b/packages/devtools_app/lib/src/extensions/extension_service.dart index 4a46e15e5d5..2c7513b48ca 100644 --- a/packages/devtools_app/lib/src/extensions/extension_service.dart +++ b/packages/devtools_app/lib/src/extensions/extension_service.dart @@ -18,20 +18,19 @@ final _log = Logger('ExtensionService'); /// Data pattern containing a [List] of available extensions and a [List] of /// visible extensions. -typedef DevToolsExtensionsGroup = - ({ - // All the DevTools extensions, runtime and static, that are available for - // the connected application, regardless of whether they have been enabled - // or disabled by the user. - // - // This set of extensions will include one version of a DevTools extension - // per package. - List availableExtensions, - - // DevTools extensions that are visible in their own DevTools screen (i.e. - // extensions that have not been manually disabled by the user). - List visibleExtensions, - }); +typedef DevToolsExtensionsGroup = ({ + // All the DevTools extensions, runtime and static, that are available for + // the connected application, regardless of whether they have been enabled + // or disabled by the user. + // + // This set of extensions will include one version of a DevTools extension + // per package. + List availableExtensions, + + // DevTools extensions that are visible in their own DevTools screen (i.e. + // extensions that have not been manually disabled by the user). + List visibleExtensions, +}); class ExtensionService extends DisposableController with AutoDisposeControllerMixin { @@ -189,10 +188,12 @@ class ExtensionService extends DisposableController _refreshInProgress.value = true; final allExtensions = await server.refreshAvailableExtensions(_appRoot); - runtimeExtensions = - allExtensions.where((e) => !e.detectedFromStaticContext).toList(); - staticExtensions = - allExtensions.where((e) => e.detectedFromStaticContext).toList(); + runtimeExtensions = allExtensions + .where((e) => !e.detectedFromStaticContext) + .toList(); + staticExtensions = allExtensions + .where((e) => e.detectedFromStaticContext) + .toList(); // TODO(kenz): consider handling duplicates in a way that gives the user a // choice of which version they want to use. @@ -261,10 +262,9 @@ class ExtensionService extends DisposableController ); stateNotifier.value = stateFromOptionsFile; - final shouldIncludeInVisible = - onlyIncludeEnabled - ? stateFromOptionsFile == ExtensionEnabledState.enabled - : stateFromOptionsFile != ExtensionEnabledState.disabled; + final shouldIncludeInVisible = onlyIncludeEnabled + ? stateFromOptionsFile == ExtensionEnabledState.enabled + : stateFromOptionsFile != ExtensionEnabledState.disabled; if (shouldIncludeInVisible) { visible.add(extension); } diff --git a/packages/devtools_app/lib/src/extensions/extension_settings.dart b/packages/devtools_app/lib/src/extensions/extension_settings.dart index f74df9d0278..fb26a80eaa2 100644 --- a/packages/devtools_app/lib/src/extensions/extension_settings.dart +++ b/packages/devtools_app/lib/src/extensions/extension_settings.dart @@ -26,14 +26,12 @@ class ExtensionSettingsAction extends ScaffoldAction { unawaited( showDialog( context: context, - builder: - (context) => ExtensionSettingsDialog( - extensions: - extensionService - .currentExtensions - .value - .availableExtensions, - ), + builder: (context) => ExtensionSettingsDialog( + extensions: extensionService + .currentExtensions + .value + .availableExtensions, + ), ), ); }, @@ -50,8 +48,9 @@ class ExtensionSettingsDialog extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); // This dialog needs a fixed height because it contains a scrollable list. - final dialogHeight = - anyTestMode ? scaleByFontFactor(1000.0) : scaleByFontFactor(300.0); + final dialogHeight = anyTestMode + ? scaleByFontFactor(1000.0) + : scaleByFontFactor(300.0); return DevToolsDialog( title: const DialogTitleText('DevTools Extensions'), content: SizedBox( @@ -76,15 +75,14 @@ class ExtensionSettingsDialog extends StatelessWidget { ), const PaddedDivider(), Expanded( - child: - extensions.isEmpty - ? Center( - child: Text( - 'No extensions available.', - style: theme.subtleTextStyle, - ), - ) - : _ExtensionsList(extensions: extensions), + child: extensions.isEmpty + ? Center( + child: Text( + 'No extensions available.', + style: theme.subtleTextStyle, + ), + ) + : _ExtensionsList(extensions: extensions), ), ], ), @@ -126,9 +124,8 @@ class __ExtensionsListState extends State<_ExtensionsList> { child: ListView.builder( controller: scrollController, itemCount: widget.extensions.length, - itemBuilder: - (context, index) => - ExtensionSetting(extension: widget.extensions[index]), + itemBuilder: (context, index) => + ExtensionSetting(extension: widget.extensions[index]), ), ); } @@ -145,9 +142,8 @@ class ExtensionSetting extends StatelessWidget { final buttonStates = [ ( title: 'Enabled', - isSelected: - (ExtensionEnabledState state) => - state == ExtensionEnabledState.enabled, + isSelected: (ExtensionEnabledState state) => + state == ExtensionEnabledState.enabled, onPressed: () { ga.select( gac.DevToolsExtensionEvents.extensionSettingsId.name, @@ -160,9 +156,8 @@ class ExtensionSetting extends StatelessWidget { ), ( title: 'Disabled', - isSelected: - (ExtensionEnabledState state) => - state == ExtensionEnabledState.disabled, + isSelected: (ExtensionEnabledState state) => + state == ExtensionEnabledState.disabled, onPressed: () { ga.select( gac.DevToolsExtensionEvents.extensionSettingsId.name, diff --git a/packages/devtools_app/lib/src/framework/home_screen.dart b/packages/devtools_app/lib/src/framework/home_screen.dart index 6e9b7ed2877..b13512837c6 100644 --- a/packages/devtools_app/lib/src/framework/home_screen.dart +++ b/packages/devtools_app/lib/src/framework/home_screen.dart @@ -104,8 +104,8 @@ class ConnectionSection extends StatelessWidget { minScreenWidthForTextBeforeScaling: _primaryMinScreenWidthForTextBeforeScaling, routerDelegate: DevToolsRouterDelegate.of(context), - onPressed: - () => Navigator.of(context, rootNavigator: true).pop('dialog'), + onPressed: () => + Navigator.of(context, rootNavigator: true).pop('dialog'), ), ], child: const ConnectedAppSummary(narrowView: false), @@ -205,8 +205,9 @@ class _ConnectInputState extends State with BlockingActionMixin { width: scaleByFontFactor(350.0), child: DevToolsClearableTextField( labelText: 'URL', - onSubmitted: - actionInProgress ? null : (str) => unawaited(_connect()), + onSubmitted: actionInProgress + ? null + : (str) => unawaited(_connect()), autofocus: true, controller: connectDialogController, ), @@ -310,20 +311,18 @@ class _SampleDataDropDownButtonState extends State { RoundedDropDownButton( value: value, items: [for (final data in widget.sampleData) _buildMenuItem(data)], - onChanged: - (file) => setState(() { - value = file; - }), + onChanged: (file) => setState(() { + value = file; + }), ), const SizedBox(width: defaultSpacing), ElevatedButton( - onPressed: - value == null - ? null - : () => Provider.of( - context, - listen: false, - ).importData(value!), + onPressed: value == null + ? null + : () => Provider.of( + context, + listen: false, + ).importData(value!), child: const MaterialIconLabel( label: 'Load sample data', iconData: Icons.file_upload, diff --git a/packages/devtools_app/lib/src/framework/initializer.dart b/packages/devtools_app/lib/src/framework/initializer.dart index f736692a701..8bc2760a6a4 100644 --- a/packages/devtools_app/lib/src/framework/initializer.dart +++ b/packages/devtools_app/lib/src/framework/initializer.dart @@ -79,10 +79,9 @@ class _InitializerState extends State children: [ const Spacer(), CenteredMessage( - message: - _showConnectToNewAppButton - ? 'Cannot connect to VM service.' - : 'Waiting for VM service connection...', + message: _showConnectToNewAppButton + ? 'Cannot connect to VM service.' + : 'Waiting for VM service connection...', ), if (_showConnectToNewAppButton) ...[ const SizedBox(height: defaultSpacing), diff --git a/packages/devtools_app/lib/src/framework/notifications_view.dart b/packages/devtools_app/lib/src/framework/notifications_view.dart index 3e5f66af961..3c7757b51ac 100644 --- a/packages/devtools_app/lib/src/framework/notifications_view.dart +++ b/packages/devtools_app/lib/src/framework/notifications_view.dart @@ -243,17 +243,17 @@ class _NotificationState extends State<_Notification> children: [ widget.message.isDismissible ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Flexible(child: _NotificationMessage(widget: widget)), - _DismissAction( - onPressed: () { - widget.remove(widget); - }, - ), - ], - ) + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Flexible(child: _NotificationMessage(widget: widget)), + _DismissAction( + onPressed: () { + widget.remove(widget); + }, + ), + ], + ) : _NotificationMessage(widget: widget), const SizedBox(height: defaultSpacing), _NotificationActions(actions: widget.message.actions), @@ -299,10 +299,9 @@ class _NotificationMessage extends StatelessWidget { ), child: Text( widget.message.text, - style: - widget.message.isError - ? textStyle.copyWith(color: theme.colorScheme.error) - : textStyle, + style: widget.message.isError + ? textStyle.copyWith(color: theme.colorScheme.error) + : textStyle, overflow: TextOverflow.visible, maxLines: 10, ), diff --git a/packages/devtools_app/lib/src/framework/observer/_memory_web.dart b/packages/devtools_app/lib/src/framework/observer/_memory_web.dart index 7f393e4e877..251cfb64071 100644 --- a/packages/devtools_app/lib/src/framework/observer/_memory_web.dart +++ b/packages/devtools_app/lib/src/framework/observer/_memory_web.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. +// ignore_for_file: prefer-correct-type-name + import 'dart:js_interop'; import 'dart:js_interop_unsafe'; @@ -27,8 +29,8 @@ extension on Performance { Future<_UserAgentSpecificMemory>? measureUserAgentSpecificMemory() => has('measureUserAgentSpecificMemory') - ? _measureUserAgentSpecificMemory().toDart - : null; + ? _measureUserAgentSpecificMemory().toDart + : null; } @JS() diff --git a/packages/devtools_app/lib/src/framework/observer/disconnect_observer.dart b/packages/devtools_app/lib/src/framework/observer/disconnect_observer.dart index f2b1224019f..bf415e4b3c8 100644 --- a/packages/devtools_app/lib/src/framework/observer/disconnect_observer.dart +++ b/packages/devtools_app/lib/src/framework/observer/disconnect_observer.dart @@ -117,37 +117,36 @@ class DisconnectObserverState extends State OverlayEntry _createDisconnectedOverlay() { final theme = Theme.of(context); currentDisconnectedOverlay = OverlayEntry( - builder: - (context) => Material( - child: Container( - color: theme.colorScheme.surface, - child: Center( - child: Column( - children: [ - const Spacer(), - Text('Disconnected', style: theme.textTheme.headlineMedium), - const SizedBox(height: defaultSpacing), - if (!isEmbedded()) - ConnectToNewAppButton( - routerDelegate: widget.routerDelegate, - onPressed: hideDisconnectedOverlay, - gaScreen: gac.devToolsMain, - ) - else - const Text('Run a new debug session to reconnect.'), - const Spacer(), - if (offlineDataController.offlineDataJson.isNotEmpty) ...[ - ElevatedButton( - onPressed: _reviewHistory, - child: const Text('Review recent data (offline)'), - ), - const Spacer(), - ], - ], - ), - ), + builder: (context) => Material( + child: Container( + color: theme.colorScheme.surface, + child: Center( + child: Column( + children: [ + const Spacer(), + Text('Disconnected', style: theme.textTheme.headlineMedium), + const SizedBox(height: defaultSpacing), + if (!isEmbedded()) + ConnectToNewAppButton( + routerDelegate: widget.routerDelegate, + onPressed: hideDisconnectedOverlay, + gaScreen: gac.devToolsMain, + ) + else + const Text('Run a new debug session to reconnect.'), + const Spacer(), + if (offlineDataController.offlineDataJson.isNotEmpty) ...[ + ElevatedButton( + onPressed: _reviewHistory, + child: const Text('Review recent data (offline)'), + ), + const Spacer(), + ], + ], ), ), + ), + ), ); return currentDisconnectedOverlay!; } diff --git a/packages/devtools_app/lib/src/framework/observer/memory_observer.dart b/packages/devtools_app/lib/src/framework/observer/memory_observer.dart index 148f86686cc..0826cdab59f 100644 --- a/packages/devtools_app/lib/src/framework/observer/memory_observer.dart +++ b/packages/devtools_app/lib/src/framework/observer/memory_observer.dart @@ -23,8 +23,12 @@ import '_memory_desktop.dart' if (dart.library.js_interop) '_memory_web.dart'; /// `toBytes` - total memory usage after the reduction request is completed. /// `success` - whether the reduction in memory brought DevTools memory usage /// below the threshold [MemoryObserver._memoryPressureLimitGb]. -typedef ReduceMemoryResult = - ({bool success, int? fromBytes, int? toBytes, String? error}); +typedef ReduceMemoryResult = ({ + bool success, + int? fromBytes, + int? toBytes, + String? error, +}); /// Observes the memory usage of the DevTools app (web only) and shows a memory /// pressure warning to users when DevTools is nearing the memory limit. @@ -86,10 +90,9 @@ class MemoryObserver extends DisposableController { static Future _memoryExceedsThreshold({ @visibleForTesting Future Function()? debugMeasureUsageInBytes, }) async { - final memoryUsageInBytes = - debugMeasureUsageInBytes != null - ? await debugMeasureUsageInBytes() - : await measureMemoryUsageInBytes(); + final memoryUsageInBytes = debugMeasureUsageInBytes != null + ? await debugMeasureUsageInBytes() + : await measureMemoryUsageInBytes(); _lastMemoryUsageInBytes = memoryUsageInBytes; if (memoryUsageInBytes == null) return false; @@ -132,10 +135,9 @@ class MemoryObserver extends DisposableController { }); } - final success = - !(await _memoryExceedsThreshold( - debugMeasureUsageInBytes: debugMeasureUsageInBytes, - )); + final success = !(await _memoryExceedsThreshold( + debugMeasureUsageInBytes: debugMeasureUsageInBytes, + )); final toBytes = _lastMemoryUsageInBytes; return ( success: success, @@ -186,12 +188,11 @@ class _MemoryPressureBannerMessage extends banner_messages.BannerWarning { ), ]; }, - buildActions: - (_) => [ - // Wrapping with an `Expanded` is okay because this list is set as - // the `children` parameter of a `Row` widget in `BannerMessage`. - const Expanded(child: _ReduceMemoryButton()), - ], + buildActions: (_) => [ + // Wrapping with an `Expanded` is okay because this list is set as + // the `children` parameter of a `Row` widget in `BannerMessage`. + const Expanded(child: _ReduceMemoryButton()), + ], ); static const _messageKey = Key('MemoryPressureBannerMessage'); @@ -229,19 +230,18 @@ class _ReduceMemoryButtonState extends State<_ReduceMemoryButton> { Flexible( child: Padding( padding: const EdgeInsets.symmetric(horizontal: denseSpacing), - child: - inProgress - ? SizedBox( - height: actionsIconSize, - width: actionsIconSize, - child: const CircularProgressIndicator(), - ) - : ValueListenableBuilder( - valueListenable: result, - builder: (context, result, _) { - return _SuccessOrFailureMessage(result: result); - }, - ), + child: inProgress + ? SizedBox( + height: actionsIconSize, + width: actionsIconSize, + child: const CircularProgressIndicator(), + ) + : ValueListenableBuilder( + valueListenable: result, + builder: (context, result, _) { + return _SuccessOrFailureMessage(result: result); + }, + ), ), ), ], diff --git a/packages/devtools_app/lib/src/framework/release_notes.dart b/packages/devtools_app/lib/src/framework/release_notes.dart index be9243f6caf..b6a05b1c04b 100644 --- a/packages/devtools_app/lib/src/framework/release_notes.dart +++ b/packages/devtools_app/lib/src/framework/release_notes.dart @@ -70,15 +70,16 @@ class ReleaseNotesController extends SidePanelController { // user's perspective, these tools are part of the IDE. if (isEmbedded()) { final currentUrl = getWebUrl(); - final currentPage = - currentUrl != null ? extractCurrentPageFromUrl(currentUrl) : null; + final currentPage = currentUrl != null + ? extractCurrentPageFromUrl(currentUrl) + : null; if (StandaloneScreenType.includes(currentPage)) return; } SemanticVersion previousVersion = SemanticVersion(); if (server.isDevToolsServerAvailable) { - final lastReleaseNotesShownVersion = - await server.getLastShownReleaseNotesVersion(); + final lastReleaseNotesShownVersion = await server + .getLastShownReleaseNotesVersion(); _log.fine('lastReleaseNotesShownVersion: $lastReleaseNotesShownVersion'); if (lastReleaseNotesShownVersion.isNotEmpty) { previousVersion = SemanticVersion.parse(lastReleaseNotesShownVersion); diff --git a/packages/devtools_app/lib/src/framework/scaffold/about_dialog.dart b/packages/devtools_app/lib/src/framework/scaffold/about_dialog.dart index 86d4bba775d..cc0fb5a8b2a 100644 --- a/packages/devtools_app/lib/src/framework/scaffold/about_dialog.dart +++ b/packages/devtools_app/lib/src/framework/scaffold/about_dialog.dart @@ -34,10 +34,8 @@ class DevToolsAboutDialog extends StatelessWidget { const Text(' - '), InkWell( child: Text('release notes', style: theme.linkTextStyle), - onTap: - () => unawaited( - releaseNotesController.openLatestReleaseNotes(), - ), + onTap: () => + unawaited(releaseNotesController.openLatestReleaseNotes()), ), ], ), @@ -135,10 +133,9 @@ class OpenAboutAction extends ScaffoldAction { unawaited( showDialog( context: context, - builder: - (context) => DevToolsAboutDialog( - Provider.of(context), - ), + builder: (context) => DevToolsAboutDialog( + Provider.of(context), + ), ), ); }, diff --git a/packages/devtools_app/lib/src/framework/scaffold/scaffold.dart b/packages/devtools_app/lib/src/framework/scaffold/scaffold.dart index e2c6de1b016..47a9caa4350 100644 --- a/packages/devtools_app/lib/src/framework/scaffold/scaffold.dart +++ b/packages/devtools_app/lib/src/framework/scaffold/scaffold.dart @@ -147,10 +147,9 @@ class DevToolsScaffoldState extends State } else if (widget.screens[_tabController!.index].screenId != widget.page) { // If the page changed (eg. the route was modified by pressing back in the // browser), animate to the new one. - var newIndex = - widget.page == null - ? 0 // When there's no supplied page, we show the first one. - : widget.screens.indexWhere((t) => t.screenId == widget.page); + var newIndex = widget.page == null + ? 0 // When there's no supplied page, we show the first one. + : widget.screens.indexWhere((t) => t.screenId == widget.page); // Ensure the returned index is in range, otherwise set to 0. if (newIndex == -1) { newIndex = 0; @@ -326,44 +325,42 @@ class DevToolsScaffoldState extends State child: KeyboardShortcuts( keyboardShortcuts: _currentScreen.buildKeyboardShortcuts(context), child: Scaffold( - appBar: - showAppBar - ? PreferredSize( - preferredSize: Size.fromHeight(defaultToolbarHeight), - // Place the AppBar inside of a Hero widget to keep it the same across - // route transitions. - child: Hero( - tag: _appBarTag, - child: DevToolsAppBar( - tabController: _tabController, - screens: widget.screens, - actions: widget.actions, - ), + appBar: showAppBar + ? PreferredSize( + preferredSize: Size.fromHeight(defaultToolbarHeight), + // Place the AppBar inside of a Hero widget to keep it the same across + // route transitions. + child: Hero( + tag: _appBarTag, + child: DevToolsAppBar( + tabController: _tabController, + screens: widget.screens, + actions: widget.actions, ), - ) - : null, + ), + ) + : null, body: OutlineDecoration.onlyTop( child: Padding( padding: widget.appPadding, - child: - showConsole - ? SplitPane( - axis: Axis.vertical, - splitters: [ConsolePaneHeader()], - initialFractions: const [0.8, 0.2], - children: [ - Padding( - padding: const EdgeInsets.only( - bottom: intermediateSpacing, - ), - child: content, + child: showConsole + ? SplitPane( + axis: Axis.vertical, + splitters: [ConsolePaneHeader()], + initialFractions: const [0.8, 0.2], + children: [ + Padding( + padding: const EdgeInsets.only( + bottom: intermediateSpacing, ), - RoundedOutlinedBorder.onlyBottom( - child: const ConsolePane(), - ), - ], - ) - : content, + child: content, + ), + RoundedOutlinedBorder.onlyBottom( + child: const ConsolePane(), + ), + ], + ) + : content, ), ), bottomNavigationBar: StatusLine( diff --git a/packages/devtools_app/lib/src/framework/scaffold/settings_dialog.dart b/packages/devtools_app/lib/src/framework/scaffold/settings_dialog.dart index 53de8c0bb55..c73d34fde84 100644 --- a/packages/devtools_app/lib/src/framework/scaffold/settings_dialog.dart +++ b/packages/devtools_app/lib/src/framework/scaffold/settings_dialog.dart @@ -61,10 +61,9 @@ class SettingsDialog extends StatelessWidget { child: CheckboxSetting( title: 'Enable analytics', notifier: analyticsController.analyticsEnabled, - onChanged: - (enable) => unawaited( - analyticsController.toggleAnalyticsEnabled(enable), - ), + onChanged: (enable) => unawaited( + analyticsController.toggleAnalyticsEnabled(enable), + ), gaScreen: gac.settingsDialog, gaItem: gac.analytics, ), @@ -133,11 +132,10 @@ class _VerboseLoggingSetting extends StatelessWidget { gaSelection: gac.copyLogs, minScreenWidthForTextBeforeScaling: _minScreenWidthForTextBeforeScaling, - onPressed: - () async => await copyToClipboard( - LogStorage.root.toString(), - successMessage: 'Successfully copied logs', - ), + onPressed: () async => await copyToClipboard( + LogStorage.root.toString(), + successMessage: 'Successfully copied logs', + ), ), const SizedBox(width: denseSpacing), ClearButton( diff --git a/packages/devtools_app/lib/src/framework/scaffold/status_line.dart b/packages/devtools_app/lib/src/framework/scaffold/status_line.dart index 6d0515b4a39..8da298bb40f 100644 --- a/packages/devtools_app/lib/src/framework/scaffold/status_line.dart +++ b/packages/devtools_app/lib/src/framework/scaffold/status_line.dart @@ -48,10 +48,12 @@ class StatusLine extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final backgroundColor = - highlightForConnection ? theme.colorScheme.primary : null; - final foregroundColor = - highlightForConnection ? theme.colorScheme.onPrimary : null; + final backgroundColor = highlightForConnection + ? theme.colorScheme.primary + : null; + final foregroundColor = highlightForConnection + ? theme.colorScheme.onPrimary + : null; final height = statusLineHeight + padding.top + padding.bottom; return ValueListenableBuilder( valueListenable: currentScreen.showIsolateSelector, @@ -81,8 +83,9 @@ class StatusLine extends StatelessWidget { List _getStatusItems(BuildContext context, bool showIsolateSelector) { final theme = Theme.of(context); - final foregroundColor = - highlightForConnection ? theme.colorScheme.onPrimary : null; + final foregroundColor = highlightForConnection + ? theme.colorScheme.onPrimary + : null; final screenWidth = ScreenSize(context).width; // TODO(https://github.com/flutter/devtools/issues/8913): this builds the // wrong status items for offline mode. @@ -146,10 +149,9 @@ class StatusLine extends StatelessWidget { description = vm.deviceDisplay; } - final color = - highlightForConnection - ? theme.colorScheme.onPrimary - : theme.regularTextStyle.color; + final color = highlightForConnection + ? theme.colorScheme.onPrimary + : theme.regularTextStyle.color; return Row( mainAxisAlignment: MainAxisAlignment.end, @@ -160,12 +162,11 @@ class StatusLine extends StatelessWidget { return SizedBox( width: smallProgressSize, height: smallProgressSize, - child: - isBusy - ? SmallCircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(color), - ) - : const SizedBox(), + child: isBusy + ? SmallCircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(color), + ) + : const SizedBox(), ); }, ), @@ -174,12 +175,11 @@ class StatusLine extends StatelessWidget { message: 'Connected device', child: Text( description, - style: - highlightForConnection - ? theme.regularTextStyle.copyWith( - color: theme.colorScheme.onPrimary, - ) - : theme.regularTextStyle, + style: highlightForConnection + ? theme.regularTextStyle.copyWith( + color: theme.colorScheme.onPrimary, + ) + : theme.regularTextStyle, overflow: TextOverflow.clip, ), ), @@ -189,13 +189,12 @@ class StatusLine extends StatelessWidget { return child!; } }, - child: - screenWidth <= MediaSize.xxs - ? DevToolsTooltip( - message: noConnectionMsg, - child: Icon(Icons.warning_amber_rounded, size: actionsIconSize), - ) - : Text(noConnectionMsg, style: theme.regularTextStyle), + child: screenWidth <= MediaSize.xxs + ? DevToolsTooltip( + message: noConnectionMsg, + child: Icon(Icons.warning_amber_rounded, size: actionsIconSize), + ) + : Text(noConnectionMsg, style: theme.regularTextStyle), ); } } @@ -218,8 +217,9 @@ class DocumentationLink extends StatelessWidget { @override Widget build(BuildContext context) { - final color = - highlightForConnection ? Theme.of(context).colorScheme.onPrimary : null; + final color = highlightForConnection + ? Theme.of(context).colorScheme.onPrimary + : null; final docPageId = screen.docPageId ?? ''; return LinkIconLabel( icon: Icons.library_books_outlined, @@ -256,8 +256,9 @@ class VideoTutorialLink extends StatelessWidget { @override Widget build(BuildContext context) { - final color = - highlightForConnection ? Theme.of(context).colorScheme.onPrimary : null; + final color = highlightForConnection + ? Theme.of(context).colorScheme.onPrimary + : null; return LinkIconLabel( icon: Icons.ondemand_video_rounded, link: GaLink( @@ -290,19 +291,17 @@ class IsolateSelector extends StatelessWidget { tooltip: 'Selected Isolate', initialValue: selectedIsolateRef, onSelected: isolateManager.selectIsolate, - itemBuilder: - (BuildContext context) => - isolates.map((ref) { - return PopupMenuItem( - value: ref, - child: _IsolateOption( - ref, - // This is always rendered against the background color - // for the pop up menu, which is the `surface` color. - color: Theme.of(context).colorScheme.onSurface, - ), - ); - }).toList(), + itemBuilder: (BuildContext context) => isolates.map((ref) { + return PopupMenuItem( + value: ref, + child: _IsolateOption( + ref, + // This is always rendered against the background color + // for the pop up menu, which is the `surface` color. + color: Theme.of(context).colorScheme.onSurface, + ), + ); + }).toList(), child: _IsolateOption( isolateManager.selectedIsolate.value, color: foregroundColor, diff --git a/packages/devtools_app/lib/src/screens/app_size/app_size_controller.dart b/packages/devtools_app/lib/src/screens/app_size/app_size_controller.dart index f202d564fd0..cabe3825ebe 100644 --- a/packages/devtools_app/lib/src/screens/app_size/app_size_controller.dart +++ b/packages/devtools_app/lib/src/screens/app_size/app_size_controller.dart @@ -396,10 +396,9 @@ class AppSizeController extends DevToolsScreenController { Map _extractDeferredUnits(Map jsonFile) { if (_hasDeferredInfo(jsonFile)) { - jsonFile['children'] = - _extractChildren( - jsonFile, - ).where((child) => child['isDeferred'] == true).toList(); + jsonFile['children'] = _extractChildren( + jsonFile, + ).where((child) => child['isDeferred'] == true).toList(); jsonFile['n'] = _deferredNodeName; } return jsonFile; @@ -699,17 +698,16 @@ class AppSizeController extends DevToolsScreenController { bool skipNodesWithNoByteSizeChange = true, }) { assert(showDiff ? diffTreeType != null : true); - final rawChildren = - (treeJson['children'] as List).cast>(); + final rawChildren = (treeJson['children'] as List) + .cast>(); final treemapNodeChildren = []; int totalByteSize = 0; // Given a child, build its subtree. for (final child in rawChildren) { - final childTreemapNode = - showDiff - ? generateDiffTree(child, diffTreeType!) - : generateTree(child); + final childTreemapNode = showDiff + ? generateDiffTree(child, diffTreeType!) + : generateTree(child); if (childTreemapNode == null) { continue; } @@ -721,11 +719,11 @@ class AppSizeController extends DevToolsScreenController { return totalByteSize == 0 && skipNodesWithNoByteSizeChange ? null : _buildNode( - treeJson, - totalByteSize, - children: treemapNodeChildren, - showDiff: showDiff, - ); + treeJson, + totalByteSize, + children: treemapNodeChildren, + showDiff: showDiff, + ); } TreemapNode _buildNode( diff --git a/packages/devtools_app/lib/src/screens/app_size/app_size_screen.dart b/packages/devtools_app/lib/src/screens/app_size/app_size_screen.dart index 102c6a46e37..36e3406bc0a 100644 --- a/packages/devtools_app/lib/src/screens/app_size/app_size_screen.dart +++ b/packages/devtools_app/lib/src/screens/app_size/app_size_screen.dart @@ -345,20 +345,19 @@ class _AnalysisViewState extends State with AutoDisposeMixin { return Column( children: [ Expanded( - child: - analysisRootLocal == null - ? _buildImportFileView() - : _AppSizeView( - title: _generateSingleFileHeaderText(), - treemapKey: AppSizeScreen.analysisViewTreemapKey, - treemapRoot: analysisRootLocal, - onRootChangedCallback: controller.changeAnalysisRoot, - analysisTable: AppSizeAnalysisTable( - rootNode: analysisRootLocal.root, - controller: controller, - ), - callGraphRoot: controller.analysisCallGraphRoot.value, + child: analysisRootLocal == null + ? _buildImportFileView() + : _AppSizeView( + title: _generateSingleFileHeaderText(), + treemapKey: AppSizeScreen.analysisViewTreemapKey, + treemapRoot: analysisRootLocal, + onRootChangedCallback: controller.changeAnalysisRoot, + analysisTable: AppSizeAnalysisTable( + rootNode: analysisRootLocal.root, + controller: controller, ), + callGraphRoot: controller.analysisCallGraphRoot.value, + ), ), ], ); @@ -366,10 +365,9 @@ class _AnalysisViewState extends State with AutoDisposeMixin { String _generateSingleFileHeaderText() { final analysisFile = controller.analysisJsonFile.value!; - String output = - analysisFile.isAnalyzeSizeFile - ? 'Total size analysis: ' - : 'Dart AOT snapshot: '; + String output = analysisFile.isAnalyzeSizeFile + ? 'Total size analysis: ' + : 'Dart AOT snapshot: '; output += analysisFile.displayText; return output; } @@ -381,26 +379,26 @@ class _AnalysisViewState extends State with AutoDisposeMixin { return processing ? const CenteredMessage(message: AppSizeScreen.loadingMessage) : Column( - children: [ - Flexible( - child: FileImportContainer( - instructions: AnalysisView.importInstructions, - actionText: 'Analyze Size', - gaScreen: gac.appSize, - gaSelectionImport: gac.importFileSingle, - gaSelectionAction: gac.analyzeSingle, - onAction: (jsonFile) { - controller.loadTreeFromJsonFile( - jsonFile: jsonFile, - onError: (error) { - if (mounted) notificationService.push(error); - }, - ); - }, + children: [ + Flexible( + child: FileImportContainer( + instructions: AnalysisView.importInstructions, + actionText: 'Analyze Size', + gaScreen: gac.appSize, + gaSelectionImport: gac.importFileSingle, + gaSelectionAction: gac.analyzeSingle, + onAction: (jsonFile) { + controller.loadTreeFromJsonFile( + jsonFile: jsonFile, + onError: (error) { + if (mounted) notificationService.push(error); + }, + ); + }, + ), ), - ), - ], - ); + ], + ); }, ); } @@ -451,17 +449,16 @@ class _DiffViewState extends State with AutoDisposeMixin { return Column( children: [ Expanded( - child: - diffRootLocal == null - ? _buildImportDiffView() - : _AppSizeView( - title: _generateDualFileHeaderText(), - treemapKey: AppSizeScreen.diffViewTreemapKey, - treemapRoot: diffRootLocal, - onRootChangedCallback: controller.changeDiffRoot, - analysisTable: AppSizeDiffTable(rootNode: diffRootLocal), - callGraphRoot: controller.diffCallGraphRoot.value, - ), + child: diffRootLocal == null + ? _buildImportDiffView() + : _AppSizeView( + title: _generateDualFileHeaderText(), + treemapKey: AppSizeScreen.diffViewTreemapKey, + treemapRoot: diffRootLocal, + onRootChangedCallback: controller.changeDiffRoot, + analysisTable: AppSizeDiffTable(rootNode: diffRootLocal), + callGraphRoot: controller.diffCallGraphRoot.value, + ), ), ], ); @@ -471,10 +468,9 @@ class _DiffViewState extends State with AutoDisposeMixin { final oldFile = controller.oldDiffJsonFile.value!; final newFile = controller.newDiffJsonFile.value!; String output = 'Diffing '; - output += - oldFile.isAnalyzeSizeFile - ? 'total size analyses: ' - : 'Dart AOT snapshots: '; + output += oldFile.isAnalyzeSizeFile + ? 'total size analyses: ' + : 'Dart AOT snapshots: '; output += oldFile.displayText; output += ' (OLD) vs (NEW) '; output += newFile.displayText; @@ -488,31 +484,30 @@ class _DiffViewState extends State with AutoDisposeMixin { return processing ? const CenteredMessage(message: AppSizeScreen.loadingMessage) : Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: DualFileImportContainer( - firstFileTitle: 'Old', - secondFileTitle: 'New', - // TODO(kenz): perhaps bold "original" and "modified". - firstInstructions: DiffView.importOldInstructions, - secondInstructions: DiffView.importNewInstructions, - actionText: 'Analyze Diff', - gaScreen: gac.appSize, - gaSelectionImportFirst: gac.importFileDiffFirst, - gaSelectionImportSecond: gac.importFileDiffSecond, - gaSelectionAction: gac.analyzeDiff, - onAction: - (oldFile, newFile, onError) => - controller.loadDiffTreeFromJsonFiles( - oldFile: oldFile, - newFile: newFile, - onError: onError, - ), + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: DualFileImportContainer( + firstFileTitle: 'Old', + secondFileTitle: 'New', + // TODO(kenz): perhaps bold "original" and "modified". + firstInstructions: DiffView.importOldInstructions, + secondInstructions: DiffView.importNewInstructions, + actionText: 'Analyze Diff', + gaScreen: gac.appSize, + gaSelectionImportFirst: gac.importFileDiffFirst, + gaSelectionImportSecond: gac.importFileDiffSecond, + gaSelectionAction: gac.analyzeDiff, + onAction: (oldFile, newFile, onError) => + controller.loadDiffTreeFromJsonFiles( + oldFile: oldFile, + newFile: newFile, + onError: onError, + ), + ), ), - ), - ], - ); + ], + ); }, ); } diff --git a/packages/devtools_app/lib/src/screens/app_size/app_size_table.dart b/packages/devtools_app/lib/src/screens/app_size/app_size_table.dart index 9c28f5c7627..0708b40ebdd 100644 --- a/packages/devtools_app/lib/src/screens/app_size/app_size_table.dart +++ b/packages/devtools_app/lib/src/screens/app_size/app_size_table.dart @@ -19,20 +19,18 @@ class AppSizeAnalysisTable extends StatelessWidget { required AppSizeController controller, }) { final treeColumn = _NameColumn( - currentRootLevel: - controller.isDeferredApp.value - ? rootNode.children.first.level - : rootNode.level, + currentRootLevel: controller.isDeferredApp.value + ? rootNode.children.first.level + : rootNode.level, ); final sizeColumn = _SizeColumn(); final columns = List>.unmodifiable([ treeColumn, sizeColumn, _SizePercentageColumn( - totalSize: - controller.isDeferredApp.value - ? rootNode.children[0].root.byteSize - : rootNode.root.byteSize, + totalSize: controller.isDeferredApp.value + ? rootNode.children[0].root.byteSize + : rootNode.root.byteSize, ), ]); @@ -65,8 +63,9 @@ class AppSizeAnalysisTable extends StatelessWidget { Widget build(BuildContext context) { return TreeTable( keyFactory: (node) => PageStorageKey(node.name), - dataRoots: - controller.isDeferredApp.value ? rootNode.children : [rootNode], + dataRoots: controller.isDeferredApp.value + ? rootNode.children + : [rootNode], dataKey: 'app-size-analysis', columns: columns, treeColumn: treeColumn, diff --git a/packages/devtools_app/lib/src/screens/app_size/code_size_attribution.dart b/packages/devtools_app/lib/src/screens/app_size/code_size_attribution.dart index 7bb60800838..b3c3668263a 100644 --- a/packages/devtools_app/lib/src/screens/app_size/code_size_attribution.dart +++ b/packages/devtools_app/lib/src/screens/app_size/code_size_attribution.dart @@ -64,13 +64,12 @@ class _CallGraphWithDominatorsState extends State { ], ), Expanded( - child: - showCallGraph - ? CallGraphView(node: widget.callGraphRoot) - : DominatorTree( - dominatorTreeRoot: dominatorTreeRoot, - selectedNode: widget.callGraphRoot, - ), + child: showCallGraph + ? CallGraphView(node: widget.callGraphRoot) + : DominatorTree( + dominatorTreeRoot: dominatorTreeRoot, + selectedNode: widget.callGraphRoot, + ), ), ], ); @@ -228,10 +227,9 @@ class _CallGraphTable extends StatelessWidget { Widget build(BuildContext context) { return FlatTable( keyFactory: (CallGraphNode node) => ValueKey(node), - data: - tableType == _CallGraphTableType.from - ? selectedNode.pred - : selectedNode.succ, + data: tableType == _CallGraphTableType.from + ? selectedNode.pred + : selectedNode.succ, dataKey: tableType.dataKey, columns: [tableColumn], onItemSelected: onNodeSelected, @@ -315,10 +313,9 @@ class _PackageColumn extends TreeColumnData { extension CallGraphNodeDisplay on CallGraphNode { String get display { - final displayText = - data is ProgramInfoNode - ? (data as ProgramInfoNode).qualifiedName - : data.toString(); + final displayText = data is ProgramInfoNode + ? (data as ProgramInfoNode).qualifiedName + : data.toString(); if (displayText == '@shared') { // Special case '@shared' because this is the name of the call graph root, // and '@root' has a more intuitive meaning. diff --git a/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart b/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart index 89e887d99b6..646fffa5d4b 100644 --- a/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart +++ b/packages/devtools_app/lib/src/screens/debugger/breakpoint_manager.dart @@ -225,10 +225,9 @@ class BreakpointManager with DisposerMixin { }) async { _breakpoints.value = breakpoints; // Build _breakpointsWithLocation from _breakpoints. - final breakpointsWithLocation = - await _breakpoints.value - .map(breakpointManager.createBreakpointWithLocation) - .wait; + final breakpointsWithLocation = await _breakpoints.value + .map(breakpointManager.createBreakpointWithLocation) + .wait; if (isolateId != _isolateRefId) { // Current request is obsolete. @@ -401,11 +400,10 @@ class BreakpointManager with DisposerMixin { // the restart. Note we only track hot restarts triggered by DevTools, // if a hot-restart was triggered by another client we won't know. // See https://github.com/flutter/flutter/issues/134470 - final hotRestartInProgress = - serviceConnection - .serviceManager - .isolateManager - .hotRestartInProgress; + final hotRestartInProgress = serviceConnection + .serviceManager + .isolateManager + .hotRestartInProgress; if (hotRestartInProgress) break; final breakpoint = event.breakpoint; diff --git a/packages/devtools_app/lib/src/screens/debugger/breakpoints.dart b/packages/devtools_app/lib/src/screens/debugger/breakpoints.dart index 9886db476a8..c5394f1779e 100644 --- a/packages/devtools_app/lib/src/screens/debugger/breakpoints.dart +++ b/packages/devtools_app/lib/src/screens/debugger/breakpoints.dart @@ -88,10 +88,9 @@ class _Breakpoint extends StatelessWidget { children: [ TextSpan( text: ' (${breakpoint.scriptUri})', - style: - isSelected - ? theme.selectedSubtleTextStyle - : theme.subtleTextStyle, + style: isSelected + ? theme.selectedSubtleTextStyle + : theme.subtleTextStyle, ), ], ), diff --git a/packages/devtools_app/lib/src/screens/debugger/call_stack.dart b/packages/devtools_app/lib/src/screens/debugger/call_stack.dart index 9fc750781e1..eaa2d239982 100644 --- a/packages/devtools_app/lib/src/screens/debugger/call_stack.dart +++ b/packages/devtools_app/lib/src/screens/debugger/call_stack.dart @@ -93,10 +93,9 @@ class _CallStackState extends State { if (locationDescription != null) TextSpan( text: ' $locationDescription', - style: - selected - ? theme.selectedSubtleTextStyle - : theme.subtleTextStyle, + style: selected + ? theme.selectedSubtleTextStyle + : theme.subtleTextStyle, ), ], ), @@ -120,13 +119,12 @@ class _CallStackState extends State { return isAsyncBreak ? result : DevToolsTooltip( - message: - locationDescription == null - ? frameDescription - : '$frameDescription $locationDescription', - waitDuration: tooltipWaitLong, - child: result, - ); + message: locationDescription == null + ? frameDescription + : '$frameDescription $locationDescription', + waitDuration: tooltipWaitLong, + child: result, + ); } Future _onStackFrameSelected(StackFrameAndSourcePosition frame) async { diff --git a/packages/devtools_app/lib/src/screens/debugger/codeview.dart b/packages/devtools_app/lib/src/screens/debugger/codeview.dart index 841aba57f40..600d5aeb8a5 100644 --- a/packages/devtools_app/lib/src/screens/debugger/codeview.dart +++ b/packages/devtools_app/lib/src/screens/debugger/codeview.dart @@ -249,8 +249,8 @@ class _CodeViewState extends State with AutoDisposeMixin { verticalController.hasAttachedControllers ? updateScrollPositionImpl() : WidgetsBinding.instance.addPostFrameCallback( - (_) => updateScrollPositionImpl(), - ); + (_) => updateScrollPositionImpl(), + ); } @override @@ -331,8 +331,8 @@ class _CodeViewState extends State with AutoDisposeMixin { thumbVisibility: true, // Only listen for vertical scroll notifications (ignore those // from the nested horizontal SingleChildScrollView): - notificationPredicate: - (ScrollNotification notification) => notification.depth == 1, + notificationPredicate: (ScrollNotification notification) => + notification.depth == 1, child: ValueListenableBuilder( valueListenable: widget.debuggerController?.selectedStackFrame ?? @@ -340,8 +340,9 @@ class _CodeViewState extends State with AutoDisposeMixin { null, ), builder: (context, frame, _) { - final pausedFrame = - frame?.scriptRef == scriptRef ? frame : null; + final pausedFrame = frame?.scriptRef == scriptRef + ? frame + : null; return ValueListenableBuilder( valueListenable: @@ -370,9 +371,8 @@ class _CodeViewState extends State with AutoDisposeMixin { ); return Scrollbar( - key: - CodeView - .debuggerCodeViewHorizontalScrollbarKey, + key: CodeView + .debuggerCodeViewHorizontalScrollbarKey, thumbVisibility: true, controller: horizontalController, child: SingleChildScrollView( @@ -390,18 +390,15 @@ class _CodeViewState extends State with AutoDisposeMixin { widget.codeViewController, scrollController: textController, lines: lines, - selectedFrameNotifier: - widget - .debuggerController - ?.selectedStackFrame, - searchMatchesNotifier: - widget - .codeViewController - .searchMatches, - activeSearchMatchNotifier: - widget - .codeViewController - .activeSearchMatch, + selectedFrameNotifier: widget + .debuggerController + ?.selectedStackFrame, + searchMatchesNotifier: widget + .codeViewController + .searchMatches, + activeSearchMatchNotifier: widget + .codeViewController + .activeSearchMatch, showProfileInformation: showProfileInformation, ), @@ -438,11 +435,9 @@ class _CodeViewState extends State with AutoDisposeMixin { return scriptUri; }, titleIcon: Icons.search, - onTitleTap: - () => - widget.codeViewController - ..toggleFileOpenerVisibility(true) - ..toggleSearchInFileVisibility(false), + onTitleTap: () => widget.codeViewController + ..toggleFileOpenerVisibility(true) + ..toggleSearchInFileVisibility(false), controls: [ ScriptPopupMenu(widget.codeViewController), ScriptHistoryPopupMenu( @@ -482,8 +477,8 @@ class _CodeViewState extends State with AutoDisposeMixin { searchFieldEnabled: parsedScript != null, shouldRequestFocus: true, searchFieldWidth: wideSearchFieldWidth, - onClose: - () => widget.codeViewController.toggleSearchInFileVisibility(false), + onClose: () => + widget.codeViewController.toggleSearchInFileVisibility(false), ), ); } @@ -533,8 +528,8 @@ class CodeViewEmptyState extends StatelessWidget { return Center( child: ElevatedButton( autofocus: true, - onPressed: - () => widget.codeViewController.toggleFileOpenerVisibility(true), + onPressed: () => + widget.codeViewController.toggleFileOpenerVisibility(true), child: Text( 'Open a file ($openFileKeySetDescription)', style: theme.textTheme.titleMedium, @@ -785,8 +780,9 @@ class Gutters extends StatelessWidget { lineCount: lineCount, lineOffset: lineOffset, pausedFrame: pausedFrame, - breakpoints: - breakpoints.where((bp) => bp.scriptRef == scriptRef).toList(), + breakpoints: breakpoints + .where((bp) => bp.scriptRef == scriptRef) + .toList(), executableLines: parsedScript?.executableLines ?? const {}, sourceReport: sourceReport, onPressed: _onPressed, @@ -800,14 +796,14 @@ class Gutters extends StatelessWidget { !showProfileInformation ? const SizedBox(width: denseSpacing) : Padding( - padding: const EdgeInsets.only(right: denseSpacing), - child: ProfileInformationGutter( - scrollController: profileController!, - lineCount: lineCount, - lineOffset: lineOffset, - sourceReport: sourceReport, + padding: const EdgeInsets.only(right: denseSpacing), + child: ProfileInformationGutter( + scrollController: profileController!, + lineCount: lineCount, + lineOffset: lineOffset, + sourceReport: sourceReport, + ), ), - ), ], ); } @@ -939,10 +935,9 @@ class GutterItem extends StatelessWidget { TextStyle? coverageTextStyleOverride; final hasCoverage = coverageHit; if (hasCoverage != null) { - color = - hasCoverage - ? theme.colorScheme.coverageHitColor - : theme.colorScheme.coverageMissColor; + color = hasCoverage + ? theme.colorScheme.coverageHitColor + : theme.colorScheme.coverageMissColor; coverageTextStyleOverride = theme.regularTextStyleWithColor( theme.colorScheme.coverageAndPerformanceTextColor, ); @@ -1068,8 +1063,9 @@ class _LinesState extends State with AutoDisposeMixin { // the top of the profiler gutter columns. Everything needs to be shifted // down a single line so profiling information for line 1 isn't hidden by // the header. - final profileInformationHeaderOffset = - widget.showProfileInformation ? 1 : 0; + final profileInformationHeaderOffset = widget.showProfileInformation + ? 1 + : 0; return SelectionArea( child: ListView.builder( @@ -1093,10 +1089,9 @@ class _LinesState extends State with AutoDisposeMixin { pausedFrame: isPausedLine ? pausedFrame : null, focused: isPausedLine || isFocusedLine, searchMatches: _searchMatchesForLine(dataIndex), - activeSearchMatch: - activeSearch?.position.line == dataIndex - ? activeSearch - : null, + activeSearchMatch: activeSearch?.position.line == dataIndex + ? activeSearch + : null, ); }, ); @@ -1208,8 +1203,9 @@ class LineItem extends StatelessWidget { ); } - final backgroundColor = - focused ? theme.colorScheme.selectedRowBackgroundColor : null; + final backgroundColor = focused + ? theme.colorScheme.selectedRowBackgroundColor + : null; return Container( alignment: Alignment.centerLeft, @@ -1252,12 +1248,11 @@ class _HoverableLine extends StatelessWidget { if (word.isNotEmpty && !isPrimitiveValueOrNull(word)) { try { final response = await evalService.evalAtCurrentFrame(word); - final isolateRef = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value; + final isolateRef = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value; if (response is! InstanceRef) return null; final variable = DartObjectNode.fromValue( value: response, @@ -1413,15 +1408,14 @@ class ScriptPopupMenu extends StatelessWidget { Widget build(BuildContext context) { return PopupMenuButton( onSelected: (option) => option.onSelected(context, _controller), - itemBuilder: - (_) => [ - for (final menuOption in defaultScriptPopupMenuOptions) - menuOption.build(), - for (final extensionMenuOption - in devToolsEnvironmentParameters - .buildExtraDebuggerScriptPopupMenuOptions()) - extensionMenuOption.build(), - ], + itemBuilder: (_) => [ + for (final menuOption in defaultScriptPopupMenuOptions) + menuOption.build(), + for (final extensionMenuOption + in devToolsEnvironmentParameters + .buildExtraDebuggerScriptPopupMenuOptions()) + extensionMenuOption.build(), + ], child: Icon(Icons.more_vert, size: actionsIconSize), ); } @@ -1494,12 +1488,9 @@ final defaultScriptPopupMenuOptions = [ final copyPackagePathOption = ScriptPopupMenuOption( label: 'Copy package path', icon: Icons.content_copy, - onSelected: - (_, controller) => Clipboard.setData( - ClipboardData( - text: controller.scriptLocation.value?.scriptRef.uri ?? '', - ), - ), + onSelected: (_, controller) => Clipboard.setData( + ClipboardData(text: controller.scriptLocation.value?.scriptRef.uri ?? ''), + ), ); final copyFilePathOption = ScriptPopupMenuOption( @@ -1520,13 +1511,12 @@ Future fetchScriptLocationFullFilePath( String? filePath; final packagePath = controller.scriptLocation.value!.scriptRef.uri; if (packagePath != null) { - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; filePath = serviceConnection.serviceManager.resolvedUriManager .lookupFileUri(isolateId, packagePath); if (filePath == null) { diff --git a/packages/devtools_app/lib/src/screens/debugger/codeview_controller.dart b/packages/devtools_app/lib/src/screens/debugger/codeview_controller.dart index f5fc5748754..a937cf826e1 100644 --- a/packages/devtools_app/lib/src/screens/debugger/codeview_controller.dart +++ b/packages/devtools_app/lib/src/screens/debugger/codeview_controller.dart @@ -390,14 +390,13 @@ class CodeViewController extends DisposableController void _maybeShowSourceMapsWarning() { final isWebApp = serviceConnection.serviceManager.connectedApp?.isDartWebAppNow ?? false; - final enableSourceMapsLink = - devToolsEnvironmentParameters.enableSourceMapsLink(); + final enableSourceMapsLink = devToolsEnvironmentParameters + .enableSourceMapsLink(); if (isWebApp && enableSourceMapsLink != null) { final enableSourceMapsAction = NotificationAction( label: 'Enable sourcemaps', - onPressed: - () => - unawaited(launchUrlWithErrorHandling(enableSourceMapsLink.url)), + onPressed: () => + unawaited(launchUrlWithErrorHandling(enableSourceMapsLink.url)), ); notificationService.pushNotification( NotificationMessage( diff --git a/packages/devtools_app/lib/src/screens/debugger/controls.dart b/packages/devtools_app/lib/src/screens/debugger/controls.dart index 0c32662fd11..ec4f7cb70f8 100644 --- a/packages/devtools_app/lib/src/screens/debugger/controls.dart +++ b/packages/devtools_app/lib/src/screens/debugger/controls.dart @@ -98,24 +98,24 @@ class _DebuggingControlsState extends State items: [ !isPaused ? ButtonGroupItemData( - tooltip: 'Pause', - icon: Icons.pause, - autofocus: true, - // Disable when selected isolate is a system isolate. - onPressed: - isSystemIsolate ? null : () => unawaited(controller.pause()), - ) + tooltip: 'Pause', + icon: Icons.pause, + autofocus: true, + // Disable when selected isolate is a system isolate. + onPressed: isSystemIsolate + ? null + : () => unawaited(controller.pause()), + ) : ButtonGroupItemData( - tooltip: 'Resume', - iconAsset: 'icons/material_symbols/resume.png', - iconSize: DebuggingControls.materialIconSize, - // Enable not resuming and selected isolate is not a system - // isolate. - onPressed: - (!resuming && !isSystemIsolate) - ? () => unawaited(controller.resume()) - : null, - ), + tooltip: 'Resume', + iconAsset: 'icons/material_symbols/resume.png', + iconSize: DebuggingControls.materialIconSize, + // Enable not resuming and selected isolate is not a system + // isolate. + onPressed: (!resuming && !isSystemIsolate) + ? () => unawaited(controller.resume()) + : null, + ), ], ); } @@ -156,10 +156,9 @@ class _DebuggingControlsState extends State label: 'File Explorer', onPressed: controller.codeViewController.toggleLibrariesVisible, gaScreen: gac.debugger, - gaSelection: - visible - ? gac.DebuggerEvents.hideFileExplorer.name - : gac.DebuggerEvents.showFileExplorer.name, + gaSelection: visible + ? gac.DebuggerEvents.hideFileExplorer.name + : gac.DebuggerEvents.showFileExplorer.name, minScreenWidthForTextBeforeScaling: DebuggingControls.minWidthBeforeScaling, ); @@ -213,12 +212,11 @@ class CodeStatisticsControls extends StatelessWidget { tooltip: 'Refresh statistics', gaScreen: gac.debugger, gaSelection: gac.DebuggerEvents.refreshStatistics.name, - onPressed: - showCodeCoverage || showProfileInformation - ? () => unawaited( - controller.codeViewController.refreshCodeStatistics(), - ) - : null, + onPressed: showCodeCoverage || showProfileInformation + ? () => unawaited( + controller.codeViewController.refreshCodeStatistics(), + ) + : null, ), ], ); @@ -264,12 +262,11 @@ class BreakOnExceptionsControl extends StatelessWidget { child: RoundedDropDownButton( value: exceptionMode, // Cannot set exception pause mode for system isolates. - onChanged: - controller.isSystemIsolate - ? null - : (ExceptionMode? mode) { - unawaited(controller.setIsolatePauseMode(mode!.id)); - }, + onChanged: controller.isSystemIsolate + ? null + : (ExceptionMode? mode) { + unawaited(controller.setIsolatePauseMode(mode!.id)); + }, isDense: true, items: [ for (final mode in ExceptionMode.modes) diff --git a/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart b/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart index d69ebc1ee42..fceb7d332ad 100644 --- a/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart +++ b/packages/devtools_app/lib/src/screens/debugger/debugger_controller.dart @@ -271,10 +271,9 @@ class DebuggerController extends DevToolsScreenController return _service .resume( _isolateRefId, - step: - useAsyncStepping - ? StepOption.kOverAsyncSuspension - : StepOption.kOver, + step: useAsyncStepping + ? StepOption.kOverAsyncSuspension + : StepOption.kOver, ) .whenComplete(() => _debugTimingLog.log('stepOver() completed')); } @@ -595,10 +594,9 @@ class DebuggerController extends DevToolsScreenController return []; } - final variables = - frame.vars! - .map((v) => DartObjectNode.create(v, _isolate.value)) - .toList(); + final variables = frame.vars! + .map((v) => DartObjectNode.create(v, _isolate.value)) + .toList(); // TODO(jacobr): would be nice to be able to remove this call to unawaited // but it would require a significant refactor. variables @@ -631,13 +629,12 @@ class DebuggerController extends DevToolsScreenController } Future _fetchDapFrame(Frame vmFrame) async { - final isolateNumber = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value - ?.number; + final isolateNumber = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value + ?.number; final frameIndex = vmFrame.index; if (isolateNumber == null || frameIndex == null) return null; @@ -675,8 +672,8 @@ class DebuggerController extends DevToolsScreenController // Prefer asyncCausalFrames if they exist. List frames = asyncCausalFrames != null && asyncCausalFrames.isNotEmpty - ? asyncCausalFrames - : stackFrames; + ? asyncCausalFrames + : stackFrames; // Include any reported exception as a variable in the first frame. if (reportedException != null && frames.isNotEmpty) { diff --git a/packages/devtools_app/lib/src/screens/debugger/debugger_screen.dart b/packages/devtools_app/lib/src/screens/debugger/debugger_screen.dart index ad0bddfa29d..f7d80c89c52 100644 --- a/packages/devtools_app/lib/src/screens/debugger/debugger_screen.dart +++ b/packages/devtools_app/lib/src/screens/debugger/debugger_screen.dart @@ -189,10 +189,11 @@ class DebuggerWindows extends StatelessWidget { actions: [ CopyToClipboardControl( dataProvider: () { - final callStackList = - controller.stackFramesWithLocation.value - .map((frame) => frame.callStackDisplay) - .toList(); + final callStackList = controller + .stackFramesWithLocation + .value + .map((frame) => frame.callStackDisplay) + .toList(); for (var i = 0; i < callStackList.length; i++) { callStackList[i] = '#$i ${callStackList[i]}'; } @@ -235,10 +236,9 @@ class _BreakpointsWindowActions extends StatelessWidget { child: ToolbarAction( icon: Icons.delete, size: defaultIconSize, - onPressed: - breakpoints.isNotEmpty - ? () => unawaited(breakpointManager.clearBreakpoints()) - : null, + onPressed: breakpoints.isNotEmpty + ? () => unawaited(breakpointManager.clearBreakpoints()) + : null, ), ), ], @@ -285,8 +285,8 @@ class DebuggerSourceAndControls extends StatelessWidget { child: ProgramExplorer( controller: codeViewController.programExplorerController, - onNodeSelected: - (node) => _onNodeSelected(context, node), + onNodeSelected: (node) => + _onNodeSelected(context, node), ), ), ], @@ -321,10 +321,9 @@ class DebuggerSourceAndControls extends StatelessWidget { debuggerController: controller, scriptRef: scriptRef, parsedScript: parsedScript, - onSelected: - (script, line) => unawaited( - breakpointManager.toggleBreakpoint(script, line), - ), + onSelected: (script, line) => unawaited( + breakpointManager.toggleBreakpoint(script, line), + ), ); }, ), diff --git a/packages/devtools_app/lib/src/screens/debugger/file_search.dart b/packages/devtools_app/lib/src/screens/debugger/file_search.dart index 2e321e077aa..f32f6e5f769 100644 --- a/packages/devtools_app/lib/src/screens/debugger/file_search.dart +++ b/packages/devtools_app/lib/src/screens/debugger/file_search.dart @@ -92,10 +92,9 @@ class FileSearchFieldState extends State // If the current query is a continuation of the previous query, then // filter down the previous matches. Otherwise search through all scripts: - final scripts = - currentQuery.startsWith(previousQuery) - ? _searchResults.scriptRefs - : scriptManager.sortedScripts.value; + final scripts = currentQuery.startsWith(previousQuery) + ? _searchResults.scriptRefs + : scriptManager.sortedScripts.value; final searchResults = _createSearchResults(currentQuery, scripts); if (searchResults.scriptRefs.isEmpty) { @@ -192,13 +191,12 @@ class FileQuery { final fileName = _fileName(scriptUri); final fileNameIndex = scriptUri.lastIndexOf(fileName); - final matchedSegments = - _findExactSegments(fileName) - .map( - (range) => - Range(range.begin + fileNameIndex, range.end + fileNameIndex), - ) - .toList(); + final matchedSegments = _findExactSegments(fileName) + .map( + (range) => + Range(range.begin + fileNameIndex, range.end + fileNameIndex), + ) + .toList(); return AutoCompleteMatch(scriptUri, matchedSegments: matchedSegments); } @@ -245,15 +243,12 @@ class FileQuery { } else { final fileName = _fileName(scriptUri); final fileNameIndex = scriptUri.lastIndexOf(fileName); - matchedSegments = - _findFuzzySegments(fileName, query) - .map( - (range) => Range( - range.begin + fileNameIndex, - range.end + fileNameIndex, - ), - ) - .toList(); + matchedSegments = _findFuzzySegments(fileName, query) + .map( + (range) => + Range(range.begin + fileNameIndex, range.end + fileNameIndex), + ) + .toList(); } return AutoCompleteMatch(scriptUri, matchedSegments: matchedSegments); @@ -350,27 +345,21 @@ class FileSearchResults { FileSearchResults get topMatches => _buildTopMatches(); - List get scriptRefs => - query.isEmpty - ? allScripts - : [ - ..._exactFileNameMatches, - ..._exactFullPathMatches, - ..._fuzzyMatches, - ]; - - List get autoCompleteMatches => - query.isEmpty - ? allScripts.map((script) => AutoCompleteMatch(script.uri!)).toList() - : [ - ..._exactFileNameMatches.map( - query.createExactFileNameAutoCompleteMatch, - ), - ..._exactFullPathMatches.map( - query.createExactFullPathAutoCompleteMatch, - ), - ..._fuzzyMatches.map(query.createFuzzyMatchAutoCompleteMatch), - ]; + List get scriptRefs => query.isEmpty + ? allScripts + : [..._exactFileNameMatches, ..._exactFullPathMatches, ..._fuzzyMatches]; + + List get autoCompleteMatches => query.isEmpty + ? allScripts.map((script) => AutoCompleteMatch(script.uri!)).toList() + : [ + ..._exactFileNameMatches.map( + query.createExactFileNameAutoCompleteMatch, + ), + ..._exactFullPathMatches.map( + query.createExactFullPathAutoCompleteMatch, + ), + ..._fuzzyMatches.map(query.createFuzzyMatchAutoCompleteMatch), + ]; FileSearchResults copyWith({ List? allScripts, diff --git a/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart b/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart index e0efbc2741a..dc602fa7ac6 100644 --- a/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart +++ b/packages/devtools_app/lib/src/screens/debugger/program_explorer.dart @@ -243,35 +243,33 @@ class ProgramStructureIcon extends StatelessWidget { height: defaultIconSize, width: defaultIconSize, child: Container( - decoration: - icon == null - ? BoxDecoration(color: color, shape: BoxShape.circle) - : null, - child: - icon == null - ? Center( - child: Text( - character!, - style: TextStyle( - height: 1, - fontFamily: theme.fixedFontStyle.fontFamily, - color: theme.colorScheme.surface, - fontSize: smallFontSize, - ), - // Required to center the individual character within the - // shape. Since letters like 'm' are shorter than letters - // like 'f', there's padding applied to the top of shorter - // characters in order for everything to align properly. - // Since we're only dealing with individual characters, we - // want to disable this behavior so shorter characters don't - // appear to be slightly below center. - textHeightBehavior: TextHeightBehavior( - applyHeightToFirstAscent: isShortCharacter!, - applyHeightToLastDescent: false, - ), + decoration: icon == null + ? BoxDecoration(color: color, shape: BoxShape.circle) + : null, + child: icon == null + ? Center( + child: Text( + character!, + style: TextStyle( + height: 1, + fontFamily: theme.fixedFontStyle.fontFamily, + color: theme.colorScheme.surface, + fontSize: smallFontSize, ), - ) - : Icon(icon, size: defaultIconSize, color: color), + // Required to center the individual character within the + // shape. Since letters like 'm' are shorter than letters + // like 'f', there's padding applied to the top of shorter + // characters in order for everything to align properly. + // Since we're only dealing with individual characters, we + // want to disable this behavior so shorter characters don't + // appear to be slightly below center. + textHeightBehavior: TextHeightBehavior( + applyHeightToFirstAscent: isShortCharacter!, + applyHeightToLastDescent: false, + ), + ), + ) + : Icon(icon, size: defaultIconSize, color: color), ), ); } @@ -297,9 +295,8 @@ class _FileExplorerState extends State<_FileExplorer> with AutoDisposeMixin { double get selectedNodeOffset => widget.controller.selectedNodeIndex.value == -1 - ? -1 - : widget.controller.selectedNodeIndex.value * - defaultTreeViewRowHeight; + ? -1 + : widget.controller.selectedNodeIndex.value * defaultTreeViewRowHeight; @override void initState() { @@ -390,8 +387,8 @@ class _ProgramOutlineView extends StatelessWidget { }, ); }, - emptyTreeViewBuilder: - () => const Center(child: Text('Nothing to inspect')), + emptyTreeViewBuilder: () => + const Center(child: Text('Nothing to inspect')), ); }, ); @@ -423,14 +420,13 @@ class ProgramExplorer extends StatelessWidget { if (!initialized) { body = const CenteredCircularProgressIndicator(); } else { - final fileExplorerHeader = - displayHeader - ? AreaPaneHeader( - title: Text(title), - includeTopBorder: false, - roundedTopBorder: false, - ) - : const BlankHeader(); + final fileExplorerHeader = displayHeader + ? AreaPaneHeader( + title: Text(title), + includeTopBorder: false, + roundedTopBorder: false, + ) + : const BlankHeader(); final fileExplorer = _FileExplorer( controller: controller, onItemExpanded: onItemExpanded, @@ -452,31 +448,31 @@ class ProgramExplorer extends StatelessWidget { .connectedApp! .isDartWebAppNow! ? Column( - children: [ - fileExplorerHeader, - Expanded(child: fileExplorer), - ], - ) + children: [ + fileExplorerHeader, + Expanded(child: fileExplorer), + ], + ) : FlexSplitColumn( - totalHeight: constraints.maxHeight, - initialFractions: const [0.7, 0.3], - minSizes: const [0.0, 0.0], - headers: [ - fileExplorerHeader as PreferredSizeWidget, - const AreaPaneHeader( - title: Text('Outline'), - roundedTopBorder: false, - ), - ], - children: [ - fileExplorer, - _ProgramOutlineView( - controller: controller, - onItemExpanded: onItemExpanded, - onItemSelected: onItemSelected, - ), - ], - ); + totalHeight: constraints.maxHeight, + initialFractions: const [0.7, 0.3], + minSizes: const [0.0, 0.0], + headers: [ + fileExplorerHeader as PreferredSizeWidget, + const AreaPaneHeader( + title: Text('Outline'), + roundedTopBorder: false, + ), + ], + children: [ + fileExplorer, + _ProgramOutlineView( + controller: controller, + onItemExpanded: onItemExpanded, + onItemSelected: onItemSelected, + ), + ], + ); }, ); } diff --git a/packages/devtools_app/lib/src/screens/debugger/program_explorer_controller.dart b/packages/devtools_app/lib/src/screens/debugger/program_explorer_controller.dart index edf32167ce9..09ad5b74983 100644 --- a/packages/devtools_app/lib/src/screens/debugger/program_explorer_controller.dart +++ b/packages/devtools_app/lib/src/screens/debugger/program_explorer_controller.dart @@ -71,13 +71,12 @@ class ProgramExplorerController extends DisposableController final isolate = serviceConnection.serviceManager.isolateManager.selectedIsolate.value; - final libraries = - isolate != null - ? serviceConnection.serviceManager.isolateManager - .isolateState(isolate) - .isolateNow! - .libraries! - : []; + final libraries = isolate != null + ? serviceConnection.serviceManager.isolateManager + .isolateState(isolate) + .isolateNow! + .libraries! + : []; if (scriptManager.sortedScripts.value.isEmpty && isolate != null) { await scriptManager.retrieveAndSortScripts(isolate); @@ -143,10 +142,9 @@ class ProgramExplorerController extends DisposableController final matchingNode = depthFirstTraversal( node, returnCondition: matchingNodeCondition, - exploreChildrenCondition: - includeCollapsedNodes - ? null - : (VMServiceObjectNode node) => node.isExpanded, + exploreChildrenCondition: includeCollapsedNodes + ? null + : (VMServiceObjectNode node) => node.isExpanded, action: (VMServiceObjectNode _) => index++, ); if (matchingNode != null) return index; @@ -245,13 +243,12 @@ class ProgramExplorerController extends DisposableController Future populateNode(VMServiceObjectNode node) async { final object = node.object; final service = serviceConnection.serviceManager.service; - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id; Future> getObjects(Iterable objs) { return objs.map((o) => service!.getObject(isolateId!, o.id!)).wait; @@ -299,21 +296,19 @@ class ProgramExplorerController extends DisposableController return; } else if (object is LibraryRef) { final lib = await service!.getObject(isolateId!, object.id!) as Library; - final (variableObjects, functionObjects) = - await ( - getObjects(lib.variables!), - getFuncs(lib.functions!, lib.variables), - ).wait; + final (variableObjects, functionObjects) = await ( + getObjects(lib.variables!), + getFuncs(lib.functions!, lib.variables), + ).wait; lib.variables = variableObjects.cast(); lib.functions = functionObjects; node.updateObject(lib); } else if (object is ClassRef) { final clazz = await service!.getObject(isolateId!, object.id!) as Class; - final (fieldObjects, functionObjects) = - await ( - getObjects(clazz.fields!), - getFuncs(clazz.functions!, clazz.fields), - ).wait; + final (fieldObjects, functionObjects) = await ( + getObjects(clazz.fields!), + getFuncs(clazz.functions!, clazz.fields), + ).wait; clazz.fields = fieldObjects.cast(); clazz.functions = functionObjects; node.updateObject(clazz); @@ -330,13 +325,12 @@ class ProgramExplorerController extends DisposableController /// which is the source location of the target [object]. Future searchFileExplorer(ObjRef object) async { final service = serviceConnection.serviceManager.service!; - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; // If `object` is a library, it will always be a root node and is simple to // find. diff --git a/packages/devtools_app/lib/src/screens/debugger/program_explorer_model.dart b/packages/devtools_app/lib/src/screens/debugger/program_explorer_model.dart index e21f7608ff9..d39907f1a6c 100644 --- a/packages/devtools_app/lib/src/screens/debugger/program_explorer_model.dart +++ b/packages/devtools_app/lib/src/screens/debugger/program_explorer_model.dart @@ -80,12 +80,11 @@ class VMServiceObjectNode extends TreeNode { // script's URI. if (libNode == null) { final service = serviceConnection.serviceManager.service!; - final isolate = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value!; + final isolate = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value!; final libRef = serviceConnection.serviceManager.isolateManager .isolateState(isolate) .isolateNow! @@ -168,10 +167,9 @@ class VMServiceObjectNode extends TreeNode { // Clear out the _childrenAsMap map. root._trimChildrenAsMapEntries(); - final processed = - root.children - .map((e) => e._collapseSingleChildDirectoryNodes()) - .toList(); + final processed = root.children + .map((e) => e._collapseSingleChildDirectoryNodes()) + .toList(); root.children.clear(); root.addAllChildren(processed); @@ -185,14 +183,13 @@ class VMServiceObjectNode extends TreeNode { // Place the root library's parent node at the top of the explorer if it's // part of a package. Otherwise, it's a file path and its directory should // appear near the top of the list anyway. - final rootLibUri = - serviceConnection - .serviceManager - .isolateManager - .mainIsolateState - ?.isolateNow - ?.rootLib - ?.uri; + final rootLibUri = serviceConnection + .serviceManager + .isolateManager + .mainIsolateState + ?.isolateNow + ?.rootLib + ?.uri; if (rootLibUri != null) { if (rootLibUri.startsWith('package:') || rootLibUri.startsWith('google3:')) { @@ -301,8 +298,9 @@ class VMServiceObjectNode extends TreeNode { } return this; } - final updated = - children.map((e) => e._collapseSingleChildDirectoryNodes()).toList(); + final updated = children + .map((e) => e._collapseSingleChildDirectoryNodes()) + .toList(); children.clear(); addAllChildren(updated); return this; @@ -344,10 +342,9 @@ class VMServiceObjectNode extends TreeNode { if (scriptRef != null) { final fetchedScript = await scriptManager.getScript(scriptRef); - final position = - tokenPos == 0 - ? null - : SourcePosition.calculatePosition(fetchedScript!, tokenPos!); + final position = tokenPos == 0 + ? null + : SourcePosition.calculatePosition(fetchedScript!, tokenPos!); location = ScriptLocation(scriptRef, location: position); } diff --git a/packages/devtools_app/lib/src/screens/debugger/span_parser.dart b/packages/devtools_app/lib/src/screens/debugger/span_parser.dart index d5f80668b7d..c6d3511458c 100644 --- a/packages/devtools_app/lib/src/screens/debugger/span_parser.dart +++ b/packages/devtools_app/lib/src/screens/debugger/span_parser.dart @@ -165,9 +165,8 @@ class ScopeSpan { /// using the 'includes' keyword. class Repository { Repository.build(Map grammarJson) { - final repositoryJson = - (grammarJson['repository'] as Map?) - ?.cast>(); + final repositoryJson = (grammarJson['repository'] as Map?) + ?.cast>(); if (repositoryJson == null) { return; } @@ -259,9 +258,8 @@ abstract class GrammarMatcher { class _SimpleMatcher extends GrammarMatcher { _SimpleMatcher(super.json) : match = RegExp(json['match'] as String, multiLine: true), - captures = - (json['captures'] as Map?) - ?.cast>(), + captures = (json['captures'] as Map?) + ?.cast>(), super._(); static bool isType(Map json) { @@ -299,21 +297,18 @@ class _MultilineMatcher extends GrammarMatcher { : begin = RegExp(json['begin'] as String, multiLine: true), beginCaptures = json['beginCaptures'] as Map?, contentName = json['contentName'] as String?, - end = - json['end'] == null - ? null - : RegExp(json['end'] as String, multiLine: true), + end = json['end'] == null + ? null + : RegExp(json['end'] as String, multiLine: true), endCaptures = json['endCaptures'] as Map?, captures = json['captures'] as Map?, - whileCond = - json['while'] == null - ? null - : RegExp(json['while'] as String, multiLine: true), - patterns = - (json['patterns'] as List?) - ?.cast>() - .map((e) => GrammarMatcher.fromJson(e)) - .toList(), + whileCond = json['while'] == null + ? null + : RegExp(json['while'] as String, multiLine: true), + patterns = (json['patterns'] as List?) + ?.cast>() + .map((e) => GrammarMatcher.fromJson(e)) + .toList(), super._(); static bool isType(Map json) { @@ -523,11 +518,10 @@ class _MultilineMatcher extends GrammarMatcher { class _PatternMatcher extends GrammarMatcher { _PatternMatcher(super.json) - : patterns = - (json['patterns'] as List?) - ?.cast>() - .map((e) => GrammarMatcher.fromJson(e)) - .toList(), + : patterns = (json['patterns'] as List?) + ?.cast>() + .map((e) => GrammarMatcher.fromJson(e)) + .toList(), super._(); static bool isType(Map json) { diff --git a/packages/devtools_app/lib/src/screens/debugger/variables.dart b/packages/devtools_app/lib/src/screens/debugger/variables.dart index 14a7be86e7a..3c0dde1631e 100644 --- a/packages/devtools_app/lib/src/screens/debugger/variables.dart +++ b/packages/devtools_app/lib/src/screens/debugger/variables.dart @@ -35,9 +35,8 @@ class Variables extends StatelessWidget { } else { return TreeView( dataRootsListenable: serviceConnection.appState.variables, - dataDisplayProvider: - (variable, onPressed) => - DisplayProvider(variable: variable, onTap: onPressed), + dataDisplayProvider: (variable, onPressed) => + DisplayProvider(variable: variable, onTap: onPressed), onItemSelected: onItemPressed, ); } diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart index bcecc8e937d..cb10ad51f2f 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_link_list_view.dart @@ -37,9 +37,8 @@ class _DeepLinkListViewState extends State { @override void initState() { super.initState(); - controller = - screenControllers.lookup() - ..firstLoadWithDefaultConfigurations(); + controller = screenControllers.lookup() + ..firstLoadWithDefaultConfigurations(); } @override @@ -143,23 +142,22 @@ class _ValidatedDeepLinksView extends StatelessWidget { Expanded( child: ValueListenableBuilder( valueListenable: controller.selectedLink, - builder: - (context, _, _) => TabBarView( - children: [ - ValidationDetailView( - controller: controller, - viewType: TableViewType.domainView, - ), - ValidationDetailView( - controller: controller, - viewType: TableViewType.pathView, - ), - ValidationDetailView( - controller: controller, - viewType: TableViewType.singleUrlView, - ), - ], + builder: (context, _, _) => TabBarView( + children: [ + ValidationDetailView( + controller: controller, + viewType: TableViewType.domainView, ), + ValidationDetailView( + controller: controller, + viewType: TableViewType.pathView, + ), + ValidationDetailView( + controller: controller, + viewType: TableViewType.singleUrlView, + ), + ], + ), ), ), ], @@ -268,12 +266,11 @@ class _DeepLinkListViewTopPanel extends StatelessWidget { _ConfigurationDropdown( title: 'iOS Configuration:', valueListenable: controller.selectedIosConfigurationIndex, - configurations: - controller - .selectedProject - .value! - .iosBuildOptions - .configurations, + configurations: controller + .selectedProject + .value! + .iosBuildOptions + .configurations, onChanged: controller.updateSelectedIosConfigurationIndex, ), const SizedBox(width: denseSpacing), @@ -357,10 +354,9 @@ class _AllDeepLinkDataTable extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: denseSpacing), child: SizedBox( - width: - controller.displayOptions.showSplitScreen - ? _kSearchFieldSplitScreenWidth - : _kSearchFieldFullWidth, + width: controller.displayOptions.showSplitScreen + ? _kSearchFieldSplitScreenWidth + : _kSearchFieldFullWidth, child: DevToolsClearableTextField( labelText: '', hintText: 'Search a URL, domain or path', @@ -394,26 +390,25 @@ class _AllDeepLinkDataTable extends StatelessWidget { Expanded( child: ValueListenableBuilder( valueListenable: controller.displayLinkDatasNotifier, - builder: - (context, linkDatas, _) => TabBarView( - children: [ - _DataTable( - viewType: TableViewType.domainView, - linkDatas: linkDatas.byDomain, - controller: controller, - ), - _DataTable( - viewType: TableViewType.pathView, - linkDatas: linkDatas.byPath, - controller: controller, - ), - _DataTable( - viewType: TableViewType.singleUrlView, - linkDatas: linkDatas.all, - controller: controller, - ), - ], + builder: (context, linkDatas, _) => TabBarView( + children: [ + _DataTable( + viewType: TableViewType.domainView, + linkDatas: linkDatas.byDomain, + controller: controller, + ), + _DataTable( + viewType: TableViewType.pathView, + linkDatas: linkDatas.byPath, + controller: controller, ), + _DataTable( + viewType: TableViewType.singleUrlView, + linkDatas: linkDatas.all, + controller: controller, + ), + ], + ), ), ), ], diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart index 4d4ce4dec34..6e51d115fe0 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_controller.dart @@ -324,9 +324,9 @@ class DeepLinksController extends DevToolsScreenController if (selectedProject.value!.androidVariants.isEmpty) { return; } - final variant = - selectedProject.value!.androidVariants[selectedAndroidVariantIndex - .value]; + final variant = selectedProject + .value! + .androidVariants[selectedAndroidVariantIndex.value]; await ga.timeAsync( gac.deeplink, gac.AnalyzeFlutterProject.loadAppLinks.name, @@ -341,8 +341,8 @@ class DeepLinksController extends DevToolsScreenController ga.impression( gac.deeplink, gac.AnalyzeFlutterProject.androidAppLinksSettingsLoaded.name, - screenMetricsProvider: - () => DeepLinkScreenMetrics(androidAppId: result.applicationId), + screenMetricsProvider: () => + DeepLinkScreenMetrics(androidAppId: result.applicationId), ); } catch (_) { ga.select( @@ -378,9 +378,8 @@ class DeepLinksController extends DevToolsScreenController ga.impression( gac.deeplink, gac.AnalyzeFlutterProject.iosUniversalLinkSettingsLoaded.name, - screenMetricsProvider: - () => - DeepLinkScreenMetrics(iosBundleId: result.bundleIdentifier), + screenMetricsProvider: () => + DeepLinkScreenMetrics(iosBundleId: result.bundleIdentifier), ); } catch (_) { pagePhase.value = PagePhase.validationErrorPage; @@ -541,12 +540,11 @@ class DeepLinksController extends DevToolsScreenController } Future> _validateDomain(List rawLinkdatas) async { - final domains = - rawLinkdatas - .where((linkdata) => linkdata.domain != null) - .map((linkdata) => linkdata.domain!) - .toSet() - .toList(); + final domains = rawLinkdatas + .where((linkdata) => linkdata.domain != null) + .map((linkdata) => linkdata.domain!) + .toSet() + .toList(); Map> androidDomainErrors = {}; Map> iosDomainErrors = {}; @@ -556,10 +554,9 @@ class DeepLinksController extends DevToolsScreenController ga.impression( gac.deeplink, gac.AnalyzeFlutterProject.androidValidateDomain.name, - screenMetricsProvider: - () => DeepLinkScreenMetrics( - androidAppId: currentAppLinkSettings!.applicationId, - ), + screenMetricsProvider: () => DeepLinkScreenMetrics( + androidAppId: currentAppLinkSettings!.applicationId, + ), ); final androidResult = await deepLinksService.validateAndroidDomain( domains: domains, @@ -574,10 +571,9 @@ class DeepLinksController extends DevToolsScreenController ga.impression( gac.deeplink, gac.AnalyzeFlutterProject.iosValidateDomain.name, - screenMetricsProvider: - () => DeepLinkScreenMetrics( - iosBundleId: currentUniversalLinkSettings!.bundleIdentifier, - ), + screenMetricsProvider: () => DeepLinkScreenMetrics( + iosBundleId: currentUniversalLinkSettings!.bundleIdentifier, + ), ); final iosResult = await deepLinksService.validateIosDomain( bundleId: bundleId, @@ -702,14 +698,12 @@ class DeepLinksController extends DevToolsScreenController byPath: linkDatasByPath(linkdata), ); displayOptionsNotifier.value = displayOptionsNotifier.value.copyWith( - domainErrorCount: - validatedLinkDatas.byDomain - .where((element) => element.domainErrors.isNotEmpty) - .length, - pathErrorCount: - validatedLinkDatas.byPath - .where((element) => element.pathErrors.isNotEmpty) - .length, + domainErrorCount: validatedLinkDatas.byDomain + .where((element) => element.domainErrors.isNotEmpty) + .length, + pathErrorCount: validatedLinkDatas.byPath + .where((element) => element.pathErrors.isNotEmpty) + .length, ); applyFilters(); @@ -803,38 +797,35 @@ class DeepLinksController extends DevToolsScreenController @visibleForTesting List getFilterredLinks(List linkDatas) { final searchContent = displayOptions.searchContent; - linkDatas = - linkDatas.where((linkData) { - if (searchContent.isNotEmpty && - !linkData.matchesSearchToken( - RegExp(searchContent, caseSensitive: false), - )) { - return false; - } + linkDatas = linkDatas.where((linkData) { + if (searchContent.isNotEmpty && + !linkData.matchesSearchToken( + RegExp(searchContent, caseSensitive: false), + )) { + return false; + } - if (!((linkData.os.contains(PlatformOS.android) && - displayOptions.filters.contains(FilterOption.android)) || - (linkData.os.contains(PlatformOS.ios) && - displayOptions.filters.contains(FilterOption.ios)))) { - return false; - } + if (!((linkData.os.contains(PlatformOS.android) && + displayOptions.filters.contains(FilterOption.android)) || + (linkData.os.contains(PlatformOS.ios) && + displayOptions.filters.contains(FilterOption.ios)))) { + return false; + } - if (!((linkData.domainErrors.isNotEmpty && - displayOptions.filters.contains( - FilterOption.failedDomainCheck, - )) || - (linkData.pathErrors.isNotEmpty && - displayOptions.filters.contains( - FilterOption.failedPathCheck, - )) || - (linkData.domainErrors.isEmpty && - linkData.pathErrors.isEmpty && - displayOptions.filters.contains(FilterOption.noIssue)))) { - return false; - } + if (!((linkData.domainErrors.isNotEmpty && + displayOptions.filters.contains( + FilterOption.failedDomainCheck, + )) || + (linkData.pathErrors.isNotEmpty && + displayOptions.filters.contains(FilterOption.failedPathCheck)) || + (linkData.domainErrors.isEmpty && + linkData.pathErrors.isEmpty && + displayOptions.filters.contains(FilterOption.noIssue)))) { + return false; + } - return true; - }).toList(); + return true; + }).toList(); return linkDatas; } diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_model.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_model.dart index 3085c6de6ad..c5f0f823b75 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_model.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_model.dart @@ -569,9 +569,8 @@ class DomainColumn extends ColumnData children: [ const Text('Domain'), PopupMenuButton( - itemBuilder: - (BuildContext context) => - _buildPopupMenuSortingEntries(controller, isPath: false), + itemBuilder: (BuildContext context) => + _buildPopupMenuSortingEntries(controller, isPath: false), child: Icon(Icons.arrow_drop_down, size: actionsIconSize), ), ], @@ -592,11 +591,11 @@ class DomainColumn extends ColumnData return dataObject.domain == null ? Text('missing domain', style: Theme.of(context).errorTextStyle) : _ErrorAwareText( - isError: dataObject.domainErrors.isNotEmpty, - controller: controller, - text: dataObject.domain!, - link: dataObject, - ); + isError: dataObject.domainErrors.isNotEmpty, + controller: controller, + text: dataObject.domain!, + link: dataObject, + ); } @override @@ -632,9 +631,8 @@ class PathColumn extends ColumnData children: [ const Text('Path'), PopupMenuButton( - itemBuilder: - (BuildContext context) => - _buildPopupMenuSortingEntries(controller, isPath: true), + itemBuilder: (BuildContext context) => + _buildPopupMenuSortingEntries(controller, isPath: true), child: Icon(Icons.arrow_drop_down, size: actionsIconSize), ), ], @@ -908,15 +906,13 @@ PopupMenuEntry _buildPopupMenuFilterEntry( children: [ ValueListenableBuilder( valueListenable: controller.displayOptionsNotifier, - builder: - (context, option, _) => Checkbox( - value: option.filters.contains(filterOption), - onChanged: - (bool? checked) => controller.updateDisplayOptions( - removedFilter: checked! ? null : filterOption, - addedFilter: checked ? filterOption : null, - ), - ), + builder: (context, option, _) => Checkbox( + value: option.filters.contains(filterOption), + onChanged: (bool? checked) => controller.updateDisplayOptions( + removedFilter: checked! ? null : filterOption, + addedFilter: checked ? filterOption : null, + ), + ), ), Text(filterOption.description), ], diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart index 73fa8b818ba..b260c74fe0c 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart @@ -161,17 +161,15 @@ class DeepLinksService { final result = json.decode(response.body) as Map; - final validationResult = - (result[_androidValidationResultKey] as List) - .cast>(); + final validationResult = (result[_androidValidationResultKey] as List) + .cast>(); googlePlayFingerprintsAvailable = result[_googlePlayFingerprintsAvailabilityKey] == _googlePlayFingerprintsAvailableValue; for (final domainResult in validationResult) { final domainName = domainResult[_domainNameKey] as String; - final failedChecks = - (domainResult[_failedChecksKey] as List?) - ?.cast>(); + final failedChecks = (domainResult[_failedChecksKey] as List?) + ?.cast>(); if (failedChecks != null) { for (final failedCheck in failedChecks) { final checkName = failedCheck[_checkNameKey] as String; @@ -214,15 +212,13 @@ class DeepLinksService { }), ); final result = json.decode(response.body) as Map; - final validationResult = - (result[_iosValidationResultsKey] as List) - .cast>(); + final validationResult = (result[_iosValidationResultsKey] as List) + .cast>(); for (final domainResult in validationResult) { if (domainResult[_domainNameKey] case final String domainName) { - final failedChecks = - (domainResult[_failedChecksKey] as List?) - ?.cast>(); + final failedChecks = (domainResult[_failedChecksKey] as List?) + ?.cast>(); if (failedChecks != null) { for (final failedCheck in failedChecks) { final checkName = failedCheck[_checkNameKey] as String; @@ -234,9 +230,8 @@ class DeepLinksService { []; // Adds sub checks for file format error. - final subChecks = - (failedCheck[_subCheckResultsKey] as List?) - ?.cast>(); + final subChecks = (failedCheck[_subCheckResultsKey] as List?) + ?.cast>(); for (final subCheck in (subChecks ?? [])) { final subCheckName = subCheck[_checkNameKey] as String; final subCheckResultType = @@ -264,23 +259,20 @@ class DeepLinksService { } } - final aasaAppPaths = - (domainResult[_aasaAppPathsKey] as List?) - ?.cast>(); + final aasaAppPaths = (domainResult[_aasaAppPathsKey] as List?) + ?.cast>(); if (aasaAppPaths != null) { for (final aasaAppPath in aasaAppPaths) { - final aasaPaths = - (aasaAppPath[_aasaPathsKey] as List?) - ?.cast>(); + final aasaPaths = (aasaAppPath[_aasaPathsKey] as List?) + ?.cast>(); if (aasaPaths != null) { for (final aasaPath in aasaPaths) { final path = aasaPath[_pathKey] as String?; if (path.isNullOrEmpty) { continue; } - final rawQueryParams = - (aasaPath[_queryParamsKey] as List?) - ?.cast>(); + final rawQueryParams = (aasaPath[_queryParamsKey] as List?) + ?.cast>(); final queryParams = { for (final item in rawQueryParams ?? []) item[_keyKey] as String: item[_valueKey] as String, @@ -337,8 +329,8 @@ class DeepLinksService { final errorCode = (result[_errorCodeKey] as String?) ?? ''; String generatedContent = ''; - final domains = - (result[_domainsKey] as List?)?.cast>(); + final domains = (result[_domainsKey] as List?) + ?.cast>(); if (domains != null) { generatedContent = domains.first[_generatedContentKey]! as String; } diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/root_selector.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/root_selector.dart index c25476df4d3..dc76fb8e7ac 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/root_selector.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/root_selector.dart @@ -120,10 +120,9 @@ class _ProjectRootsDropdownState extends State { isExpanded: true, value: selectedUri, items: [for (final uri in widget.projectRoots) _buildMenuItem(uri)], - onChanged: - (uri) => setState(() { - this.selectedUri = uri; - }), + onChanged: (uri) => setState(() { + this.selectedUri = uri; + }), ), ); } @@ -176,7 +175,11 @@ class _FlexibleProjectSelectionView extends StatelessWidget { if (!showButtonInRow) { content = Column( mainAxisSize: MainAxisSize.min, - children: [content, const SizedBox(height: defaultSpacing), button], + children: [ + content, + const SizedBox(height: defaultSpacing), + button, + ], ); } @@ -198,8 +201,9 @@ class _ValidateDeepLinksButton extends StatelessWidget { return DevToolsButton( elevated: true, label: 'Validate deep links', - onPressed: - projectRoot == null ? null : () => onValidatePressed(projectRoot!), + onPressed: projectRoot == null + ? null + : () => onValidatePressed(projectRoot!), ); } } diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart index 3da6e205dba..abd3dd989dc 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/project_root_selection/select_project_view.dart @@ -50,8 +50,8 @@ class _SelectProjectViewState extends State { } Future _validateProject() async { - final packageDirectoryForMainIsolate = - await controller.packageDirectoryForMainIsolate(); + final packageDirectoryForMainIsolate = await controller + .packageDirectoryForMainIsolate(); if (packageDirectoryForMainIsolate != null) { _handleValidateProject(packageDirectoryForMainIsolate); } diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart index b8f0915bb4e..9121769a080 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/validation_details_view.dart @@ -113,8 +113,8 @@ class ValidationDetailHeader extends StatelessWidget { style: Theme.of(context).textTheme.titleMedium, ), IconButton( - onPressed: - () => controller.updateDisplayOptions(showSplitScreen: false), + onPressed: () => + controller.updateDisplayOptions(showSplitScreen: false), icon: const Icon(Icons.close), ), ], @@ -178,18 +178,18 @@ class _DomainCheckTable extends StatelessWidget { for (final error in linkData.domainErrors.whereType()) _IssuesBorderWrap( - children: - error == IosDomainError.existence - ? [ - _FailureDetails( - errors: [error], - oneFixGuideForAll: - 'To fix this issue, add an Apple-App-Site-Association file at the following location: ' - 'https://${controller.selectedLink.value!.domain}/.well-known/apple-app-site-association', - ), - const SizedBox(height: denseSpacing), - _CodeCard( - content: '''{ + children: error == IosDomainError.existence + ? [ + _FailureDetails( + errors: [error], + oneFixGuideForAll: + 'To fix this issue, add an Apple-App-Site-Association file at the following location: ' + 'https://${controller.selectedLink.value!.domain}/.well-known/apple-app-site-association', + ), + const SizedBox(height: denseSpacing), + _CodeCard( + content: + '''{ "applinks": { "details": [ { @@ -205,13 +205,13 @@ class _DomainCheckTable extends StatelessWidget { ] } }''', - ), - ] - : [ - _FailureDetails( - errors: [error, ...error.subcheckErrors], - ), - ], + ), + ] + : [ + _FailureDetails( + errors: [error, ...error.subcheckErrors], + ), + ], ), ], ), @@ -232,10 +232,9 @@ class _AssetLinksJsonFileIssues extends StatelessWidget { @override Widget build(BuildContext context) { - final errors = - controller.selectedLink.value!.domainErrors - .where((error) => domainAssetLinksJsonFileErrors.contains(error)) - .toList(); + final errors = controller.selectedLink.value!.domainErrors + .where((error) => domainAssetLinksJsonFileErrors.contains(error)) + .toList(); return ExpansionTile( controlAffinity: ListTileControlAffinity.leading, title: _VerifiedOrErrorText( @@ -271,10 +270,9 @@ class _HostingIssues extends StatelessWidget { @override Widget build(BuildContext context) { - final errors = - controller.selectedLink.value!.domainErrors - .where((error) => domainAndroidHostingErrors.contains(error)) - .toList(); + final errors = controller.selectedLink.value!.domainErrors + .where((error) => domainAndroidHostingErrors.contains(error)) + .toList(); return ExpansionTile( controlAffinity: ListTileControlAffinity.leading, title: _VerifiedOrErrorText( @@ -369,38 +367,38 @@ class _LocalFingerprint extends StatelessWidget { const SizedBox(height: intermediateSpacing), controller.localFingerprint.value == null ? TextField( - decoration: const InputDecoration( - labelText: 'Enter your local fingerprint', - hintText: - 'eg: A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4', - filled: true, - ), - onSubmitted: (fingerprint) async { - final validFingerprintAdded = controller.addLocalFingerprint( - fingerprint, - ); - - if (!validFingerprintAdded) { - await showDialog( - context: context, - builder: (_) { - return const DevToolsDialog( - title: Text('This is not a valid fingerprint'), - content: Text( - 'A valid fingerprint consists of 32 pairs of hexadecimal digits separated by colons.' - 'It should be the same encoding and format as in the assetlinks.json', - ), - actions: [DialogCloseButton()], - ); - }, + decoration: const InputDecoration( + labelText: 'Enter your local fingerprint', + hintText: + 'eg: A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4:A1:B2:C3:D4', + filled: true, + ), + onSubmitted: (fingerprint) async { + final validFingerprintAdded = controller.addLocalFingerprint( + fingerprint, ); - } - }, - ) + + if (!validFingerprintAdded) { + await showDialog( + context: context, + builder: (_) { + return const DevToolsDialog( + title: Text('This is not a valid fingerprint'), + content: Text( + 'A valid fingerprint consists of 32 pairs of hexadecimal digits separated by colons.' + 'It should be the same encoding and format as in the assetlinks.json', + ), + actions: [DialogCloseButton()], + ); + }, + ); + } + }, + ) : _CodeCard( - content: controller.localFingerprint.value, - hasCopyAction: false, - ), + content: controller.localFingerprint.value, + hasCopyAction: false, + ), ], ); } @@ -440,18 +438,17 @@ class _CodeCard extends StatelessWidget { elevation: 0.0, child: Padding( padding: const EdgeInsets.all(denseSpacing), - child: - content != null - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Flexible(child: SelectionArea(child: Text(content!))), - if (hasCopyAction) - CopyToClipboardControl(dataProvider: () => content), - ], - ) - : const CenteredCircularProgressIndicator(), + child: content != null + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Flexible(child: SelectionArea(child: Text(content!))), + if (hasCopyAction) + CopyToClipboardControl(dataProvider: () => content), + ], + ) + : const CenteredCircularProgressIndicator(), ), ); } @@ -471,9 +468,9 @@ class _GenerateAssetLinksPanel extends StatelessWidget { return (generatedAssetLinks != null && generatedAssetLinks.errorCode.isNotEmpty) ? Text( - 'Not able to generate assetlinks.json, because the app ${controller.applicationId} is not uploaded to Google Play.', - style: theme.subtleTextStyle, - ) + 'Not able to generate assetlinks.json, because the app ${controller.applicationId} is not uploaded to Google Play.', + style: theme.subtleTextStyle, + ) : _CodeCard(content: generatedAssetLinks?.generatedString); }, ); @@ -534,28 +531,27 @@ class _DomainAssociatedLinksPanel extends StatelessWidget { padding: const EdgeInsets.all(denseSpacing), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: - linkData.associatedPath - .map( - (path) => Padding( - padding: const EdgeInsets.symmetric( - vertical: denseRowSpacing, - ), - child: Row( - children: [ - if (linkData.domainErrors.isNotEmpty) - Icon( - Icons.error, - color: theme.colorScheme.error, - size: defaultIconSize, - ), - const SizedBox(width: denseSpacing), - Text('${linkData.domain}$path'), - ], - ), - ), - ) - .toList(), + children: linkData.associatedPath + .map( + (path) => Padding( + padding: const EdgeInsets.symmetric( + vertical: denseRowSpacing, + ), + child: Row( + children: [ + if (linkData.domainErrors.isNotEmpty) + Icon( + Icons.error, + color: theme.colorScheme.error, + size: defaultIconSize, + ), + const SizedBox(width: denseSpacing), + Text('${linkData.domain}$path'), + ], + ), + ), + ) + .toList(), ), ), ), @@ -670,10 +666,9 @@ class _ManifestFileCheck extends StatelessWidget { @override Widget build(BuildContext context) { final linkData = controller.selectedLink.value!; - final errors = - manifestFileErrors - .where((error) => linkData.pathErrors.contains(error)) - .toList(); + final errors = manifestFileErrors + .where((error) => linkData.pathErrors.contains(error)) + .toList(); return _CheckExpansionTile( os: PlatformOS.android, @@ -836,9 +831,9 @@ class _CheckStatusText extends StatelessWidget { return hasError ? Text('Check failed', style: theme.errorTextStyle) : Text( - 'No issues found', - style: TextStyle(color: theme.colorScheme.green), - ); + 'No issues found', + style: TextStyle(color: theme.colorScheme.green), + ); } } @@ -853,15 +848,15 @@ class _VerifiedOrErrorText extends StatelessWidget { children: [ isError ? Icon( - Icons.error, - color: Theme.of(context).colorScheme.error, - size: defaultIconSize, - ) + Icons.error, + color: Theme.of(context).colorScheme.error, + size: defaultIconSize, + ) : Icon( - Icons.verified, - color: Theme.of(context).colorScheme.green, - size: defaultIconSize, - ), + Icons.verified, + color: Theme.of(context).colorScheme.green, + size: defaultIconSize, + ), const SizedBox(width: denseSpacing), Text(text), ], diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_breadcrumbs.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_breadcrumbs.dart index 9830363d5b5..9beabcf1732 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_breadcrumbs.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_breadcrumbs.dart @@ -37,19 +37,18 @@ class InspectorBreadcrumbNavigator extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 6), child: Row( - children: - breadcrumbs.map((item) { - if (item.isChevron) { - return Icon(Icons.chevron_right, size: defaultIconSize); - } - - return Flexible( - child: _InspectorBreadcrumb( - data: item, - onTap: () => onTap(item.node), - ), - ); - }).toList(), + children: breadcrumbs.map((item) { + if (item.isChevron) { + return Icon(Icons.chevron_right, size: defaultIconSize); + } + + return Flexible( + child: _InspectorBreadcrumb( + data: item, + onTap: () => onTap(item.node), + ), + ); + }).toList(), ), ), ); @@ -59,25 +58,23 @@ class InspectorBreadcrumbNavigator extends StatelessWidget { List nodes, ) { final lastNode = nodes.safeLast; - final items = - nodes.map((node) { - return _InspectorBreadcrumbData.wrap( - node: node, - isSelected: node == lastNode, - ); - }).toList(); + final items = nodes.map((node) { + return _InspectorBreadcrumbData.wrap( + node: node, + isSelected: node == lastNode, + ); + }).toList(); List<_InspectorBreadcrumbData> breadcrumbs; - breadcrumbs = - items.length > _maxNumberOfBreadcrumbs - ? [ - items[0], - _InspectorBreadcrumbData.more(), - ...items.sublist( - items.length - _maxNumberOfBreadcrumbs + 1, - items.length, - ), - ] - : items; + breadcrumbs = items.length > _maxNumberOfBreadcrumbs + ? [ + items[0], + _InspectorBreadcrumbData.more(), + ...items.sublist( + items.length - _maxNumberOfBreadcrumbs + 1, + items.length, + ), + ] + : items; return breadcrumbs.joinWith(_InspectorBreadcrumbData.chevron()); } @@ -102,16 +99,15 @@ class _InspectorBreadcrumb extends StatelessWidget { ).copyWith(fontSize: scaleByFontFactor(11)), ); - final icon = - data.icon == null - ? null - : Transform.scale( - scale: _iconScale, - child: Padding( - padding: const EdgeInsets.only(right: iconPadding), - child: data.icon, - ), - ); + final icon = data.icon == null + ? null + : Transform.scale( + scale: _iconScale, + child: Padding( + padding: const EdgeInsets.only(right: iconPadding), + child: data.icon, + ), + ); return InkWell( onTap: data.isClickable ? onTap : null, @@ -123,14 +119,16 @@ class _InspectorBreadcrumb extends StatelessWidget { ), decoration: BoxDecoration( borderRadius: defaultBorderRadius, - color: - data.isSelected - ? Theme.of(context).colorScheme.selectedRowBackgroundColor - : Colors.transparent, + color: data.isSelected + ? Theme.of(context).colorScheme.selectedRowBackgroundColor + : Colors.transparent, ), child: Row( mainAxisSize: MainAxisSize.min, - children: [if (icon != null) icon, Flexible(child: text)], + children: [ + if (icon != null) icon, + Flexible(child: text), + ], ), ), ); diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart index 2716ef3393e..9ddc8196e90 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart @@ -64,15 +64,14 @@ class InspectorController extends DisposableController onExpand: _onExpand, onClientActiveChange: _onClientChange, ); - details = - isSummaryTree - ? InspectorController( - inspectorTree: detailsTree!, - treeType: treeType, - parent: this, - isSummaryTree: false, - ) - : null; + details = isSummaryTree + ? InspectorController( + inspectorTree: detailsTree!, + treeType: treeType, + parent: this, + isSummaryTree: false, + ) + : null; await serviceConnection.serviceManager.onServiceAvailable; @@ -425,8 +424,8 @@ class InspectorController extends DisposableController } else { if (disposed) return; if (inspectorService is InspectorService) { - final widgetTreeReady = - await (inspectorService as InspectorService).isWidgetTreeReady(); + final widgetTreeReady = await (inspectorService as InspectorService) + .isWidgetTreeReady(); flutterAppFrameReady = widgetTreeReady; } if (isActive && flutterAppFrameReady) { @@ -450,10 +449,9 @@ class InspectorController extends DisposableController treeGroups.cancelNext(); try { final group = treeGroups.next; - final node = - await (detailsSubtree - ? group.getDetailsSubtree(subtreeRoot, subtreeDepth: subtreeDepth) - : group.getRoot(treeType, isSummaryTree: true)); + final node = await (detailsSubtree + ? group.getDetailsSubtree(subtreeRoot, subtreeDepth: subtreeDepth) + : group.getRoot(treeType, isSummaryTree: true)); if (node == null || group.disposed || disposed) { return; } @@ -644,8 +642,9 @@ class InspectorController extends DisposableController restrictToLocalProject: isSummaryTree, ); - final pendingDetailsFuture = - isSummaryTree ? group.getSelection(selectedDiagnostic, treeType) : null; + final pendingDetailsFuture = isSummaryTree + ? group.getSelection(selectedDiagnostic, treeType) + : null; try { final newSelection = await pendingSelectionFuture; @@ -736,17 +735,15 @@ class InspectorController extends DisposableController void _updateSelectedErrorFromNode(InspectorTreeNode? node) { final inspectorRef = node?.diagnostic?.valueRef.id; - final errors = - serviceConnection.errorBadgeManager - .erroredItemsForPage(InspectorScreen.id) - .value; + final errors = serviceConnection.errorBadgeManager + .erroredItemsForPage(InspectorScreen.id) + .value; // Check whether the node that was just selected has any errors associated // with it. - var errorIndex = - inspectorRef != null - ? errors.keys.toList().indexOf(inspectorRef) - : null; + var errorIndex = inspectorRef != null + ? errors.keys.toList().indexOf(inspectorRef) + : null; if (errorIndex == -1) { errorIndex = null; } @@ -772,10 +769,9 @@ class InspectorController extends DisposableController void selectErrorByIndex(int index) { _selectedErrorIndex.value = index; - final errors = - serviceConnection.errorBadgeManager - .erroredItemsForPage(InspectorScreen.id) - .value; + final errors = serviceConnection.errorBadgeManager + .erroredItemsForPage(InspectorScreen.id) + .value; unawaited( updateSelectionFromService( diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_data_models.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_data_models.dart index 4d52c286f5c..a12ed91f76e 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_data_models.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_data_models.dart @@ -111,15 +111,13 @@ class LayoutProperties { isFlex = node.isFlex, flexFactor = node.flexFactor, flexFit = node.flexFit, - children = - copyLevel == 0 - ? [] - : node.childrenNow - .map( - (child) => - LayoutProperties(child, copyLevel: copyLevel - 1), - ) - .toList(growable: false) { + children = copyLevel == 0 + ? [] + : node.childrenNow + .map( + (child) => LayoutProperties(child, copyLevel: copyLevel - 1), + ) + .toList(growable: false) { for (final child in children) { child.parent = this; } @@ -182,10 +180,10 @@ class LayoutProperties { if (constraintsLocal == null) return ''; return constraintsLocal.hasBoundedWidth ? describeAxis( - constraintsLocal.minWidth, - constraintsLocal.maxWidth, - 'w', - ) + constraintsLocal.minWidth, + constraintsLocal.maxWidth, + 'w', + ) : 'width is unconstrained'; } @@ -194,10 +192,10 @@ class LayoutProperties { if (constraintsLocal == null) return ''; return constraintsLocal.hasBoundedHeight ? describeAxis( - constraintsLocal.minHeight, - constraintsLocal.maxHeight, - 'h', - ) + constraintsLocal.minHeight, + constraintsLocal.maxHeight, + 'h', + ) : 'height is unconstrained'; } @@ -365,9 +363,8 @@ class FlexLayoutProperties extends LayoutProperties { static FlexLayoutProperties _buildNode(RemoteDiagnosticsNode node) { final renderObjectJson = node.renderObject!.json; - final properties = - (renderObjectJson['properties'] as List) - .cast>(); + final properties = (renderObjectJson['properties'] as List) + .cast>(); final data = { for (final property in properties) @@ -406,8 +403,9 @@ class FlexLayoutProperties extends LayoutProperties { List get displayChildren { final displayChildren = _displayChildren; if (displayChildren != null) return displayChildren; - return _displayChildren = - startIsTopLeft ? children : children.reversed.toList(); + return _displayChildren = startIsTopLeft + ? children + : children.reversed.toList(); } int? _totalFlex; @@ -428,11 +426,10 @@ class FlexLayoutProperties extends LayoutProperties { num get totalFlex { if (children.isEmpty) return 0; - _totalFlex ??= - children - .map((child) => child.flexFactor ?? 0) - .reduce((value, element) => value + element) - .toInt(); + _totalFlex ??= children + .map((child) => child.flexFactor ?? 0) + .reduce((value, element) => value + element) + .toInt(); return _totalFlex!; } @@ -490,8 +487,9 @@ class FlexLayoutProperties extends LayoutProperties { }) { /// calculate the render empty spaces final freeSpace = dimension(direction) - sum(childrenDimensions(direction)); - final displayMainAxisAlignment = - startIsTopLeft ? mainAxisAlignment : mainAxisAlignment?.reversed; + final displayMainAxisAlignment = startIsTopLeft + ? mainAxisAlignment + : mainAxisAlignment?.reversed; double leadingSpace(double freeSpace) { if (children.isEmpty) return 0.0; @@ -539,8 +537,9 @@ class FlexLayoutProperties extends LayoutProperties { } double largestRenderSize(Axis axis) { - final lrs = - axis == Axis.horizontal ? largestRenderWidth : largestRenderHeight; + final lrs = axis == Axis.horizontal + ? largestRenderWidth + : largestRenderHeight; // use all the space when visualizing cross axis return (axis == direction) ? lrs : maxSizeAvailable(axis); } @@ -566,12 +565,11 @@ class FlexLayoutProperties extends LayoutProperties { ); } else { // uniform cross axis sizes. - double size = - crossAxisAlignment == CrossAxisAlignment.stretch - ? maxSizeAvailable(axis) - : largestSize / - math.max(dimension(axis), 1.0) * - maxSizeAvailable(axis); + double size = crossAxisAlignment == CrossAxisAlignment.stretch + ? maxSizeAvailable(axis) + : largestSize / + math.max(dimension(axis), 1.0) * + maxSizeAvailable(axis); size = math.max(size, smallestRenderSize(axis)); return sizes.map((_) => size).toList(); } @@ -580,10 +578,9 @@ class FlexLayoutProperties extends LayoutProperties { final widths = renderSizes(Axis.horizontal); final heights = renderSizes(Axis.vertical); - final renderFreeSpace = - freeSpace > 0.0 - ? (isMainAxisHorizontal ? widths.last : heights.last) - : 0.0; + final renderFreeSpace = freeSpace > 0.0 + ? (isMainAxisHorizontal ? widths.last : heights.last) + : 0.0; final renderLeadingSpace = leadingSpace(renderFreeSpace); final renderBetweenSpace = betweenSpace(renderFreeSpace); @@ -614,8 +611,9 @@ class FlexLayoutProperties extends LayoutProperties { double calculateCrossAxisOffset(int i) { final maxDimension = maxSizeAvailable(crossAxisDirection); - final usedDimension = - crossAxisDirection == Axis.horizontal ? widths[i] : heights[i]; + final usedDimension = crossAxisDirection == Axis.horizontal + ? widths[i] + : heights[i]; if (crossAxisAlignment == CrossAxisAlignment.start || crossAxisAlignment == CrossAxisAlignment.stretch || @@ -721,10 +719,9 @@ class FlexLayoutProperties extends LayoutProperties { renderProperties.crossAxisOffset, ); } else { - space.crossAxisOffset = - crossAxisAlignment == CrossAxisAlignment.end - ? 0 - : renderProperties.crossAxisDimension; + space.crossAxisOffset = crossAxisAlignment == CrossAxisAlignment.end + ? 0 + : renderProperties.crossAxisDimension; spaces.add(space); } } @@ -732,14 +729,14 @@ class FlexLayoutProperties extends LayoutProperties { } static final _directionNamesToValues = Axis.values.asNameMap(); - static final _mainAxisAlignmentNamesToValues = - MainAxisAlignment.values.asNameMap(); + static final _mainAxisAlignmentNamesToValues = MainAxisAlignment.values + .asNameMap(); static final _mainAxisSizeNamesToValues = MainAxisSize.values.asNameMap(); - static final _crossAxisAlignmentNamesToValues = - CrossAxisAlignment.values.asNameMap(); + static final _crossAxisAlignmentNamesToValues = CrossAxisAlignment.values + .asNameMap(); static final _textDirectionNamesToValues = TextDirection.values.asNameMap(); - static final _verticalDirectionNamesToValues = - VerticalDirection.values.asNameMap(); + static final _verticalDirectionNamesToValues = VerticalDirection.values + .asNameMap(); static final _textBaselineNamesToValues = TextBaseline.values.asNameMap(); } diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart index d46b311a94f..bfcb72dbcdb 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_screen_body.dart @@ -154,8 +154,8 @@ class InspectorScreenBodyState extends State constraints: constraints, onRefreshInspectorPressed: _refreshInspector, onSearchVisibleToggle: _onSearchVisibleToggle, - searchFieldBuilder: - () => StatelessSearchField( + searchFieldBuilder: () => + StatelessSearchField( controller: _summaryTreeController, searchFieldEnabled: true, shouldRequestFocus: searchVisible, @@ -189,17 +189,15 @@ class InspectorScreenBodyState extends State if (errors.isNotEmpty) ValueListenableBuilder( valueListenable: controller.selectedErrorIndex, - builder: - (_, selectedErrorIndex, _) => Positioned( - top: 0, - right: 0, - child: ErrorNavigator( - errors: inspectableErrors, - errorIndex: selectedErrorIndex, - onSelectError: - controller.selectErrorByIndex, - ), - ), + builder: (_, selectedErrorIndex, _) => Positioned( + top: 0, + right: 0, + child: ErrorNavigator( + errors: inspectableErrors, + errorIndex: selectedErrorIndex, + onSelectError: controller.selectErrorByIndex, + ), + ), ), ], ); @@ -315,18 +313,18 @@ class InspectorSummaryTreeControls extends StatelessWidget { ), ...!isSearchVisible ? [ - const Spacer(), - ToolbarAction( - icon: Icons.search, - onPressed: onSearchVisibleToggle, - tooltip: 'Search Tree', - ), - ] + const Spacer(), + ToolbarAction( + icon: Icons.search, + onPressed: onSearchVisibleToggle, + tooltip: 'Search Tree', + ), + ] : [ - constraints.maxWidth >= _searchBreakpoint - ? _buildSearchControls() - : const Spacer(), - ], + constraints.maxWidth >= _searchBreakpoint + ? _buildSearchControls() + : const Spacer(), + ], ToolbarAction( icon: Icons.refresh, onPressed: onRefreshInspectorPressed, @@ -378,10 +376,9 @@ class ErrorNavigator extends StatelessWidget { @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; - final label = - errorIndex != null - ? 'Error ${errorIndex! + 1}/${errors.length}' - : 'Errors: ${errors.length}'; + final label = errorIndex != null + ? 'Error ${errorIndex! + 1}/${errors.length}' + : 'Errors: ${errors.length}'; return Container( color: colorScheme.errorContainer, child: Padding( diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart index 3d39d484cf5..ebdcd9661b3 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart @@ -127,12 +127,11 @@ class InspectorTreeController extends DisposableController gac.inspector, gac.inspectorTreeControllerInitialized, nonInteraction: true, - screenMetricsProvider: - () => InspectorScreenMetrics.legacy( - inspectorTreeControllerId: gaId, - rootSetCount: _rootSetCount, - rowCount: _root?.subtreeSize, - ), + screenMetricsProvider: () => InspectorScreenMetrics.legacy( + inspectorTreeControllerId: gaId, + rootSetCount: _rootSetCount, + rowCount: _root?.subtreeSize, + ), ); } @@ -179,12 +178,11 @@ class InspectorTreeController extends DisposableController gac.inspector, gac.inspectorTreeControllerRootChange, nonInteraction: true, - screenMetricsProvider: - () => InspectorScreenMetrics.legacy( - inspectorTreeControllerId: gaId, - rootSetCount: ++_rootSetCount, - rowCount: _root?.subtreeSize, - ), + screenMetricsProvider: () => InspectorScreenMetrics.legacy( + inspectorTreeControllerId: gaId, + rootSetCount: ++_rootSetCount, + rowCount: _root?.subtreeSize, + ), ); }); } @@ -349,15 +347,14 @@ class InspectorTreeController extends DisposableController final rootLocal = root!; - selection = - rootLocal - .getRow( - (rootLocal.getRowIndex(selection!) + indexOffset).clamp( - 0, - numRows - 1, - ), - ) - ?.node; + selection = rootLocal + .getRow( + (rootLocal.getRowIndex(selection!) + indexOffset).clamp( + 0, + numRows - 1, + ), + ) + ?.node; } double get horizontalPadding => 10.0; @@ -517,8 +514,9 @@ class InspectorTreeController extends DisposableController final row = getRowForNode(target); if (row != null) { final rowRect = getBoundingBox(row); - targetRect = - targetRect == null ? rowRect : targetRect.expandToInclude(rowRect); + targetRect = targetRect == null + ? rowRect + : targetRect.expandToInclude(rowRect); } } @@ -872,14 +870,12 @@ class _InspectorTreeState extends State final initialX = rect.left; final initialY = rect.top; - final yOffsetAtViewportTop = - _scrollControllerY.hasClients - ? _scrollControllerY.offset - : _scrollControllerY.initialScrollOffset; - final xOffsetAtViewportLeft = - _scrollControllerX.hasClients - ? _scrollControllerX.offset - : _scrollControllerX.initialScrollOffset; + final yOffsetAtViewportTop = _scrollControllerY.hasClients + ? _scrollControllerY.offset + : _scrollControllerY.initialScrollOffset; + final xOffsetAtViewportLeft = _scrollControllerX.hasClients + ? _scrollControllerX.offset + : _scrollControllerX.initialScrollOffset; final viewPortInScrollControllerSpace = Rect.fromLTWH( xOffsetAtViewportLeft, @@ -1017,10 +1013,9 @@ class _InspectorTreeState extends State ga.timeEnd( screenId, gac.pageReady, - screenMetricsProvider: - () => InspectorScreenMetrics.legacy( - rowCount: treeControllerLocal.numRows, - ), + screenMetricsProvider: () => InspectorScreenMetrics.legacy( + rowCount: treeControllerLocal.numRows, + ), ); unawaited( serviceConnection.sendDwdsEvent( @@ -1081,9 +1076,9 @@ class _InspectorTreeState extends State viewportWidth: viewportWidth, error: widget.widgetErrors != null && - inspectorRef != null - ? widget.widgetErrors![inspectorRef] - : null, + inspectorRef != null + ? widget.widgetErrors![inspectorRef] + : null, ); }, childCount: treeControllerLocal.numRows + 1), controller: _scrollControllerY, @@ -1099,8 +1094,8 @@ class _InspectorTreeState extends State if (shouldShowBreadcrumbs) { final inspectorTreeController = widget.summaryTreeController!; - final parents = - inspectorTreeController.getPathFromSelectedRowToRoot(); + final parents = inspectorTreeController + .getPathFromSelectedRowToRoot(); return Column( children: [ InspectorBreadcrumbNavigator( @@ -1121,10 +1116,9 @@ class _InspectorTreeState extends State bool get wantKeepAlive => true; } -Paint _defaultPaint(ColorScheme colorScheme) => - Paint() - ..color = colorScheme.treeGuidelineColor - ..strokeWidth = chartLineStrokeWidth; +Paint _defaultPaint(ColorScheme colorScheme) => Paint() + ..color = colorScheme.treeGuidelineColor + ..strokeWidth = chartLineStrokeWidth; /// Custom painter that draws lines indicating how parent and child rows are /// connected to each other. @@ -1165,10 +1159,9 @@ class _RowPainter extends CustomPainter { currentX = _controller.getDepthIndent(row.depth - 1) - inspectorColumnWidth * 0.5; - final width = - showExpandCollapse - ? inspectorColumnWidth * 0.5 - : inspectorColumnWidth; + final width = showExpandCollapse + ? inspectorColumnWidth * 0.5 + : inspectorColumnWidth; canvas.drawLine( Offset(currentX, 0.0), Offset(currentX, inspectorRowHeight * 0.5), @@ -1237,10 +1230,9 @@ class InspectorRowContent extends StatelessWidget { Color? backgroundColor; if (row.isSelected) { - backgroundColor = - hasError - ? colorScheme.errorContainer - : colorScheme.selectedRowBackgroundColor; + backgroundColor = hasError + ? colorScheme.errorContainer + : colorScheme.selectedRowBackgroundColor; } final node = row.node; @@ -1257,16 +1249,16 @@ class InspectorRowContent extends StatelessWidget { children: [ node.showExpandCollapse ? InkWell( - onTap: onToggle, - child: RotationTransition( - turns: expandArrowAnimation, - child: Icon(Icons.expand_more, size: defaultIconSize), - ), - ) + onTap: onToggle, + child: RotationTransition( + turns: expandArrowAnimation, + child: Icon(Icons.expand_more, size: defaultIconSize), + ), + ) : const SizedBox( - width: defaultSpacing, - height: defaultSpacing, - ), + width: defaultSpacing, + height: defaultSpacing, + ), Expanded( child: Container( color: backgroundColor, @@ -1287,12 +1279,12 @@ class InspectorRowContent extends StatelessWidget { errorText: error?.errorMessage, nodeDescriptionHighlightStyle: searchValue.isEmpty || !row.isSearchMatch - ? DiagnosticsTextStyles.regular( - Theme.of(context).colorScheme, - ) - : row.isSelected - ? theme.searchMatchHighlightStyleFocused - : theme.searchMatchHighlightStyle, + ? DiagnosticsTextStyles.regular( + Theme.of(context).colorScheme, + ) + : row.isSelected + ? theme.searchMatchHighlightStyleFocused + : theme.searchMatchHighlightStyle, ), ), ), diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/box/box.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/box/box.dart index 4908dc2ad04..ff579921994 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/box/box.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/box/box.dart @@ -77,10 +77,9 @@ class BoxLayoutExplorerWidgetState setState(() { // This implementation will need to change if we support showing more than // a single widget in the box visualization for the layout explorer. - highlighted = - newProperties != null && selectedNode == newProperties.node - ? newProperties - : null; + highlighted = newProperties != null && selectedNode == newProperties.node + ? newProperties + : null; }); } @@ -225,8 +224,9 @@ class BoxLayoutExplorerWidgetState height: constraints.maxHeight, decoration: BoxDecoration( border: Border.all( - color: - WidgetTheme.fromName(propertiesLocal.node.description).color, + color: WidgetTheme.fromName( + propertiesLocal.node.description, + ).color, ), ), child: Stack( diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart index 4980a444237..df439c0fd5d 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/flex.dart @@ -55,23 +55,22 @@ class FlexLayoutExplorerWidgetState Color horizontalColor(ColorScheme colorScheme) => properties!.isMainAxisHorizontal - ? colorScheme.mainAxisColor - : colorScheme.crossAxisColor; + ? colorScheme.mainAxisColor + : colorScheme.crossAxisColor; - Color verticalColor(ColorScheme colorScheme) => - properties!.isMainAxisVertical - ? colorScheme.mainAxisColor - : colorScheme.crossAxisColor; + Color verticalColor(ColorScheme colorScheme) => properties!.isMainAxisVertical + ? colorScheme.mainAxisColor + : colorScheme.crossAxisColor; Color horizontalTextColor(ColorScheme colorScheme) => properties!.isMainAxisHorizontal - ? colorScheme.mainAxisTextColor - : colorScheme.crossAxisTextColor; + ? colorScheme.mainAxisTextColor + : colorScheme.crossAxisTextColor; Color verticalTextColor(ColorScheme colorScheme) => properties!.isMainAxisVertical - ? colorScheme.mainAxisTextColor - : colorScheme.crossAxisTextColor; + ? colorScheme.mainAxisTextColor + : colorScheme.crossAxisTextColor; String get flexType => properties!.type; @@ -122,10 +121,9 @@ class FlexLayoutExplorerWidgetState Widget _buildAxisAlignmentDropdown(Axis axis, ThemeData theme) { final colorScheme = theme.colorScheme; - final color = - axis == direction - ? colorScheme.mainAxisTextColor - : colorScheme.crossAxisTextColor; + final color = axis == direction + ? colorScheme.mainAxisTextColor + : colorScheme.crossAxisTextColor; List alignmentEnumEntries; Object? selected; final propertiesLocal = properties!; @@ -153,10 +151,9 @@ class FlexLayoutExplorerWidgetState isExpanded: true, // Avoid showing an underline for the main axis and cross-axis drop downs. underline: const SizedBox(), - iconEnabledColor: - axis == propertiesLocal.direction - ? colorScheme.mainAxisColor - : colorScheme.crossAxisColor, + iconEnabledColor: axis == propertiesLocal.direction + ? colorScheme.mainAxisColor + : colorScheme.crossAxisColor, selectedItemBuilder: (context) { return [ for (final alignment in alignmentEnumEntries) @@ -177,13 +174,13 @@ class FlexLayoutExplorerWidgetState child: Image.asset( (axis == direction) ? mainAxisAssetImageUrl( - direction, - alignment as MainAxisAlignment, - ) + direction, + alignment as MainAxisAlignment, + ) : crossAxisAssetImageUrl( - direction, - alignment as CrossAxisAlignment, - ), + direction, + alignment as CrossAxisAlignment, + ), height: axisAlignmentAssetImageHeight, fit: BoxFit.fitHeight, color: color, @@ -216,13 +213,13 @@ class FlexLayoutExplorerWidgetState child: Image.asset( (axis == direction) ? mainAxisAssetImageUrl( - direction, - alignment as MainAxisAlignment, - ) + direction, + alignment as MainAxisAlignment, + ) : crossAxisAssetImageUrl( - direction, - alignment as CrossAxisAlignment, - ), + direction, + alignment as CrossAxisAlignment, + ), fit: BoxFit.fitHeight, color: color, ), @@ -238,14 +235,13 @@ class FlexLayoutExplorerWidgetState // if the axis is the main axis the type should be [MainAxisAlignment] // if the axis is the cross axis the type should be [CrossAxisAlignment] FlexLayoutProperties changedProperties; - changedProperties = - axis == direction - ? propertiesLocal.copyWith( - mainAxisAlignment: newSelection as MainAxisAlignment?, - ) - : propertiesLocal.copyWith( - crossAxisAlignment: newSelection as CrossAxisAlignment?, - ); + changedProperties = axis == direction + ? propertiesLocal.copyWith( + mainAxisAlignment: newSelection as MainAxisAlignment?, + ) + : propertiesLocal.copyWith( + crossAxisAlignment: newSelection as CrossAxisAlignment?, + ); final valueRef = propertiesLocal.node.valueRef; markAsDirty(); await objectGroup!.invokeSetFlexProperties( @@ -429,8 +425,8 @@ class _VisualizeFlexChildrenState extends State { lastHighlighted = widget.highlighted; if (widget.highlighted != null) { WidgetsBinding.instance.addPostFrameCallback((_) { - final selectedRenderObject = - selectedChildKey.currentContext?.findRenderObject(); + final selectedRenderObject = selectedChildKey.currentContext + ?.findRenderObject(); if (selectedRenderObject != null && widget.scrollController.hasClients) { unawaited( @@ -475,14 +471,12 @@ class _VisualizeFlexChildrenState extends State { maxSizeAvailable: maxSizeAvailable, ); - final renderProperties = - childrenAndMainAxisSpacesRenderProps - .where((renderProps) => !renderProps.isFreeSpace) - .toList(); - final mainAxisSpaces = - childrenAndMainAxisSpacesRenderProps - .where((renderProps) => renderProps.isFreeSpace) - .toList(); + final renderProperties = childrenAndMainAxisSpacesRenderProps + .where((renderProps) => !renderProps.isFreeSpace) + .toList(); + final mainAxisSpaces = childrenAndMainAxisSpacesRenderProps + .where((renderProps) => renderProps.isFreeSpace) + .toList(); final crossAxisSpaces = widget.properties.crossAxisSpaces( childrenRenderProperties: renderProperties, maxSizeAvailable: maxSizeAvailable, @@ -528,27 +522,24 @@ class _VisualizeFlexChildrenState extends State { scrollDirection: widget.properties.direction, controller: widget.scrollController, child: ConstrainedBox( - constraints: - BoxConstraints( - minWidth: maxWidth, - minHeight: maxHeight, - maxWidth: - widget.direction == Axis.horizontal - ? sum( - childrenAndMainAxisSpacesRenderProps.map( - (renderSize) => renderSize.width, - ), - ) - : maxWidth, - maxHeight: - widget.direction == Axis.vertical - ? sum( - childrenAndMainAxisSpacesRenderProps.map( - (renderSize) => renderSize.height, - ), - ) - : maxHeight, - ).normalize(), + constraints: BoxConstraints( + minWidth: maxWidth, + minHeight: maxHeight, + maxWidth: widget.direction == Axis.horizontal + ? sum( + childrenAndMainAxisSpacesRenderProps.map( + (renderSize) => renderSize.width, + ), + ) + : maxWidth, + maxHeight: widget.direction == Axis.vertical + ? sum( + childrenAndMainAxisSpacesRenderProps.map( + (renderSize) => renderSize.height, + ), + ) + : maxHeight, + ).normalize(), child: Stack( children: [ LayoutExplorerBackground(colorScheme: colorScheme), @@ -617,10 +608,9 @@ class FlexChildVisualizer extends StatelessWidget { Widget buildMenuitemChild(int? flexFactor) { return Text( 'flex: $flexFactor', - style: - flexFactor == propertiesLocal.flexFactor - ? theme.boldTextStyle.copyWith(color: emphasizedTextColor) - : theme.regularTextStyleWithColor(emphasizedTextColor), + style: flexFactor == propertiesLocal.flexFactor + ? theme.boldTextStyle.copyWith(color: emphasizedTextColor) + : theme.regularTextStyleWithColor(emphasizedTextColor), ); } @@ -724,20 +714,15 @@ class FlexChildVisualizer extends StatelessWidget { final horizontal = rootLocal.isMainAxisHorizontal; late Size size; - size = - propertiesLocal.hasFlexFactor - ? SizeTween( - begin: Size( - horizontal - ? minRenderWidth - entranceMargin - : renderSize.width, - vertical - ? minRenderHeight - entranceMargin - : renderSize.height, - ), - end: renderSize, - ).evaluate(state.entranceCurve)! - : renderSize; + size = propertiesLocal.hasFlexFactor + ? SizeTween( + begin: Size( + horizontal ? minRenderWidth - entranceMargin : renderSize.width, + vertical ? minRenderHeight - entranceMargin : renderSize.height, + ), + end: renderSize, + ).evaluate(state.entranceCurve)! + : renderSize; // Not-expanded widgets enter much faster. return Opacity( opacity: min([state.entranceCurve.value * 5, 1.0]), diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/utils.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/utils.dart index 482152d46c2..cc3b2019ca3 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/utils.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/flex/utils.dart @@ -80,12 +80,11 @@ class AnimatedFlexLayoutProperties } @override - double get crossAxisDimension => - lerpDouble( - begin.crossAxisDimension, - end.crossAxisDimension, - animation.value, - )!; + double get crossAxisDimension => lerpDouble( + begin.crossAxisDimension, + end.crossAxisDimension, + animation.value, + )!; @override Axis get crossAxisDirection => end.crossAxisDirection; @@ -115,12 +114,11 @@ class AnimatedFlexLayoutProperties bool get isMainAxisVertical => end.isMainAxisVertical; @override - double get mainAxisDimension => - lerpDouble( - begin.mainAxisDimension, - end.mainAxisDimension, - animation.value, - )!; + double get mainAxisDimension => lerpDouble( + begin.mainAxisDimension, + end.mainAxisDimension, + animation.value, + )!; @override MainAxisSize? get mainAxisSize => end.mainAxisSize; diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/arrow.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/arrow.dart index cc7285add51..7fcf002900a 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/arrow.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/arrow.dart @@ -13,10 +13,9 @@ const defaultDistanceToArrow = 4.0; enum ArrowType { up, left, right, down } -Axis axis(ArrowType type) => - (type == ArrowType.up || type == ArrowType.down) - ? Axis.vertical - : Axis.horizontal; +Axis axis(ArrowType type) => (type == ArrowType.up || type == ArrowType.down) + ? Axis.vertical + : Axis.horizontal; /// Widget that draws a bidirectional arrow around another widget. /// @@ -49,10 +48,12 @@ class ArrowWrapper extends StatelessWidget { }) : assert(arrowHeadSize >= 0.0), assert(childMarginFromArrow >= 0.0), isBidirectional = true, - startArrowType = - direction == Axis.horizontal ? ArrowType.left : ArrowType.up, - endArrowType = - direction == Axis.horizontal ? ArrowType.right : ArrowType.down; + startArrowType = direction == Axis.horizontal + ? ArrowType.left + : ArrowType.up, + endArrowType = direction == Axis.horizontal + ? ArrowType.right + : ArrowType.down; final Color arrowColor; final double arrowHeadSize; @@ -92,11 +93,10 @@ class ArrowWrapper extends StatelessWidget { headSize: arrowHeadSize, strokeWidth: arrowStrokeWidth, type: startArrowType, - shouldDrawHead: - isBidirectional - ? true - : (startArrowType == ArrowType.left || - startArrowType == ArrowType.up), + shouldDrawHead: isBidirectional + ? true + : (startArrowType == ArrowType.left || + startArrowType == ArrowType.up), ), ), ), @@ -112,11 +112,10 @@ class ArrowWrapper extends StatelessWidget { headSize: arrowHeadSize, strokeWidth: arrowStrokeWidth, type: endArrowType, - shouldDrawHead: - isBidirectional - ? true - : (endArrowType == ArrowType.right || - endArrowType == ArrowType.down), + shouldDrawHead: isBidirectional + ? true + : (endArrowType == ArrowType.right || + endArrowType == ArrowType.down), ), ), ), @@ -199,10 +198,9 @@ class _ArrowPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final paint = - Paint() - ..color = color - ..strokeWidth = strokeWidth; + final paint = Paint() + ..color = color + ..strokeWidth = strokeWidth; final originX = size.width / 2, originY = size.height / 2; Offset lineStartingPoint = Offset.zero; @@ -235,12 +233,11 @@ class _ArrowPainter extends CustomPainter { p3 = Offset(originX + headSizeDividedBy2, startingY); break; } - final path = - Path() - ..moveTo(p1.dx, p1.dy) - ..lineTo(p2.dx, p2.dy) - ..lineTo(p3.dx, p3.dy) - ..close(); + final path = Path() + ..moveTo(p1.dx, p1.dy) + ..lineTo(p2.dx, p2.dy) + ..lineTo(p3.dx, p3.dy) + ..close(); canvas.drawPath(path, paint); switch (type) { diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/dimension.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/dimension.dart index ca9a67e0371..cc5e40cc5df 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/dimension.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/dimension.dart @@ -15,10 +15,9 @@ Widget dimensionDescription( final text = Text.rich( description, textAlign: TextAlign.center, - style: - overflow - ? overflowingDimensionIndicatorTextStyle(colorScheme) - : dimensionIndicatorTextStyle, + style: overflow + ? overflowingDimensionIndicatorTextStyle(colorScheme) + : dimensionIndicatorTextStyle, overflow: TextOverflow.ellipsis, ); if (overflow) { diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/overflow_indicator_painter.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/overflow_indicator_painter.dart index 18d87d6e7a8..298b7782ef8 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/overflow_indicator_painter.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/overflow_indicator_painter.dart @@ -34,15 +34,14 @@ class OverflowIndicatorPainter extends CustomPainter { /// since all of them are private. static const black = Color(0xBF000000); static const yellow = Color(0xBFFFFF00); - static final indicatorPaint = - Paint() - ..shader = ui.Gradient.linear( - const Offset(0.0, 0.0), - const Offset(10.0, 10.0), - [black, yellow, yellow, black], - [0.25, 0.25, 0.75, 0.75], - TileMode.repeated, - ); + static final indicatorPaint = Paint() + ..shader = ui.Gradient.linear( + const Offset(0.0, 0.0), + const Offset(10.0, 10.0), + [black, yellow, yellow, black], + [0.25, 0.25, 0.75, 0.75], + TileMode.repeated, + ); @override void paint(Canvas canvas, Size size) { diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/utils.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/utils.dart index 58706da8b31..798ea7a45f7 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/utils.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/utils.dart @@ -156,22 +156,21 @@ class WidgetVisualizer extends StatelessWidget { decoration: BoxDecoration( border: Border.all( color: borderColor, - width: - isSelected ? _borderSelectedWidth : _borderUnselectedWidth, + width: isSelected + ? _borderSelectedWidth + : _borderUnselectedWidth, ), - color: - isSelected - ? theme.canvasColor.brighten() - : theme.canvasColor.darken(), - boxShadow: - isSelected - ? [ - BoxShadow( - color: Colors.black.withAlpha(255 ~/ 2), - blurRadius: 20, - ), - ] - : null, + color: isSelected + ? theme.canvasColor.brighten() + : theme.canvasColor.darken(), + boxShadow: isSelected + ? [ + BoxShadow( + color: Colors.black.withAlpha(255 ~/ 2), + blurRadius: 20, + ), + ] + : null, ), child: Stack( children: [ @@ -186,14 +185,12 @@ class WidgetVisualizer extends StatelessWidget { ), Container( margin: EdgeInsets.only( - right: - overflowSide == OverflowSide.right - ? _overflowIndicatorSize - : 0.0, - bottom: - overflowSide == OverflowSide.bottom - ? _overflowIndicatorSize - : 0.0, + right: overflowSide == OverflowSide.right + ? _overflowIndicatorSize + : 0.0, + bottom: overflowSide == OverflowSide.bottom + ? _overflowIndicatorSize + : 0.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -207,11 +204,10 @@ class WidgetVisualizer extends StatelessWidget { Flexible( child: Container( constraints: BoxConstraints( - maxWidth: - largeTitle - ? defaultMaxRenderWidth - : minRenderWidth * - widgetTitleMaxWidthPercentage, + maxWidth: largeTitle + ? defaultMaxRenderWidth + : minRenderWidth * + widgetTitleMaxWidthPercentage, ), decoration: BoxDecoration(color: borderColor), padding: const EdgeInsets.all(4.0), @@ -317,10 +313,10 @@ class AnimatedLayoutProperties final constraintsLocal = constraints!; return constraintsLocal.hasBoundedWidth ? LayoutProperties.describeAxis( - constraintsLocal.minWidth, - constraintsLocal.maxWidth, - 'w', - ) + constraintsLocal.minWidth, + constraintsLocal.maxWidth, + 'w', + ) : 'w=unconstrained'; } @@ -329,10 +325,10 @@ class AnimatedLayoutProperties final constraintsLocal = constraints!; return constraintsLocal.hasBoundedHeight ? LayoutProperties.describeAxis( - constraintsLocal.minHeight, - constraintsLocal.maxHeight, - 'h', - ) + constraintsLocal.minHeight, + constraintsLocal.maxHeight, + 'h', + ) : 'h=unconstrained'; } diff --git a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/widget_constraints.dart b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/widget_constraints.dart index 72f3eb4de53..dfc1005c534 100644 --- a/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/widget_constraints.dart +++ b/packages/devtools_app/lib/src/screens/inspector/layout_explorer/ui/widget_constraints.dart @@ -51,9 +51,9 @@ class VisualizeWidthAndHeightWithConstraints extends StatelessWidget { text: ' (${propertiesLocal.describeHeightConstraints()})', style: propertiesLocal.constraints!.hasBoundedHeight || - !warnIfUnconstrained - ? null - : TextStyle(color: colorScheme.unconstrainedColor), + !warnIfUnconstrained + ? null + : TextStyle(color: colorScheme.unconstrainedColor), ), ], if (showOverflowHeight) @@ -111,9 +111,9 @@ class VisualizeWidthAndHeightWithConstraints extends StatelessWidget { text: '(${propertiesLocal.describeWidthConstraints()})', style: propertiesLocal.constraints!.hasBoundedWidth || - !warnIfUnconstrained - ? null - : TextStyle(color: colorScheme.unconstrainedColor), + !warnIfUnconstrained + ? null + : TextStyle(color: colorScheme.unconstrainedColor), ), ], if (showChildrenWidthsSum) diff --git a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_controls.dart b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_controls.dart index eae44cb02af..daba252a54f 100644 --- a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_controls.dart +++ b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_controls.dart @@ -27,8 +27,9 @@ class InspectorControls extends StatelessWidget { @override Widget build(BuildContext context) { - final activeButtonColor = - Theme.of(context).colorScheme.activeToggleButtonColor; + final activeButtonColor = Theme.of( + context, + ).colorScheme.activeToggleButtonColor; final isInspectorV2 = controller != null && FeatureFlags.inspectorV2; return Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -48,8 +49,9 @@ class InspectorControls extends StatelessWidget { ], minScreenWidthForTextBeforeScaling: minScreenWidthForTextBeforeScaling, - minScreenWidthForTextBeforeTruncating: - isInspectorV2 ? minScreenWidthForTextBeforeTruncating : null, + minScreenWidthForTextBeforeTruncating: isInspectorV2 + ? minScreenWidthForTextBeforeTruncating + : null, ); }, ), @@ -126,11 +128,11 @@ class ShowImplementationWidgetsButton extends StatelessWidget { 'Show widgets created by the Flutter framework or other packages.', label: isScreenWiderThan( - context, - InspectorControls.minScreenWidthForTextBeforeTruncating, - ) - ? 'Show Implementation Widgets' - : 'Show', + context, + InspectorControls.minScreenWidthForTextBeforeTruncating, + ) + ? 'Show Implementation Widgets' + : 'Show', onPressed: controller.toggleImplementationWidgetsVisibility, icon: Icons.code, minScreenWidthForTextBeforeScaling: diff --git a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart index dc1ed6fd9b5..ce950c777c3 100644 --- a/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart +++ b/packages/devtools_app/lib/src/screens/inspector_shared/inspector_settings_dialog.dart @@ -159,10 +159,9 @@ class InspectorDefaultDetailsViewOption extends StatelessWidget { void _onChanged(InspectorDetailsViewType? value) { if (value != null) { preferences.inspector.setDefaultInspectorDetailsView(value); - final item = - value.name == InspectorDetailsViewType.layoutExplorer.name - ? gac.defaultDetailsViewToLayoutExplorer - : gac.defaultDetailsViewToWidgetDetails; + final item = value.name == InspectorDetailsViewType.layoutExplorer.name + ? gac.defaultDetailsViewToLayoutExplorer + : gac.defaultDetailsViewToWidgetDetails; ga.select(gac.inspector, item); } } @@ -185,18 +184,15 @@ class PubRootDirectorySection extends StatelessWidget { entries: preferences.inspector.pubRootDirectories, textFieldLabel: 'Enter a new package directory', isRefreshing: preferences.inspector.isRefreshingPubRootDirectories, - onEntryAdded: - (p0) => unawaited( - preferences.inspector.addPubRootDirectories([ - p0, - ], shouldCache: true), - ), - onEntryRemoved: - (p0) => unawaited( - preferences.inspector.removePubRootDirectories([p0]), - ), - onRefreshTriggered: - () => unawaited(preferences.inspector.loadPubRootDirectories()), + onEntryAdded: (p0) => unawaited( + preferences.inspector.addPubRootDirectories([ + p0, + ], shouldCache: true), + ), + onEntryRemoved: (p0) => + unawaited(preferences.inspector.removePubRootDirectories([p0])), + onRefreshTriggered: () => + unawaited(preferences.inspector.loadPubRootDirectories()), ), ); }, diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart index a66cffff278..32de022bcdf 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart @@ -44,17 +44,16 @@ final _log = Logger('inspector_controller'); /// Data pattern containing the properties and render properties for a widget /// tree node. -typedef WidgetTreeNodeProperties = - ({ - /// Properties defined directly on the widget. - List widgetProperties, +typedef WidgetTreeNodeProperties = ({ + /// Properties defined directly on the widget. + List widgetProperties, - /// Properties defined on the widget's render object. - List renderProperties, + /// Properties defined on the widget's render object. + List renderProperties, - /// Layout properties for the widget. - LayoutProperties? layoutProperties, - }); + /// Layout properties for the widget. + LayoutProperties? layoutProperties, +}); /// This class is based on the InspectorPanel class from the Flutter IntelliJ /// plugin with some refactors to make it more of a true controller than a view. @@ -442,8 +441,8 @@ class InspectorController extends DisposableController } else { if (disposed) return; if (inspectorService is InspectorService) { - final widgetTreeReady = - await (inspectorService as InspectorService).isWidgetTreeReady(); + final widgetTreeReady = await (inspectorService as InspectorService) + .isWidgetTreeReady(); flutterAppFrameReady = widgetTreeReady; } if (isActive && flutterAppFrameReady) { @@ -541,10 +540,8 @@ class InspectorController extends DisposableController // TODO(https://github.com/flutter/devtools/issues/8481): Consider using a // variation of a path-finding algorithm to determine the new selection, // instead of looking for the first matching descendant. - final ( - closestUnchangedAncestor, - distanceToAncestor, - ) = _findClosestUnchangedAncestor(previousSelection); + final (closestUnchangedAncestor, distanceToAncestor) = + _findClosestUnchangedAncestor(previousSelection); if (closestUnchangedAncestor == null) return inspectorTree.root?.diagnostic; // TODO(elliette): This might cause a race event that will set this to false @@ -873,10 +870,9 @@ class InspectorController extends DisposableController // Show a notification that the user selected an implementation widget, // e.g. "Selected an implementation widget of Text: RichText." - final messageDetails = - selectedWidgetName.isEmpty - ? '' - : ' of $selectedWidgetName${implementationWidgetName.isEmpty ? '' : ': $implementationWidgetName'}'; + final messageDetails = selectedWidgetName.isEmpty + ? '' + : ' of $selectedWidgetName${implementationWidgetName.isEmpty ? '' : ': $implementationWidgetName'}'; notificationService.pushNotification( NotificationMessage( '$_implementationWidgetMessage$messageDetails.', @@ -965,17 +961,15 @@ class InspectorController extends DisposableController void _updateSelectedErrorFromNode(InspectorTreeNode? node) { final inspectorRef = node?.diagnostic?.valueRef.id; - final errors = - serviceConnection.errorBadgeManager - .erroredItemsForPage(InspectorScreen.id) - .value; + final errors = serviceConnection.errorBadgeManager + .erroredItemsForPage(InspectorScreen.id) + .value; // Check whether the node that was just selected has any errors associated // with it. - var errorIndex = - inspectorRef != null - ? errors.keys.toList().indexOf(inspectorRef) - : null; + var errorIndex = inspectorRef != null + ? errors.keys.toList().indexOf(inspectorRef) + : null; if (errorIndex == -1) { errorIndex = null; } @@ -1001,10 +995,9 @@ class InspectorController extends DisposableController void selectErrorByIndex(int index) { _selectedErrorIndex.value = index; - final errors = - serviceConnection.errorBadgeManager - .erroredItemsForPage(InspectorScreen.id) - .value; + final errors = serviceConnection.errorBadgeManager + .erroredItemsForPage(InspectorScreen.id) + .value; unawaited( updateSelectionFromService(inspectorRef: errors.keys.elementAt(index)), diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_data_models.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_data_models.dart index b9c5ba894c9..188dabd14b6 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_data_models.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_data_models.dart @@ -104,23 +104,22 @@ List computeRenderSizes({ } /// Data pattern containing a widget's widths or heights. -typedef WidgetSizes = - ({ - /// Whether this record represents a widget's widths or heights. - SizeType type, +typedef WidgetSizes = ({ + /// Whether this record represents a widget's widths or heights. + SizeType type, - /// Either the widget's left (if [type] is [SizeType.widths]) or top (if - /// [type] is [SizeType.heights]) padding. - double paddingA, + /// Either the widget's left (if [type] is [SizeType.widths]) or top (if + /// [type] is [SizeType.heights]) padding. + double paddingA, - /// Either the widget's width (if [type] is [SizeType.widths]) or height (if - /// [type] is [SizeType.heights]). - double widgetSize, + /// Either the widget's width (if [type] is [SizeType.widths]) or height (if + /// [type] is [SizeType.heights]). + double widgetSize, - /// Either the widget's right (if [type] is [SizeType.widths]) or bottom (if - /// [type] is [SizeType.heights]) padding. - double paddingB, - }); + /// Either the widget's right (if [type] is [SizeType.widths]) or bottom (if + /// [type] is [SizeType.heights]) padding. + double paddingB, +}); enum SizeType { widths, heights } @@ -134,16 +133,14 @@ class LayoutProperties { isFlex = node.isFlex, flexFactor = node.flexFactor, flexFit = node.flexFit, - children = - copyLevel == 0 - ? [] - : node.childrenNow - .where((child) => child.size != null) - .map( - (child) => - LayoutProperties(child, copyLevel: copyLevel - 1), - ) - .toList(growable: false) { + children = copyLevel == 0 + ? [] + : node.childrenNow + .where((child) => child.size != null) + .map( + (child) => LayoutProperties(child, copyLevel: copyLevel - 1), + ) + .toList(growable: false) { for (final child in children) { child.parent = this; } @@ -206,10 +203,10 @@ class LayoutProperties { if (constraintsLocal == null) return ''; return constraintsLocal.hasBoundedWidth ? describeAxis( - constraintsLocal.minWidth, - constraintsLocal.maxWidth, - 'w', - ) + constraintsLocal.minWidth, + constraintsLocal.maxWidth, + 'w', + ) : 'width is unconstrained'; } @@ -218,10 +215,10 @@ class LayoutProperties { if (constraintsLocal == null) return ''; return constraintsLocal.hasBoundedHeight ? describeAxis( - constraintsLocal.minHeight, - constraintsLocal.maxHeight, - 'h', - ) + constraintsLocal.minHeight, + constraintsLocal.maxHeight, + 'h', + ) : 'height is unconstrained'; } @@ -459,9 +456,8 @@ class FlexLayoutProperties extends LayoutProperties { static FlexLayoutProperties _buildNode(RemoteDiagnosticsNode node) { final renderObjectJson = node.renderObject!.json; - final properties = - (renderObjectJson['properties'] as List) - .cast>(); + final properties = (renderObjectJson['properties'] as List) + .cast>(); final data = { for (final property in properties) @@ -500,8 +496,9 @@ class FlexLayoutProperties extends LayoutProperties { List get displayChildren { final displayChildren = _displayChildren; if (displayChildren != null) return displayChildren; - return _displayChildren = - startIsTopLeft ? children : children.reversed.toList(); + return _displayChildren = startIsTopLeft + ? children + : children.reversed.toList(); } int? _totalFlex; @@ -522,11 +519,10 @@ class FlexLayoutProperties extends LayoutProperties { num get totalFlex { if (children.isEmpty) return 0; - _totalFlex ??= - children - .map((child) => child.flexFactor ?? 0) - .reduce((value, element) => value + element) - .toInt(); + _totalFlex ??= children + .map((child) => child.flexFactor ?? 0) + .reduce((value, element) => value + element) + .toInt(); return _totalFlex!; } @@ -584,8 +580,9 @@ class FlexLayoutProperties extends LayoutProperties { }) { /// calculate the render empty spaces final freeSpace = dimension(direction) - sum(childrenDimensions(direction)); - final displayMainAxisAlignment = - startIsTopLeft ? mainAxisAlignment : mainAxisAlignment?.reversed; + final displayMainAxisAlignment = startIsTopLeft + ? mainAxisAlignment + : mainAxisAlignment?.reversed; double leadingSpace(double freeSpace) { if (children.isEmpty) return 0.0; @@ -633,8 +630,9 @@ class FlexLayoutProperties extends LayoutProperties { } double largestRenderSize(Axis axis) { - final lrs = - axis == Axis.horizontal ? largestRenderWidth : largestRenderHeight; + final lrs = axis == Axis.horizontal + ? largestRenderWidth + : largestRenderHeight; // use all the space when visualizing cross axis return (axis == direction) ? lrs : maxSizeAvailable(axis); } @@ -660,12 +658,11 @@ class FlexLayoutProperties extends LayoutProperties { ); } else { // uniform cross axis sizes. - double size = - crossAxisAlignment == CrossAxisAlignment.stretch - ? maxSizeAvailable(axis) - : largestSize / - math.max(dimension(axis), 1.0) * - maxSizeAvailable(axis); + double size = crossAxisAlignment == CrossAxisAlignment.stretch + ? maxSizeAvailable(axis) + : largestSize / + math.max(dimension(axis), 1.0) * + maxSizeAvailable(axis); size = math.max(size, smallestRenderSize(axis)); return sizes.map((_) => size).toList(); } @@ -674,10 +671,9 @@ class FlexLayoutProperties extends LayoutProperties { final widths = renderSizes(Axis.horizontal); final heights = renderSizes(Axis.vertical); - final renderFreeSpace = - freeSpace > 0.0 - ? (isMainAxisHorizontal ? widths.last : heights.last) - : 0.0; + final renderFreeSpace = freeSpace > 0.0 + ? (isMainAxisHorizontal ? widths.last : heights.last) + : 0.0; final renderLeadingSpace = leadingSpace(renderFreeSpace); final renderBetweenSpace = betweenSpace(renderFreeSpace); @@ -708,8 +704,9 @@ class FlexLayoutProperties extends LayoutProperties { double calculateCrossAxisOffset(int i) { final maxDimension = maxSizeAvailable(crossAxisDirection); - final usedDimension = - crossAxisDirection == Axis.horizontal ? widths[i] : heights[i]; + final usedDimension = crossAxisDirection == Axis.horizontal + ? widths[i] + : heights[i]; if (crossAxisAlignment == CrossAxisAlignment.start || crossAxisAlignment == CrossAxisAlignment.stretch || @@ -815,10 +812,9 @@ class FlexLayoutProperties extends LayoutProperties { renderProperties.crossAxisOffset, ); } else { - space.crossAxisOffset = - crossAxisAlignment == CrossAxisAlignment.end - ? 0 - : renderProperties.crossAxisDimension; + space.crossAxisOffset = crossAxisAlignment == CrossAxisAlignment.end + ? 0 + : renderProperties.crossAxisDimension; spaces.add(space); } } @@ -826,14 +822,14 @@ class FlexLayoutProperties extends LayoutProperties { } static final _directionNamesToValues = Axis.values.asNameMap(); - static final _mainAxisAlignmentNamesToValues = - MainAxisAlignment.values.asNameMap(); + static final _mainAxisAlignmentNamesToValues = MainAxisAlignment.values + .asNameMap(); static final _mainAxisSizeNamesToValues = MainAxisSize.values.asNameMap(); - static final _crossAxisAlignmentNamesToValues = - CrossAxisAlignment.values.asNameMap(); + static final _crossAxisAlignmentNamesToValues = CrossAxisAlignment.values + .asNameMap(); static final _textDirectionNamesToValues = TextDirection.values.asNameMap(); - static final _verticalDirectionNamesToValues = - VerticalDirection.values.asNameMap(); + static final _verticalDirectionNamesToValues = VerticalDirection.values + .asNameMap(); static final _textBaselineNamesToValues = TextBaseline.values.asNameMap(); } diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart index 91903f21b1e..21bb918f517 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_screen_body.dart @@ -123,7 +123,10 @@ class InspectorScreenBodyState extends State final widgetTrees = SplitPane( axis: splitAxis, initialFractions: const [0.33, 0.67], - children: [inspectorTree, WidgetDetails(controller: controller)], + children: [ + inspectorTree, + WidgetDetails(controller: controller), + ], ); return Column( children: [ @@ -145,8 +148,8 @@ class InspectorScreenBodyState extends State constraints: constraints, onRefreshInspectorPressed: _manualInspectorRefresh, onSearchVisibleToggle: _onSearchVisibleToggle, - searchFieldBuilder: - () => StatelessSearchField( + searchFieldBuilder: () => + StatelessSearchField( controller: _inspectorTreeController, searchFieldEnabled: true, shouldRequestFocus: searchVisible, @@ -179,17 +182,15 @@ class InspectorScreenBodyState extends State if (errors.isNotEmpty) ValueListenableBuilder( valueListenable: controller.selectedErrorIndex, - builder: - (_, selectedErrorIndex, _) => Positioned( - top: 0, - right: 0, - child: ErrorNavigator( - errors: inspectableErrors, - errorIndex: selectedErrorIndex, - onSelectError: - controller.selectErrorByIndex, - ), - ), + builder: (_, selectedErrorIndex, _) => Positioned( + top: 0, + right: 0, + child: ErrorNavigator( + errors: inspectableErrors, + errorIndex: selectedErrorIndex, + onSelectError: controller.selectErrorByIndex, + ), + ), ), ], ); @@ -269,18 +270,18 @@ class InspectorTreeControls extends StatelessWidget { ), ...!isSearchVisible ? [ - const Spacer(), - ToolbarAction( - icon: Icons.search, - onPressed: onSearchVisibleToggle, - tooltip: 'Search Tree', - ), - ] + const Spacer(), + ToolbarAction( + icon: Icons.search, + onPressed: onSearchVisibleToggle, + tooltip: 'Search Tree', + ), + ] : [ - constraints.maxWidth >= _searchBreakpoint - ? _buildSearchControls() - : const Spacer(), - ], + constraints.maxWidth >= _searchBreakpoint + ? _buildSearchControls() + : const Spacer(), + ], ToolbarAction( icon: Icons.refresh, onPressed: onRefreshInspectorPressed, @@ -332,10 +333,9 @@ class ErrorNavigator extends StatelessWidget { @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; - final label = - errorIndex != null - ? 'Error ${errorIndex! + 1}/${errors.length}' - : 'Errors: ${errors.length}'; + final label = errorIndex != null + ? 'Error ${errorIndex! + 1}/${errors.length}' + : 'Errors: ${errors.length}'; return Container( color: colorScheme.errorContainer, child: Padding( diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart index d2521fa4c47..e6692e4a344 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart @@ -133,12 +133,11 @@ class InspectorTreeController extends DisposableController gac.inspector, gac.inspectorTreeControllerInitialized, nonInteraction: true, - screenMetricsProvider: - () => InspectorScreenMetrics.v2( - inspectorTreeControllerId: gaId, - rootSetCount: _rootSetCount, - rowCount: _rowsInTree.value.length, - ), + screenMetricsProvider: () => InspectorScreenMetrics.v2( + inspectorTreeControllerId: gaId, + rootSetCount: _rootSetCount, + rowCount: _rowsInTree.value.length, + ), ); } @@ -182,12 +181,11 @@ class InspectorTreeController extends DisposableController gac.inspector, gac.inspectorTreeControllerRootChange, nonInteraction: true, - screenMetricsProvider: - () => InspectorScreenMetrics.v2( - inspectorTreeControllerId: gaId, - rootSetCount: ++_rootSetCount, - rowCount: _rowsInTree.value.length, - ), + screenMetricsProvider: () => InspectorScreenMetrics.v2( + inspectorTreeControllerId: gaId, + rootSetCount: ++_rootSetCount, + rowCount: _rowsInTree.value.length, + ), ); } @@ -393,15 +391,14 @@ class InspectorTreeController extends DisposableController refreshTree( updateTreeAction: () { - final nodeToSelect = - selection == null - ? root - : rowAtIndex( - (_rowIndexFromNode(selection!) + indexOffset).clamp( - 0, - _numRows - 1, - ), - )?.node; + final nodeToSelect = selection == null + ? root + : rowAtIndex( + (_rowIndexFromNode(selection!) + indexOffset).clamp( + 0, + _numRows - 1, + ), + )?.node; setSelectedNode(nodeToSelect); return true; }, @@ -633,8 +630,9 @@ class InspectorTreeController extends DisposableController final row = getRowForNode(target); if (row != null) { final rowRect = getBoundingBox(row); - targetRect = - targetRect == null ? rowRect : targetRect.expandToInclude(rowRect); + targetRect = targetRect == null + ? rowRect + : targetRect.expandToInclude(rowRect); } } @@ -692,8 +690,9 @@ class InspectorTreeController extends DisposableController node, node.diagnostic!.childrenNow, expandChildren: expandChildren && styleIsMultiline, - hideableGroupLeader: - inHideableGroup ? (hideableGroupLeader ?? diagnosticsNode) : null, + hideableGroupLeader: inHideableGroup + ? (hideableGroupLeader ?? diagnosticsNode) + : null, ); } else { node.clearChildren(); @@ -741,8 +740,9 @@ class InspectorTreeController extends DisposableController createNode(), child, expandChildren: expandChildren, - hideableGroupLeader: - child.inHideableGroup ? hideableGroupLeader : null, + hideableGroupLeader: child.inHideableGroup + ? hideableGroupLeader + : null, ), ); } @@ -1005,14 +1005,12 @@ class _InspectorTreeState extends State final initialX = rect.left; final initialY = rect.top; - final yOffsetAtViewportTop = - _scrollControllerY.hasClients - ? _scrollControllerY.offset - : _scrollControllerY.initialScrollOffset; - final xOffsetAtViewportLeft = - _scrollControllerX.hasClients - ? _scrollControllerX.offset - : _scrollControllerX.initialScrollOffset; + final yOffsetAtViewportTop = _scrollControllerY.hasClients + ? _scrollControllerY.offset + : _scrollControllerY.initialScrollOffset; + final xOffsetAtViewportLeft = _scrollControllerX.hasClients + ? _scrollControllerX.offset + : _scrollControllerX.initialScrollOffset; final viewPortInScrollControllerSpace = Rect.fromLTWH( xOffsetAtViewportLeft, @@ -1157,8 +1155,8 @@ class _InspectorTreeState extends State ga.timeEnd( screenId, gac.pageReady, - screenMetricsProvider: - () => InspectorScreenMetrics.v2(rowCount: rows.length), + screenMetricsProvider: () => + InspectorScreenMetrics.v2(rowCount: rows.length), ); unawaited( serviceConnection.sendDwdsEvent( @@ -1221,9 +1219,9 @@ class _InspectorTreeState extends State viewportWidth: viewportWidth, error: widget.widgetErrors != null && - inspectorRef != null - ? widget.widgetErrors![inspectorRef] - : null, + inspectorRef != null + ? widget.widgetErrors![inspectorRef] + : null, ); }, childCount: rows.length + 1), controller: _scrollControllerY, @@ -1246,10 +1244,9 @@ class _InspectorTreeState extends State bool get wantKeepAlive => true; } -Paint _defaultPaint(ColorScheme colorScheme) => - Paint() - ..color = colorScheme.treeGuidelineColor - ..strokeWidth = chartLineStrokeWidth; +Paint _defaultPaint(ColorScheme colorScheme) => Paint() + ..color = colorScheme.treeGuidelineColor + ..strokeWidth = chartLineStrokeWidth; /// The distance (on the x-axis) between the center of the widget icon and the /// start of the row, as determined by a percentage of the @@ -1306,10 +1303,9 @@ class _RowPainter extends CustomPainter { final parentExpandCollapseX = _controller.getDepthIndent(row.depth - 1) - distanceFromIconCenterToRowStart; - final width = - showExpandCollapse - ? inspectorColumnIndent * 0.45 - : inspectorColumnIndent * 0.6; + final width = showExpandCollapse + ? inspectorColumnIndent * 0.45 + : inspectorColumnIndent * 0.6; canvas.drawLine( Offset(parentExpandCollapseX, 0.0), Offset(parentExpandCollapseX, inspectorRowHeight * 0.5), @@ -1414,10 +1410,9 @@ class InspectorRowContent extends StatelessWidget { Color? backgroundColor; if (row.isSelected) { - backgroundColor = - hasError - ? colorScheme.errorContainer - : colorScheme.selectedRowBackgroundColor; + backgroundColor = hasError + ? colorScheme.errorContainer + : colorScheme.selectedRowBackgroundColor; } final node = row.node; @@ -1436,16 +1431,16 @@ class InspectorRowContent extends StatelessWidget { children: [ node.showExpandCollapse ? InkWell( - onTap: onToggle, - child: RotationTransition( - turns: expandArrowAnimation, - child: Icon(Icons.expand_more, size: defaultIconSize), - ), - ) + onTap: onToggle, + child: RotationTransition( + turns: expandArrowAnimation, + child: Icon(Icons.expand_more, size: defaultIconSize), + ), + ) : const SizedBox( - width: expandCollapseWidth, - height: defaultSpacing, - ), + width: expandCollapseWidth, + height: defaultSpacing, + ), Expanded( child: Container( color: backgroundColor, @@ -1472,37 +1467,35 @@ class InspectorRowContent extends StatelessWidget { emphasizeNodesFromLocalProject: true, nodeDescriptionHighlightStyle: searchValue.isEmpty || !row.isSearchMatch - ? DiagnosticsTextStyles.regular( - Theme.of(context).colorScheme, - ) - : row.isSelected - ? theme.searchMatchHighlightStyleFocused - : theme.searchMatchHighlightStyle, - actionLabel: - isHideableGroupLeader - ? diagnostic!.groupIsHidden - ? '(expand)' - : '(collapse)' - : null, - actionCallback: - isHideableGroupLeader - ? () { - controller.refreshTree( - updateTreeAction: () { - controller.toggleHiddenGroup(node); - return true; - }, - ); - } - : null, + ? DiagnosticsTextStyles.regular( + Theme.of(context).colorScheme, + ) + : row.isSelected + ? theme.searchMatchHighlightStyleFocused + : theme.searchMatchHighlightStyle, + actionLabel: isHideableGroupLeader + ? diagnostic!.groupIsHidden + ? '(expand)' + : '(collapse)' + : null, + actionCallback: isHideableGroupLeader + ? () { + controller.refreshTree( + updateTreeAction: () { + controller.toggleHiddenGroup(node); + return true; + }, + ); + } + : null, customDescription: isHideableGroupLeader && diagnostic!.groupIsHidden - ? '${diagnostic.hideableGroupSubordinates!.length + 1} more widgets...' - : null, + ? '${diagnostic.hideableGroupSubordinates!.length + 1} more widgets...' + : null, customIconName: isHideableGroupLeader && diagnostic!.groupIsHidden - ? 'HiddenGroup' - : null, + ? 'HiddenGroup' + : null, ), ), ), diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/box/box.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/box/box.dart index 73bacc7aef3..bfd22ddd984 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/box/box.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/box/box.dart @@ -173,8 +173,9 @@ class BoxLayoutExplorerWidget extends StatelessWidget { heights: displayHeights, ); - final widgetColor = - WidgetTheme.fromName(propertiesLocal.node.description).color; + final widgetColor = WidgetTheme.fromName( + propertiesLocal.node.description, + ).color; return Column( children: [ Container( @@ -350,10 +351,9 @@ WidgetSizes _simpleFractionalLayout({ final paddingASize = sizes.paddingA; final paddingBSize = sizes.paddingB; - final paddingFraction = - paddingASize > 0 && paddingBSize > 0 - ? _narrowPaddingVisualizerPercent - : _widePaddingVisualizerPercent; + final paddingFraction = paddingASize > 0 && paddingBSize > 0 + ? _narrowPaddingVisualizerPercent + : _widePaddingVisualizerPercent; final paddingAFraction = paddingASize > 0 ? paddingFraction : 0.0; final paddingBFraction = paddingBSize > 0 ? paddingFraction : 0.0; diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/flex.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/flex.dart index 8b533031be9..c91256411d8 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/flex.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/flex.dart @@ -55,23 +55,22 @@ class FlexLayoutExplorerWidgetState Color horizontalColor(ColorScheme colorScheme) => properties!.isMainAxisHorizontal - ? colorScheme.mainAxisColor - : colorScheme.crossAxisColor; + ? colorScheme.mainAxisColor + : colorScheme.crossAxisColor; - Color verticalColor(ColorScheme colorScheme) => - properties!.isMainAxisVertical - ? colorScheme.mainAxisColor - : colorScheme.crossAxisColor; + Color verticalColor(ColorScheme colorScheme) => properties!.isMainAxisVertical + ? colorScheme.mainAxisColor + : colorScheme.crossAxisColor; Color horizontalTextColor(ColorScheme colorScheme) => properties!.isMainAxisHorizontal - ? colorScheme.mainAxisTextColor - : colorScheme.crossAxisTextColor; + ? colorScheme.mainAxisTextColor + : colorScheme.crossAxisTextColor; Color verticalTextColor(ColorScheme colorScheme) => properties!.isMainAxisVertical - ? colorScheme.mainAxisTextColor - : colorScheme.crossAxisTextColor; + ? colorScheme.mainAxisTextColor + : colorScheme.crossAxisTextColor; String get flexType => properties!.type; @@ -122,10 +121,9 @@ class FlexLayoutExplorerWidgetState Widget _buildAxisAlignmentDropdown(Axis axis, ThemeData theme) { final colorScheme = theme.colorScheme; - final color = - axis == direction - ? colorScheme.mainAxisTextColor - : colorScheme.crossAxisTextColor; + final color = axis == direction + ? colorScheme.mainAxisTextColor + : colorScheme.crossAxisTextColor; List alignmentEnumEntries; Object? selected; final propertiesLocal = properties!; @@ -153,10 +151,9 @@ class FlexLayoutExplorerWidgetState isExpanded: true, // Avoid showing an underline for the main axis and cross-axis drop downs. underline: const SizedBox(), - iconEnabledColor: - axis == propertiesLocal.direction - ? colorScheme.mainAxisColor - : colorScheme.crossAxisColor, + iconEnabledColor: axis == propertiesLocal.direction + ? colorScheme.mainAxisColor + : colorScheme.crossAxisColor, selectedItemBuilder: (context) { return [ for (final alignment in alignmentEnumEntries) @@ -177,13 +174,13 @@ class FlexLayoutExplorerWidgetState child: Image.asset( (axis == direction) ? mainAxisAssetImageUrl( - direction, - alignment as MainAxisAlignment, - ) + direction, + alignment as MainAxisAlignment, + ) : crossAxisAssetImageUrl( - direction, - alignment as CrossAxisAlignment, - ), + direction, + alignment as CrossAxisAlignment, + ), height: axisAlignmentAssetImageHeight, fit: BoxFit.fitHeight, color: color, @@ -216,13 +213,13 @@ class FlexLayoutExplorerWidgetState child: Image.asset( (axis == direction) ? mainAxisAssetImageUrl( - direction, - alignment as MainAxisAlignment, - ) + direction, + alignment as MainAxisAlignment, + ) : crossAxisAssetImageUrl( - direction, - alignment as CrossAxisAlignment, - ), + direction, + alignment as CrossAxisAlignment, + ), fit: BoxFit.fitHeight, color: color, ), @@ -238,14 +235,13 @@ class FlexLayoutExplorerWidgetState // if the axis is the main axis the type should be [MainAxisAlignment] // if the axis is the cross axis the type should be [CrossAxisAlignment] FlexLayoutProperties changedProperties; - changedProperties = - axis == direction - ? propertiesLocal.copyWith( - mainAxisAlignment: newSelection as MainAxisAlignment?, - ) - : propertiesLocal.copyWith( - crossAxisAlignment: newSelection as CrossAxisAlignment?, - ); + changedProperties = axis == direction + ? propertiesLocal.copyWith( + mainAxisAlignment: newSelection as MainAxisAlignment?, + ) + : propertiesLocal.copyWith( + crossAxisAlignment: newSelection as CrossAxisAlignment?, + ); final valueRef = propertiesLocal.node.valueRef; markAsDirty(); await objectGroup!.invokeSetFlexProperties( @@ -430,8 +426,8 @@ class _VisualizeFlexChildrenState extends State { lastHighlighted = widget.highlighted; if (widget.highlighted != null) { WidgetsBinding.instance.addPostFrameCallback((_) { - final selectedRenderObject = - selectedChildKey.currentContext?.findRenderObject(); + final selectedRenderObject = selectedChildKey.currentContext + ?.findRenderObject(); if (selectedRenderObject != null && widget.scrollController.hasClients) { unawaited( @@ -476,14 +472,12 @@ class _VisualizeFlexChildrenState extends State { maxSizeAvailable: maxSizeAvailable, ); - final renderProperties = - childrenAndMainAxisSpacesRenderProps - .where((renderProps) => !renderProps.isFreeSpace) - .toList(); - final mainAxisSpaces = - childrenAndMainAxisSpacesRenderProps - .where((renderProps) => renderProps.isFreeSpace) - .toList(); + final renderProperties = childrenAndMainAxisSpacesRenderProps + .where((renderProps) => !renderProps.isFreeSpace) + .toList(); + final mainAxisSpaces = childrenAndMainAxisSpacesRenderProps + .where((renderProps) => renderProps.isFreeSpace) + .toList(); final crossAxisSpaces = widget.properties.crossAxisSpaces( childrenRenderProperties: renderProperties, maxSizeAvailable: maxSizeAvailable, @@ -529,27 +523,24 @@ class _VisualizeFlexChildrenState extends State { scrollDirection: widget.properties.direction, controller: widget.scrollController, child: ConstrainedBox( - constraints: - BoxConstraints( - minWidth: maxWidth, - minHeight: maxHeight, - maxWidth: - widget.direction == Axis.horizontal - ? sum( - childrenAndMainAxisSpacesRenderProps.map( - (renderSize) => renderSize.width, - ), - ) - : maxWidth, - maxHeight: - widget.direction == Axis.vertical - ? sum( - childrenAndMainAxisSpacesRenderProps.map( - (renderSize) => renderSize.height, - ), - ) - : maxHeight, - ).normalize(), + constraints: BoxConstraints( + minWidth: maxWidth, + minHeight: maxHeight, + maxWidth: widget.direction == Axis.horizontal + ? sum( + childrenAndMainAxisSpacesRenderProps.map( + (renderSize) => renderSize.width, + ), + ) + : maxWidth, + maxHeight: widget.direction == Axis.vertical + ? sum( + childrenAndMainAxisSpacesRenderProps.map( + (renderSize) => renderSize.height, + ), + ) + : maxHeight, + ).normalize(), child: Stack( children: [ LayoutExplorerBackground(colorScheme: colorScheme), @@ -618,10 +609,9 @@ class FlexChildVisualizer extends StatelessWidget { Widget buildMenuitemChild(int? flexFactor) { return Text( 'flex: $flexFactor', - style: - flexFactor == propertiesLocal.flexFactor - ? theme.boldTextStyle.copyWith(color: emphasizedTextColor) - : theme.regularTextStyleWithColor(emphasizedTextColor), + style: flexFactor == propertiesLocal.flexFactor + ? theme.boldTextStyle.copyWith(color: emphasizedTextColor) + : theme.regularTextStyleWithColor(emphasizedTextColor), ); } @@ -725,20 +715,15 @@ class FlexChildVisualizer extends StatelessWidget { final horizontal = rootLocal.isMainAxisHorizontal; late Size size; - size = - propertiesLocal.hasFlexFactor - ? SizeTween( - begin: Size( - horizontal - ? minRenderWidth - entranceMargin - : renderSize.width, - vertical - ? minRenderHeight - entranceMargin - : renderSize.height, - ), - end: renderSize, - ).evaluate(state.entranceCurve)! - : renderSize; + size = propertiesLocal.hasFlexFactor + ? SizeTween( + begin: Size( + horizontal ? minRenderWidth - entranceMargin : renderSize.width, + vertical ? minRenderHeight - entranceMargin : renderSize.height, + ), + end: renderSize, + ).evaluate(state.entranceCurve)! + : renderSize; // Not-expanded widgets enter much faster. return Opacity( opacity: min([state.entranceCurve.value * 5, 1.0]), diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/utils.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/utils.dart index 14c775f646f..5e67d1e3117 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/utils.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/flex/utils.dart @@ -80,12 +80,11 @@ class AnimatedFlexLayoutProperties } @override - double get crossAxisDimension => - lerpDouble( - begin.crossAxisDimension, - end.crossAxisDimension, - animation.value, - )!; + double get crossAxisDimension => lerpDouble( + begin.crossAxisDimension, + end.crossAxisDimension, + animation.value, + )!; @override Axis get crossAxisDirection => end.crossAxisDirection; @@ -115,12 +114,11 @@ class AnimatedFlexLayoutProperties bool get isMainAxisVertical => end.isMainAxisVertical; @override - double get mainAxisDimension => - lerpDouble( - begin.mainAxisDimension, - end.mainAxisDimension, - animation.value, - )!; + double get mainAxisDimension => lerpDouble( + begin.mainAxisDimension, + end.mainAxisDimension, + animation.value, + )!; @override MainAxisSize? get mainAxisSize => end.mainAxisSize; diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/arrow.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/arrow.dart index 799bdd99d46..3adb4e615cb 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/arrow.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/arrow.dart @@ -13,10 +13,9 @@ const defaultDistanceToArrow = 4.0; enum ArrowType { up, left, right, down } -Axis axis(ArrowType type) => - (type == ArrowType.up || type == ArrowType.down) - ? Axis.vertical - : Axis.horizontal; +Axis axis(ArrowType type) => (type == ArrowType.up || type == ArrowType.down) + ? Axis.vertical + : Axis.horizontal; /// Widget that draws a bidirectional arrow around another widget. /// @@ -49,10 +48,12 @@ class ArrowWrapper extends StatelessWidget { }) : assert(arrowHeadSize >= 0.0), assert(childMarginFromArrow >= 0.0), isBidirectional = true, - startArrowType = - direction == Axis.horizontal ? ArrowType.left : ArrowType.up, - endArrowType = - direction == Axis.horizontal ? ArrowType.right : ArrowType.down; + startArrowType = direction == Axis.horizontal + ? ArrowType.left + : ArrowType.up, + endArrowType = direction == Axis.horizontal + ? ArrowType.right + : ArrowType.down; final Color arrowColor; final double arrowHeadSize; @@ -92,11 +93,10 @@ class ArrowWrapper extends StatelessWidget { headSize: arrowHeadSize, strokeWidth: arrowStrokeWidth, type: startArrowType, - shouldDrawHead: - isBidirectional - ? true - : (startArrowType == ArrowType.left || - startArrowType == ArrowType.up), + shouldDrawHead: isBidirectional + ? true + : (startArrowType == ArrowType.left || + startArrowType == ArrowType.up), ), ), ), @@ -112,11 +112,10 @@ class ArrowWrapper extends StatelessWidget { headSize: arrowHeadSize, strokeWidth: arrowStrokeWidth, type: endArrowType, - shouldDrawHead: - isBidirectional - ? true - : (endArrowType == ArrowType.right || - endArrowType == ArrowType.down), + shouldDrawHead: isBidirectional + ? true + : (endArrowType == ArrowType.right || + endArrowType == ArrowType.down), ), ), ), @@ -199,10 +198,9 @@ class _ArrowPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final paint = - Paint() - ..color = color - ..strokeWidth = strokeWidth; + final paint = Paint() + ..color = color + ..strokeWidth = strokeWidth; final originX = size.width / 2, originY = size.height / 2; Offset lineStartingPoint = Offset.zero; @@ -235,12 +233,11 @@ class _ArrowPainter extends CustomPainter { p3 = Offset(originX + headSizeDividedBy2, startingY); break; } - final path = - Path() - ..moveTo(p1.dx, p1.dy) - ..lineTo(p2.dx, p2.dy) - ..lineTo(p3.dx, p3.dy) - ..close(); + final path = Path() + ..moveTo(p1.dx, p1.dy) + ..lineTo(p2.dx, p2.dy) + ..lineTo(p3.dx, p3.dy) + ..close(); canvas.drawPath(path, paint); switch (type) { diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/dimension.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/dimension.dart index c852da24d0b..7dfb1b8e2c1 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/dimension.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/dimension.dart @@ -15,10 +15,9 @@ Widget dimensionDescription( final text = Text.rich( description, textAlign: TextAlign.center, - style: - overflow - ? overflowingDimensionIndicatorTextStyle(colorScheme) - : dimensionIndicatorTextStyle, + style: overflow + ? overflowingDimensionIndicatorTextStyle(colorScheme) + : dimensionIndicatorTextStyle, overflow: TextOverflow.ellipsis, ); if (overflow) { diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/overflow_indicator_painter.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/overflow_indicator_painter.dart index 702af0122af..2295666ceb5 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/overflow_indicator_painter.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/overflow_indicator_painter.dart @@ -34,15 +34,14 @@ class OverflowIndicatorPainter extends CustomPainter { /// since all of them are private. static const black = Color(0xBF000000); static const yellow = Color(0xBFFFFF00); - static final indicatorPaint = - Paint() - ..shader = ui.Gradient.linear( - const Offset(0.0, 0.0), - const Offset(10.0, 10.0), - [black, yellow, yellow, black], - [0.25, 0.25, 0.75, 0.75], - TileMode.repeated, - ); + static final indicatorPaint = Paint() + ..shader = ui.Gradient.linear( + const Offset(0.0, 0.0), + const Offset(10.0, 10.0), + [black, yellow, yellow, black], + [0.25, 0.25, 0.75, 0.75], + TileMode.repeated, + ); @override void paint(Canvas canvas, Size size) { diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/utils.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/utils.dart index 0f73c55c6c3..5b4b1ec2d4f 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/utils.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/utils.dart @@ -157,22 +157,21 @@ class WidgetVisualizer extends StatelessWidget { decoration: BoxDecoration( border: Border.all( color: borderColor, - width: - isSelected ? _borderSelectedWidth : _borderUnselectedWidth, + width: isSelected + ? _borderSelectedWidth + : _borderUnselectedWidth, ), - color: - isSelected - ? theme.canvasColor.brighten() - : theme.canvasColor.darken(), - boxShadow: - isSelected - ? [ - BoxShadow( - color: Colors.black.withAlpha(255 ~/ 2), - blurRadius: 10, - ), - ] - : null, + color: isSelected + ? theme.canvasColor.brighten() + : theme.canvasColor.darken(), + boxShadow: isSelected + ? [ + BoxShadow( + color: Colors.black.withAlpha(255 ~/ 2), + blurRadius: 10, + ), + ] + : null, ), child: Stack( children: [ @@ -187,29 +186,26 @@ class WidgetVisualizer extends StatelessWidget { ), Container( margin: EdgeInsets.only( - right: - overflowSide == OverflowSide.right - ? _overflowIndicatorSize - : 0.0, - bottom: - overflowSide == OverflowSide.bottom - ? _overflowIndicatorSize - : 0.0, + right: overflowSide == OverflowSide.right + ? _overflowIndicatorSize + : 0.0, + bottom: overflowSide == OverflowSide.bottom + ? _overflowIndicatorSize + : 0.0, ), - child: - isFlex - ? FlexWidgetVisualizer( - title: title, - largeTitle: largeTitle, - borderColor: borderColor, - hint: hint, - child: child, - ) - : BoxWidgetVisualizer( - borderColor: borderColor, - title: title, - properties: properties, - ), + child: isFlex + ? FlexWidgetVisualizer( + title: title, + largeTitle: largeTitle, + borderColor: borderColor, + hint: hint, + child: child, + ) + : BoxWidgetVisualizer( + borderColor: borderColor, + title: title, + properties: properties, + ), ), ], ), @@ -255,10 +251,9 @@ class FlexWidgetVisualizer extends StatelessWidget { Flexible( child: Container( constraints: BoxConstraints( - maxWidth: - largeTitle - ? defaultMaxRenderWidth - : minRenderWidth * widgetTitleMaxWidthPercentage, + maxWidth: largeTitle + ? defaultMaxRenderWidth + : minRenderWidth * widgetTitleMaxWidthPercentage, ), decoration: BoxDecoration(color: borderColor), padding: const EdgeInsets.all(densePadding), @@ -303,7 +298,9 @@ class BoxWidgetVisualizer extends StatelessWidget { return Column( mainAxisSize: MainAxisSize.min, children: [ - Center(child: WidgetLabel(labelColor: borderColor, labelText: title)), + Center( + child: WidgetLabel(labelColor: borderColor, labelText: title), + ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -444,10 +441,10 @@ class AnimatedLayoutProperties final constraintsLocal = constraints!; return constraintsLocal.hasBoundedWidth ? LayoutProperties.describeAxis( - constraintsLocal.minWidth, - constraintsLocal.maxWidth, - 'w', - ) + constraintsLocal.minWidth, + constraintsLocal.maxWidth, + 'w', + ) : 'w=unconstrained'; } @@ -456,10 +453,10 @@ class AnimatedLayoutProperties final constraintsLocal = constraints!; return constraintsLocal.hasBoundedHeight ? LayoutProperties.describeAxis( - constraintsLocal.minHeight, - constraintsLocal.maxHeight, - 'h', - ) + constraintsLocal.minHeight, + constraintsLocal.maxHeight, + 'h', + ) : 'h=unconstrained'; } @@ -593,17 +590,15 @@ class PositionedBackgroundLabel extends StatelessWidget { Widget build(BuildContext context) { return Column( // Push to the bottom if there is no padding on the top. - mainAxisAlignment: - !hasTopPadding && hasBottomPadding - ? MainAxisAlignment.end - : MainAxisAlignment.start, + mainAxisAlignment: !hasTopPadding && hasBottomPadding + ? MainAxisAlignment.end + : MainAxisAlignment.start, children: [ Row( // Push to the right if there is no padding on the left. - mainAxisAlignment: - (!hasLeftPadding && hasRightPadding) - ? MainAxisAlignment.end - : MainAxisAlignment.start, + mainAxisAlignment: (!hasLeftPadding && hasRightPadding) + ? MainAxisAlignment.end + : MainAxisAlignment.start, children: [ Flexible( child: WidgetLabel( diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/widget_constraints.dart b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/widget_constraints.dart index ce67dbc057a..70f9c9f1835 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/widget_constraints.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/layout_explorer/ui/widget_constraints.dart @@ -51,9 +51,9 @@ class VisualizeWidthAndHeightWithConstraints extends StatelessWidget { text: ' (${propertiesLocal.describeHeightConstraints()})', style: propertiesLocal.constraints!.hasBoundedHeight || - !warnIfUnconstrained - ? null - : TextStyle(color: colorScheme.unconstrainedColor), + !warnIfUnconstrained + ? null + : TextStyle(color: colorScheme.unconstrainedColor), ), ], if (showOverflowHeight) @@ -111,9 +111,9 @@ class VisualizeWidthAndHeightWithConstraints extends StatelessWidget { text: '(${propertiesLocal.describeWidthConstraints()})', style: propertiesLocal.constraints!.hasBoundedWidth || - !warnIfUnconstrained - ? null - : TextStyle(color: colorScheme.unconstrainedColor), + !warnIfUnconstrained + ? null + : TextStyle(color: colorScheme.unconstrainedColor), ), ], if (showChildrenWidthsSum) diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/widget_properties/properties_view.dart b/packages/devtools_app/lib/src/screens/inspector_v2/widget_properties/properties_view.dart index 9900966831b..1822d718819 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/widget_properties/properties_view.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/widget_properties/properties_view.dart @@ -227,8 +227,9 @@ class _PropertiesViewState extends State { final layoutExplorerOffset = includeLayoutExplorer ? 1 : 0; // If there are no properties to display, include a single row that says as // much. - final propertyRowsCount = - _sortedProperties.isEmpty ? 1 : _sortedProperties.length; + final propertyRowsCount = _sortedProperties.isEmpty + ? 1 + : _sortedProperties.length; // If the layout explorer is available, it is the first row. final totalRowsCount = propertyRowsCount + layoutExplorerOffset; @@ -258,8 +259,9 @@ class _PropertiesViewState extends State { return DecoratedPropertiesTableRow( index: index + layoutExplorerOffset, child: Flex( - direction: - horizontalLayout ? Axis.horizontal : Axis.vertical, + direction: horizontalLayout + ? Axis.horizontal + : Axis.vertical, children: [ Padding( padding: const EdgeInsets.all(largeSpacing), @@ -275,10 +277,9 @@ class _PropertiesViewState extends State { ), if (layoutPropertiesList != null) Padding( - padding: - horizontalLayout - ? const EdgeInsets.only(left: largeSpacing) - : const EdgeInsets.only(bottom: largeSpacing), + padding: horizontalLayout + ? const EdgeInsets.only(left: largeSpacing) + : const EdgeInsets.only(bottom: largeSpacing), child: layoutPropertiesList, ), ], @@ -345,11 +346,8 @@ class LayoutPropertiesList extends StatelessWidget { LayoutWidthsAndHeights? get widthsAndHeights => widgetHeights != null && widgetWidths != null - ? LayoutWidthsAndHeights( - widths: widgetWidths!, - heights: widgetHeights!, - ) - : null; + ? LayoutWidthsAndHeights(widths: widgetWidths!, heights: widgetHeights!) + : null; @override Widget build(BuildContext context) { diff --git a/packages/devtools_app/lib/src/screens/logging/_log_details.dart b/packages/devtools_app/lib/src/screens/logging/_log_details.dart index b691797d8aa..e32a9015829 100644 --- a/packages/devtools_app/lib/src/screens/logging/_log_details.dart +++ b/packages/devtools_app/lib/src/screens/logging/_log_details.dart @@ -88,16 +88,16 @@ class _LogDetailsState extends State controller: scrollController, child: preferences.logging.detailsFormat.value == - LoggingDetailsFormat.text || - (log?.encodedDetails ?? '').isEmpty - ? Padding( - padding: const EdgeInsets.all(denseSpacing), - child: SelectableText( - log?.prettyPrinted() ?? '', - textAlign: TextAlign.left, - ), - ) - : JsonViewer(encodedJson: log!.encodedDetails), + LoggingDetailsFormat.text || + (log?.encodedDetails ?? '').isEmpty + ? Padding( + padding: const EdgeInsets.all(denseSpacing), + child: SelectableText( + log?.prettyPrinted() ?? '', + textAlign: TextAlign.left, + ), + ) + : JsonViewer(encodedJson: log!.encodedDetails), ), ), ); @@ -144,26 +144,27 @@ class LogDetailsFormatButton extends StatelessWidget { @override Widget build(BuildContext context) { final currentlyUsingTextFormat = format == LoggingDetailsFormat.text; - final tooltip = - currentlyUsingTextFormat ? viewAsJsonTooltip : viewAsRawTextTooltip; + final tooltip = currentlyUsingTextFormat + ? viewAsJsonTooltip + : viewAsRawTextTooltip; void togglePreference() => preferences.logging.detailsFormat.value = format.opposite(); return currentlyUsingTextFormat ? Padding( - // This padding aligns this button with the copy button. - padding: const EdgeInsets.only(bottom: borderPadding), - child: SmallAction( + // This padding aligns this button with the copy button. + padding: const EdgeInsets.only(bottom: borderPadding), + child: SmallAction( + tooltip: tooltip, + onPressed: togglePreference, + child: Text(' { } ', style: Theme.of(context).regularTextStyle), + ), + ) + : ToolbarAction( + icon: Icons.text_fields, tooltip: tooltip, onPressed: togglePreference, - child: Text(' { } ', style: Theme.of(context).regularTextStyle), - ), - ) - : ToolbarAction( - icon: Icons.text_fields, - tooltip: tooltip, - onPressed: togglePreference, - size: defaultIconSize, - ); + size: defaultIconSize, + ); } } diff --git a/packages/devtools_app/lib/src/screens/logging/_when_column.dart b/packages/devtools_app/lib/src/screens/logging/_when_column.dart index 5563c297e90..53eaf670944 100644 --- a/packages/devtools_app/lib/src/screens/logging/_when_column.dart +++ b/packages/devtools_app/lib/src/screens/logging/_when_column.dart @@ -20,18 +20,16 @@ class WhenColumn extends ColumnData { int getValue(LogData dataObject) => dataObject.timestamp ?? -1; @override - String getDisplayValue(LogData dataObject) => - dataObject.timestamp == null - ? '' - : timeFormat.format( - DateTime.fromMillisecondsSinceEpoch(dataObject.timestamp!), - ); + String getDisplayValue(LogData dataObject) => dataObject.timestamp == null + ? '' + : timeFormat.format( + DateTime.fromMillisecondsSinceEpoch(dataObject.timestamp!), + ); @override - String getTooltip(LogData dataObject) => - dataObject.timestamp == null - ? '' - : dateTimeFormat.format( - DateTime.fromMillisecondsSinceEpoch(dataObject.timestamp!), - ); + String getTooltip(LogData dataObject) => dataObject.timestamp == null + ? '' + : dateTimeFormat.format( + DateTime.fromMillisecondsSinceEpoch(dataObject.timestamp!), + ); } diff --git a/packages/devtools_app/lib/src/screens/logging/logging_controller.dart b/packages/devtools_app/lib/src/screens/logging/logging_controller.dart index f8cbe73e49b..eb8daafa106 100644 --- a/packages/devtools_app/lib/src/screens/logging/logging_controller.dart +++ b/packages/devtools_app/lib/src/screens/logging/logging_controller.dart @@ -153,9 +153,8 @@ class LoggingController extends DevToolsScreenController SettingFilter( id: _minLogLevelFilterId, name: 'Hide logs below the minimum log level', - includeCallback: - (LogData element, int currentFilterValue) => - element.level >= currentFilterValue, + includeCallback: (LogData element, int currentFilterValue) => + element.level >= currentFilterValue, enabledCallback: (int filterValue) => filterValue > Level.ALL.value, possibleValues: _possibleLogLevels.map((l) => l.value).toList(), possibleValueDisplays: _possibleLogLevels.map((l) => l.name).toList(), @@ -168,11 +167,9 @@ class LoggingController extends DevToolsScreenController name: 'Hide verbose Flutter framework logs (initialization, frame ' 'times, image sizes)', - includeCallback: - (log) => - !_verboseFlutterFrameworkLogKinds.any( - (kind) => kind.caseInsensitiveEquals(log.kind), - ), + includeCallback: (log) => !_verboseFlutterFrameworkLogKinds.any( + (kind) => kind.caseInsensitiveEquals(log.kind), + ), defaultValue: true, ), ToggleFilter( @@ -180,11 +177,9 @@ class LoggingController extends DevToolsScreenController name: 'Hide verbose Flutter service logs (service extension state ' 'changes)', - includeCallback: - (log) => - !_verboseFlutterServiceLogKinds.any( - (kind) => kind.caseInsensitiveEquals(log.kind), - ), + includeCallback: (log) => !_verboseFlutterServiceLogKinds.any( + (kind) => kind.caseInsensitiveEquals(log.kind), + ), defaultValue: true, ), ], @@ -197,8 +192,8 @@ class LoggingController extends DevToolsScreenController ]; static final _possibleLogLevels = Level.LEVELS - // Omit Level.OFF from the possible minimum levels. - .where((level) => level != Level.OFF); + // Omit Level.OFF from the possible minimum levels. + .where((level) => level != Level.OFF); static const _kindFilterId = 'logging-kind-filter'; static const _isolateFilterId = 'logging-isolate-filter'; @@ -271,11 +266,10 @@ class LoggingController extends DevToolsScreenController String label; - label = - totalCount == showingCount - ? nf.format(totalCount) - : 'showing ${nf.format(showingCount)} of ' - '${nf.format(totalCount)}'; + label = totalCount == showingCount + ? nf.format(totalCount) + : 'showing ${nf.format(showingCount)} of ' + '${nf.format(totalCount)}'; label = '$label ${pluralize('event', totalCount)}'; diff --git a/packages/devtools_app/lib/src/screens/logging/logging_controls.dart b/packages/devtools_app/lib/src/screens/logging/logging_controls.dart index 824cdb715be..45808d1eb4c 100644 --- a/packages/devtools_app/lib/src/screens/logging/logging_controls.dart +++ b/packages/devtools_app/lib/src/screens/logging/logging_controls.dart @@ -37,15 +37,14 @@ class LoggingControls extends StatelessWidget { // TODO(kenz): fix focus issue when state is refreshed child: ValueListenableBuilder( valueListenable: controller.filteredData, - builder: - (context, _, _) => SearchField( - searchFieldWidth: - isScreenWiderThan(context, _loggingMinVerboseWidth) - ? wideSearchFieldWidth - : defaultSearchFieldWidth, - searchController: controller, - searchFieldEnabled: controller.filteredData.value.isNotEmpty, - ), + builder: (context, _, _) => SearchField( + searchFieldWidth: + isScreenWiderThan(context, _loggingMinVerboseWidth) + ? wideSearchFieldWidth + : defaultSearchFieldWidth, + searchController: controller, + searchFieldEnabled: controller.filteredData.value.isNotEmpty, + ), ), ), const SizedBox(width: denseSpacing), @@ -57,10 +56,9 @@ class LoggingControls extends StatelessWidget { ), const SizedBox(width: denseSpacing), CopyToClipboardControl( - dataProvider: - () => controller.filteredData.value - .map((e) => '${e.timestamp} [${e.kind}] ${e.prettyPrinted()}') - .joinWithTrailing('\n'), + dataProvider: () => controller.filteredData.value + .map((e) => '${e.timestamp} [${e.kind}] ${e.prettyPrinted()}') + .joinWithTrailing('\n'), tooltip: 'Copy filtered logs', ), const SizedBox(width: denseSpacing), diff --git a/packages/devtools_app/lib/src/screens/logging/logging_screen.dart b/packages/devtools_app/lib/src/screens/logging/logging_screen.dart index 7344d031a84..2b68a9dc1fe 100644 --- a/packages/devtools_app/lib/src/screens/logging/logging_screen.dart +++ b/packages/devtools_app/lib/src/screens/logging/logging_screen.dart @@ -70,10 +70,9 @@ class _LoggingScreenState extends State Expanded( child: SplitPane( axis: splitAxis, - initialFractions: - splitAxis == Axis.vertical - ? const [0.8, 0.2] - : const [0.7, 0.3], + initialFractions: splitAxis == Axis.vertical + ? const [0.8, 0.2] + : const [0.7, 0.3], children: [ RoundedOutlinedBorder( clip: true, diff --git a/packages/devtools_app/lib/src/screens/logging/metadata.dart b/packages/devtools_app/lib/src/screens/logging/metadata.dart index 40a8d851560..8babf3b1a74 100644 --- a/packages/devtools_app/lib/src/screens/logging/metadata.dart +++ b/packages/devtools_app/lib/src/screens/logging/metadata.dart @@ -145,15 +145,13 @@ abstract class MetadataChip extends StatelessWidget { decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(_borderRadius), - border: - outlined - ? Border.all(color: theme.colorScheme.subtleTextColor) - : null, + border: outlined + ? Border.all(color: theme.colorScheme.subtleTextColor) + : null, ), - margin: - includeLeadingMargin - ? const EdgeInsets.only(left: denseSpacing) - : null, + margin: includeLeadingMargin + ? const EdgeInsets.only(left: denseSpacing) + : null, padding: const EdgeInsets.symmetric( horizontal: horizontalPadding, vertical: verticalPadding, @@ -305,9 +303,8 @@ class ZoneChip extends MetadataChip { super.outlined = false, }) : super( text: name, - tooltip: - identityHashCode != null - ? 'Zone identityHashCode: $identityHashCode' - : null, + tooltip: identityHashCode != null + ? 'Zone identityHashCode: $identityHashCode' + : null, ); } diff --git a/packages/devtools_app/lib/src/screens/memory/framework/memory_controller.dart b/packages/devtools_app/lib/src/screens/memory/framework/memory_controller.dart index 7843ae0a61a..9a54884e24d 100644 --- a/packages/devtools_app/lib/src/screens/memory/framework/memory_controller.dart +++ b/packages/devtools_app/lib/src/screens/memory/framework/memory_controller.dart @@ -129,17 +129,17 @@ class MemoryController extends DevToolsScreenController chart = MemoryChartPaneController(data: offlineData?.chart ?? ChartData()); - final rootPackage = - isConnected - ? serviceConnection.serviceManager.rootInfoNow().package! - : null; + final rootPackage = isConnected + ? serviceConnection.serviceManager.rootInfoNow().package! + : null; diff = diffPaneController ?? offlineData?.diff ?? DiffPaneController( - loader: - isConnected ? HeapGraphLoaderRuntime(chart.data.timeline) : null, + loader: isConnected + ? HeapGraphLoaderRuntime(chart.data.timeline) + : null, rootPackage: rootPackage, ); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/chart_pane_controller.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/chart_pane_controller.dart index 035962bc77c..9c3d6562c98 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/chart_pane_controller.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/chart_pane_controller.dart @@ -89,11 +89,10 @@ class MemoryChartPaneController extends DisposableController if (!isChartVisible.value) return; if (!offlineDataController.showingOfflineData.value) { if (_chartConnection == null) { - _chartConnection ??= - _chartConnection = ChartVmConnection( - data.timeline, - isAndroidChartVisible: isAndroidChartVisible, - ); + _chartConnection ??= _chartConnection = ChartVmConnection( + data.timeline, + isAndroidChartVisible: isAndroidChartVisible, + ); if (serviceConnection.serviceManager.connectedState.value.connected) { _chartConnection!.init(); resume(); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/memory_tracker.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/memory_tracker.dart index 3550961d450..7690029922a 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/memory_tracker.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/memory_tracker.dart @@ -107,11 +107,10 @@ class MemoryTracker extends Disposable { // > adb shell dumpsys meminfo -d _adbMemoryInfo = serviceConnection.serviceManager.connectedState.value.connected && - serviceConnection.serviceManager.vm!.operatingSystem == - 'android' && - isAndroidChartVisible.value - ? await _fetchAdbInfo() - : AdbMemoryInfo.empty(); + serviceConnection.serviceManager.vm!.operatingSystem == 'android' && + isAndroidChartVisible.value + ? await _fetchAdbInfo() + : AdbMemoryInfo.empty(); // Query the engine's rasterCache estimate. rasterCache = await _fetchRasterCacheInfo(); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/data/charts.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/data/charts.dart index e9199815531..35d74718e76 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/data/charts.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/data/charts.dart @@ -284,8 +284,9 @@ class ChartsValues { } else if (hasMonitorStart) { eventsDisplayed['Monitor Start'] = monitorLegend; } else if (hasMonitorReset) { - eventsDisplayed['Monitor Reset'] = - isLight ? resetLightLegend : resetDarkLegend; + eventsDisplayed['Monitor Reset'] = isLight + ? resetLightLegend + : resetDarkLegend; } if (hasGc) { diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_control_pane.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_control_pane.dart index 0314c4636c0..8f3bfb524bf 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_control_pane.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_control_pane.dart @@ -106,19 +106,17 @@ class _LegendButton extends StatelessWidget { Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: chartController.data.isLegendVisible, - builder: - (_, legendVisible, _) => GaDevToolsButton( - onPressed: chartController.data.toggleLegendVisibility, - gaScreen: gac.memory, - gaSelection: - legendVisible - ? gac.MemoryEvents.hideChartLegend.name - : gac.MemoryEvents.showChartLegend.name, - icon: legendVisible ? Icons.close : Icons.storage, - label: 'Legend', - tooltip: 'Toggle visibility of the chart legend', - minScreenWidthForTextBeforeScaling: memoryControlsMinVerboseWidth, - ), + builder: (_, legendVisible, _) => GaDevToolsButton( + onPressed: chartController.data.toggleLegendVisibility, + gaScreen: gac.memory, + gaSelection: legendVisible + ? gac.MemoryEvents.hideChartLegend.name + : gac.MemoryEvents.showChartLegend.name, + icon: legendVisible ? Icons.close : Icons.storage, + label: 'Legend', + tooltip: 'Toggle visibility of the chart legend', + minScreenWidthForTextBeforeScaling: memoryControlsMinVerboseWidth, + ), ); } } diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart index a5f6b48ec89..42ef94b260e 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/chart_pane.dart @@ -67,8 +67,8 @@ class _MemoryChartPaneState extends State (tracesCount * hoverItemHeight) + (extensionEventsCount > 0 ? (extensionEventsCount == 1 - ? _hoverOneEventsHeight - : _hoverEventsHeight) + ? _hoverOneEventsHeight + : _hoverEventsHeight) : 0); static int get _timestamp => DateTime.now().millisecondsSinceEpoch; @@ -272,12 +272,11 @@ class _MemoryChartPaneState extends State double totalHoverHeight; int totalTraces; - totalTraces = - widget.chart.isAndroidChartVisible.value - ? chartsValues.vmData.entries.length - - 1 + - chartsValues.androidData.entries.length - : chartsValues.vmData.entries.length - 1; + totalTraces = widget.chart.isAndroidChartVisible.value + ? chartsValues.vmData.entries.length - + 1 + + chartsValues.androidData.entries.length + : chartsValues.vmData.entries.length - 1; totalHoverHeight = _computeHoverHeight( chartsValues.eventCount, @@ -289,41 +288,37 @@ class _MemoryChartPaneState extends State final overlayState = Overlay.of(context); _hoverOverlayEntry ??= OverlayEntry( - builder: - (context) => Positioned( - top: position.dy + _hoverYOffset, - left: xPosition, - height: totalHoverHeight, - child: Container( - padding: const EdgeInsets.only(top: 5, bottom: 8), - decoration: BoxDecoration( - color: colorScheme.surface, - border: Border.all( - color: focusColor, - width: _hoverCardBorderWidth, + builder: (context) => Positioned( + top: position.dy + _hoverYOffset, + left: xPosition, + height: totalHoverHeight, + child: Container( + padding: const EdgeInsets.only(top: 5, bottom: 8), + decoration: BoxDecoration( + color: colorScheme.surface, + border: Border.all(color: focusColor, width: _hoverCardBorderWidth), + borderRadius: defaultBorderRadius, + ), + width: _hoverWidth, + child: ListView( + children: [ + Container( + width: _hoverWidth, + padding: const EdgeInsets.only(bottom: 4), + child: Text( + 'Time $displayTimestamp', + style: theme.legendTextStyle, + textAlign: TextAlign.center, ), - borderRadius: defaultBorderRadius, - ), - width: _hoverWidth, - child: ListView( - children: [ - Container( - width: _hoverWidth, - padding: const EdgeInsets.only(bottom: 4), - child: Text( - 'Time $displayTimestamp', - style: theme.legendTextStyle, - textAlign: TextAlign.center, - ), - ), - ..._displayEventsInHover(chartsValues), - ..._displayVmDataInHover(chartsValues), - ..._displayAndroidDataInHover(chartsValues), - ..._displayExtensionEventsInHover(chartsValues), - ], ), - ), + ..._displayEventsInHover(chartsValues), + ..._displayVmDataInHover(chartsValues), + ..._displayAndroidDataInHover(chartsValues), + ..._displayExtensionEventsInHover(chartsValues), + ], ), + ), + ), ); overlayState.insert(_hoverOverlayEntry!); @@ -339,14 +334,15 @@ class _MemoryChartPaneState extends State for (final entry in dataToDisplay.entries) { final keys = entry.value.keys; - final image = - keys.contains(renderImage) - ? entry.value[renderImage] as String? - : null; - final color = - keys.contains(renderLine) ? entry.value[renderLine] as Color? : null; - final dashedLine = - keys.contains(renderDashed) ? entry.value[renderDashed] : false; + final image = keys.contains(renderImage) + ? entry.value[renderImage] as String? + : null; + final color = keys.contains(renderLine) + ? entry.value[renderLine] as Color? + : null; + final dashedLine = keys.contains(renderDashed) + ? entry.value[renderDashed] + : false; results.add( _hoverRow( @@ -398,15 +394,15 @@ class _MemoryChartPaneState extends State // Logic would be hard to read as a conditional expression. // ignore: prefer-conditional-expression if (colorPatch != null) { - traceColor = - dashed ? createDashWidget(colorPatch) : createSolidLine(colorPatch); + traceColor = dashed + ? createDashWidget(colorPatch) + : createSolidLine(colorPatch); } else { - traceColor = - image == null - ? const SizedBox() - : scaleImage - ? Image(image: AssetImage(image), width: 20, height: 10) - : Image(image: AssetImage(image)); + traceColor = image == null + ? const SizedBox() + : scaleImage + ? Image(image: AssetImage(image), width: 20, height: 10) + : Image(image: AssetImage(image)); } return [ diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/interval_dropdown.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/interval_dropdown.dart index 3fba961b019..a02b56be643 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/interval_dropdown.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/interval_dropdown.dart @@ -22,15 +22,14 @@ class IntervalDropdown extends StatefulWidget { class _IntervalDropdownState extends State { @override Widget build(BuildContext context) { - final displayTypes = - ChartInterval.values.map>(( - ChartInterval value, - ) { + final displayTypes = ChartInterval.values + .map>((ChartInterval value) { return DropdownMenuItem( value: value, child: Text(value.displayName), ); - }).toList(); + }) + .toList(); return RoundedDropDownButton( isDense: true, diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart index fa94584ae01..c709deef93c 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/widgets/legend.dart @@ -129,18 +129,15 @@ class _LegendRow extends StatelessWidget { } Widget legendSymbol(Map dataToDisplay) { - final image = - dataToDisplay.containsKey(renderImage) - ? dataToDisplay[renderImage] as String? - : null; - final color = - dataToDisplay.containsKey(renderLine) - ? dataToDisplay[renderLine] as Color? - : null; - final dashedLine = - dataToDisplay.containsKey(renderDashed) - ? dataToDisplay[renderDashed] - : false; + final image = dataToDisplay.containsKey(renderImage) + ? dataToDisplay[renderImage] as String? + : null; + final color = dataToDisplay.containsKey(renderLine) + ? dataToDisplay[renderLine] as Color? + : null; + final dashedLine = dataToDisplay.containsKey(renderDashed) + ? dataToDisplay[renderDashed] + : false; Widget traceColor; if (color != null) { @@ -150,8 +147,9 @@ class _LegendRow extends StatelessWidget { traceColor = createSolidLine(color); } } else { - traceColor = - image == null ? const SizedBox() : Image(image: AssetImage(image)); + traceColor = image == null + ? const SizedBox() + : Image(image: AssetImage(image)); } return traceColor; diff --git a/packages/devtools_app/lib/src/screens/memory/panes/control/widgets/control_pane.dart b/packages/devtools_app/lib/src/screens/memory/panes/control/widgets/control_pane.dart index 3aee542cb95..334d9c3dbcd 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/control/widgets/control_pane.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/control/widgets/control_pane.dart @@ -26,15 +26,14 @@ class MemoryControlPane extends StatelessWidget { Widget build(BuildContext context) { // OfflineAwareControls are here to enable button to exit offline mode. return OfflineAwareControls( - controlsBuilder: - (_) => Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const PrimaryControls(), - const Spacer(), - SecondaryControls(isGcing: isGcing, onGc: onGc, onSave: onSave), - ], - ), + controlsBuilder: (_) => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const PrimaryControls(), + const Spacer(), + SecondaryControls(isGcing: isGcing, onGc: onGc, onSave: onSave), + ], + ), gaScreen: ScreenMetaData.memory.id, ); } diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/controller/diff_pane_controller.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/controller/diff_pane_controller.dart index a46a1948cbb..9425b6c0ca7 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/controller/diff_pane_controller.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/controller/diff_pane_controller.dart @@ -44,16 +44,13 @@ class DiffPaneController extends DisposableController with Serializable { } factory DiffPaneController.fromJson(Map json) { - final snapshots = - (json[Json.snapshots.name] as List) - .map( - (e) => - deserialize(e, SnapshotDataItem.fromJson), - ) - .toList(); + final snapshots = (json[Json.snapshots.name] as List) + .map((e) => deserialize(e, SnapshotDataItem.fromJson)) + .toList(); - final diffWith = - (json[Json.diffWith.name] as List).map((e) => e as int?).toList(); + final diffWith = (json[Json.diffWith.name] as List) + .map((e) => e as int?) + .toList(); assert(snapshots.length == diffWith.length); @@ -73,21 +70,19 @@ class DiffPaneController extends DisposableController with Serializable { @override Map toJson() { - final snapshots = - core.snapshots.value - .whereType() - .where((s) => s.heap != null) - .toList(); + final snapshots = core.snapshots.value + .whereType() + .where((s) => s.heap != null) + .toList(); final snapshotToIndex = snapshots.asMap().map( (index, item) => MapEntry(item, index), ); - final diffWithIndices = - snapshots.map((item) { - final diffWith = item.diffWith.value; - return diffWith == null ? null : snapshotToIndex[diffWith]; - }).toList(); + final diffWithIndices = snapshots.map((item) { + final diffWith = item.diffWith.value; + return diffWith == null ? null : snapshotToIndex[diffWith]; + }).toList(); return { Json.snapshots.name: snapshots, @@ -265,10 +260,9 @@ class CoreData extends Disposable { SnapshotItem get selectedItem => _snapshots.value[_selectedSnapshotIndex.value]; - SnapshotDataItem? get selectedDataItem => - selectedItem is SnapshotDataItem - ? selectedItem as SnapshotDataItem - : null; + SnapshotDataItem? get selectedDataItem => selectedItem is SnapshotDataItem + ? selectedItem as SnapshotDataItem + : null; /// Full name for the selected class. /// diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/data/classes_diff.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/data/classes_diff.dart index c554744ba22..931023fdbc2 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/data/classes_diff.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/data/classes_diff.dart @@ -132,18 +132,18 @@ class DiffClassData extends ClassData { dataAfter: dataAfter, ), // PathFromRoot, ObjectSetStats - byPath: subtractMaps< - PathFromRoot, - ObjectSetStats, - ObjectSetStats, - ObjectSetStats - >( - from: after?.byPath, - subtract: before?.byPath, - subtractor: - ({subtract, from}) => + byPath: + subtractMaps< + PathFromRoot, + ObjectSetStats, + ObjectSetStats, + ObjectSetStats + >( + from: after?.byPath, + subtract: before?.byPath, + subtractor: ({subtract, from}) => ObjectSetStats.subtract(subtract: subtract, from: from), - ), + ), ); if (result.isZero()) return null; diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_data.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_data.dart index b6b9c144364..91c3b950f31 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_data.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_data.dart @@ -28,22 +28,22 @@ HeapDiffData calculateHeapDiffData({ required HeapData before, required HeapData after, }) { - final classesByName = subtractMaps< - HeapClassName, - SingleClassData, - SingleClassData, - DiffClassData - >( - from: after.classes!.asMap(), - subtract: before.classes!.asMap(), - subtractor: - ({subtract, from}) => DiffClassData.compare( + final classesByName = + subtractMaps< + HeapClassName, + SingleClassData, + SingleClassData, + DiffClassData + >( + from: after.classes!.asMap(), + subtract: before.classes!.asMap(), + subtractor: ({subtract, from}) => DiffClassData.compare( before: subtract, after: from, dataBefore: before, dataAfter: after, ), - ); + ); return HeapDiffData._( ClassDataList(classesByName.values.toList(growable: false)), diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_store.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_store.dart index 067b7034ef8..6b7614614be 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_store.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/data/heap_diff_store.dart @@ -28,17 +28,14 @@ HeapDiffData _calculateDiffGaWrapper(_HeapCouple couple) { ga.timeSync( gac.memory, gac.MemoryTime.calculateDiff.name, - syncOperation: - () => - result = calculateHeapDiffData( - before: couple.before, - after: couple.after, - ), - screenMetricsProvider: - () => MemoryScreenMetrics( - heapDiffObjectsBefore: couple.before.graph.objects.length, - heapDiffObjectsAfter: couple.after.graph.objects.length, - ), + syncOperation: () => result = calculateHeapDiffData( + before: couple.before, + after: couple.after, + ), + screenMetricsProvider: () => MemoryScreenMetrics( + heapDiffObjectsBefore: couple.before.graph.objects.length, + heapDiffObjectsAfter: couple.after.graph.objects.length, + ), ); return result; } diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/diff_pane.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/diff_pane.dart index 38ec4a46fa5..2342b95fc20 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/diff_pane.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/diff_pane.dart @@ -72,9 +72,8 @@ class _SnapshotItemContent extends StatelessWidget { styleSheet: MarkdownStyleSheet( p: Theme.of(context).regularTextStyle, ), - onTapLink: - (text, url, title) => - unawaited(launchUrlWithErrorHandling(url!)), + onTapLink: (text, url, title) => + unawaited(launchUrlWithErrorHandling(url!)), ), ), const SizedBox(width: densePadding), diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/path.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/path.dart index 1b1246db3e3..7821f0c3bbb 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/path.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/path.dart @@ -81,36 +81,33 @@ class _PathControlPane extends StatelessWidget { const SizedBox(width: denseSpacing), ValueListenableBuilder( valueListenable: controller.hideStandard, - builder: - (_, hideStandard, _) => DevToolsFilterButton( - onPressed: () { - ga.select( - gac.memory, - '${gac.MemoryEvents.diffPathFilter.name}-$hideStandard', - ); - controller.hideStandard.value = - !controller.hideStandard.value; - }, - isFilterActive: hideStandard, - message: 'Hide standard libraries', - ), + builder: (_, hideStandard, _) => DevToolsFilterButton( + onPressed: () { + ga.select( + gac.memory, + '${gac.MemoryEvents.diffPathFilter.name}-$hideStandard', + ); + controller.hideStandard.value = !controller.hideStandard.value; + }, + isFilterActive: hideStandard, + message: 'Hide standard libraries', + ), ), const SizedBox(width: denseSpacing), ValueListenableBuilder( valueListenable: controller.invert, - builder: - (_, invert, _) => DevToolsToggleButton( - onPressed: () { - ga.select( - gac.memory, - '${gac.MemoryEvents.diffPathInvert.name}-$invert', - ); - controller.invert.value = !controller.invert.value; - }, - isSelected: invert, - message: 'Invert the path', - icon: Icons.swap_horiz, - ), + builder: (_, invert, _) => DevToolsToggleButton( + onPressed: () { + ga.select( + gac.memory, + '${gac.MemoryEvents.diffPathInvert.name}-$invert', + ); + controller.invert.value = !controller.invert.value; + }, + isSelected: invert, + message: 'Invert the path', + icon: Icons.swap_horiz, + ), ), ], ); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/paths.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/paths.dart index 9cf7f988a4a..603b1c640fe 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/paths.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details/paths.dart @@ -147,11 +147,10 @@ class RetainingPathTable extends StatelessWidget { data: _data, keyFactory: (e) => ValueKey(e.path), selectionNotifier: selection, - onItemSelected: - (_) => ga.select( - gac.memory, - '${gac.MemoryEvents.diffPathSelect.name}-${isDiff ? "diff" : "single"}', - ), + onItemSelected: (_) => ga.select( + gac.memory, + '${gac.MemoryEvents.diffPathSelect.name}-${isDiff ? "diff" : "single"}', + ), defaultSortColumn: columns.retainedSizeColumn, defaultSortDirection: SortDirection.descending, tallHeaders: true, diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_diff.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_diff.dart index 7f9baed7567..0b940796351 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_diff.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_diff.dart @@ -141,10 +141,9 @@ class _InstanceColumn extends ColumnData return null; } - final heapCallback = - dataPart == _DataPart.deleted - ? diffData.heapBefore - : diffData.heapAfter; + final heapCallback = dataPart == _DataPart.deleted + ? diffData.heapBefore + : diffData.heapAfter; if (objects is! ObjectSet) { throw StateError( @@ -266,17 +265,16 @@ class _SizeGroupTitle extends StatelessWidget { RoundedDropDownButton( isDense: true, value: sizeType, - onChanged: - (SizeType? value) => diffData.selectedSizeType.value = value!, - items: - SizeType.values - .map( - (sizeType) => DropdownMenuItem( - value: sizeType, - child: Text(sizeType.displayName), - ), - ) - .toList(), + onChanged: (SizeType? value) => + diffData.selectedSizeType.value = value!, + items: SizeType.values + .map( + (sizeType) => DropdownMenuItem( + value: sizeType, + child: Text(sizeType.displayName), + ), + ) + .toList(), ), const SizedBox(width: denseSpacing), const Text('Size'), @@ -331,11 +329,8 @@ class ClassesTableDiff extends StatelessWidget { dataKey: dataKey, keyFactory: (e) => Key(e.className.fullName), selectionNotifier: diffData.selection, - onItemSelected: - (_) => ga.select( - gac.memory, - gac.MemoryEvents.diffClassDiffSelect.name, - ), + onItemSelected: (_) => + ga.select(gac.memory, gac.MemoryEvents.diffClassDiffSelect.name), defaultSortColumn: columns.sizeDeltaColumn, defaultSortDirection: SortDirection.descending, ); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_single.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_single.dart index 3f51fa80804..0c6afb6be22 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_single.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/classes_table_single.dart @@ -198,11 +198,8 @@ class ClassesTableSingle extends StatelessWidget { dataKey: dataKey, keyFactory: (e) => Key(e.className.fullName), selectionNotifier: classesData.selection, - onItemSelected: - (_) => ga.select( - gac.memory, - gac.MemoryEvents.diffClassSingleSelect.name, - ), + onItemSelected: (_) => + ga.select(gac.memory, gac.MemoryEvents.diffClassSingleSelect.name), defaultSortColumn: _columns.retainedSizeColumn, defaultSortDirection: SortDirection.descending, ); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/instances.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/instances.dart index 76fb8e3c14e..38a1af79c46 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/instances.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/instances.dart @@ -25,10 +25,9 @@ class HeapInstanceTableCell extends StatelessWidget { super.key, required bool isSelected, this.liveItemsEnabled = true, - }) : _sampleObtainer = - _shouldShowMenu(isSelected, objects) - ? SnapshotClassSampler(heapClass, objects, heap()) - : null, + }) : _sampleObtainer = _shouldShowMenu(isSelected, objects) + ? SnapshotClassSampler(heapClass, objects, heap()) + : null, _count = objects.instanceCount; static bool _shouldShowMenu(bool isSelected, ObjectSet objects) => @@ -43,11 +42,10 @@ class HeapInstanceTableCell extends StatelessWidget { Widget build(BuildContext context) { return InstanceViewWithContextMenu( count: _count, - menuBuilder: - () => _buildHeapInstancesMenu( - sampler: _sampleObtainer, - liveItemsEnabled: liveItemsEnabled, - ), + menuBuilder: () => _buildHeapInstancesMenu( + sampler: _sampleObtainer, + liveItemsEnabled: liveItemsEnabled, + ), ); } } @@ -86,11 +84,10 @@ class _StoreAllAsVariableMenu extends StatelessWidget { required bool subclasses, required bool implementers, }) => MenuItemButton( - onPressed: - () async => await sampler.allLiveToConsole( - includeImplementers: implementers, - includeSubclasses: subclasses, - ), + onPressed: () async => await sampler.allLiveToConsole( + includeImplementers: implementers, + includeSubclasses: subclasses, + ), child: Text(title), ); @@ -128,23 +125,21 @@ class _StoreAsOneVariableMenu extends StatelessWidget { return SubmenuButton( menuChildren: [ MenuItemButton( - onPressed: - () => unawaited( - sampler.oneStaticToConsole( - sourceFeature: MemoryAreas.snapshotDiff.name, - ), - ), + onPressed: () => unawaited( + sampler.oneStaticToConsole( + sourceFeature: MemoryAreas.snapshotDiff.name, + ), + ), child: const Text('Any'), ), MenuItemButton( - onPressed: - liveItemsEnabled - ? () => unawaited( - sampler.oneLiveStaticToConsole( - sourceFeature: MemoryAreas.snapshotDiff.name, - ), - ) - : null, + onPressed: liveItemsEnabled + ? () => unawaited( + sampler.oneLiveStaticToConsole( + sourceFeature: MemoryAreas.snapshotDiff.name, + ), + ) + : null, child: const Text('Any, not garbage collected'), ), ], diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_control_pane.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_control_pane.dart index d9a82630705..856d9bb1099 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_control_pane.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_control_pane.dart @@ -66,51 +66,52 @@ class _DiffDropdown extends StatelessWidget { final SnapshotDataItem current; final DiffPaneController controller; - List> items() => - controller.core.snapshots.value - .whereType() - .where((item) => item.isProcessed) - .map((item) { - return DropdownMenuItem( - value: item, - child: Text(item == current ? '-' : item.name), - ); - }) - .toList(); + List> items() => controller + .core + .snapshots + .value + .whereType() + .where((item) => item.isProcessed) + .map((item) { + return DropdownMenuItem( + value: item, + child: Text(item == current ? '-' : item.name), + ); + }) + .toList(); @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: current.diffWith, - builder: - (_, diffWith, _) => Row( - children: [ - const Text('Diff with:'), - const SizedBox(width: defaultSpacing), - RoundedDropDownButton( - isDense: true, - value: current.diffWith.value ?? current, - onChanged: (SnapshotDataItem? value) { - late SnapshotDataItem? newDiffWith; - if ((value ?? current) == current) { - ga.select( - gac.memory, - gac.MemoryEvents.diffSnapshotDiffSelectOff.name, - ); - newDiffWith = null; - } else { - ga.select( - gac.memory, - gac.MemoryEvents.diffSnapshotDiffSelect.name, - ); - newDiffWith = value; - } - controller.setDiffing(current, newDiffWith); - }, - items: items(), - ), - ], + builder: (_, diffWith, _) => Row( + children: [ + const Text('Diff with:'), + const SizedBox(width: defaultSpacing), + RoundedDropDownButton( + isDense: true, + value: current.diffWith.value ?? current, + onChanged: (SnapshotDataItem? value) { + late SnapshotDataItem? newDiffWith; + if ((value ?? current) == current) { + ga.select( + gac.memory, + gac.MemoryEvents.diffSnapshotDiffSelectOff.name, + ); + newDiffWith = null; + } else { + ga.select( + gac.memory, + gac.MemoryEvents.diffSnapshotDiffSelect.name, + ); + newDiffWith = value; + } + controller.setDiffing(current, newDiffWith); + }, + items: items(), ), + ], + ), ); } } diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_list.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_list.dart index 2f576ef0f31..63e2b04fec9 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_list.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_list.dart @@ -61,11 +61,10 @@ class _ListControlPane extends StatelessWidget { if (!context.mounted) return; await showDialog( context: context, - builder: - (context) => UnexpectedErrorDialog( - additionalInfo: - 'Encountered an error while taking a heap snapshot:\n${e.runtimeType}\n$e\n$trace', - ), + builder: (context) => UnexpectedErrorDialog( + additionalInfo: + 'Encountered an error while taking a heap snapshot:\n${e.runtimeType}\n$e\n$trace', + ), ); } } @@ -93,16 +92,15 @@ class _ListControlPane extends StatelessWidget { icon: Icons.delete, size: defaultIconSize, tooltip: 'Delete all snapshots', - onPressed: - controller.hasSnapshots - ? () { - ga.select( - gac.memory, - gac.MemoryEvents.diffClearSnapshots.name, - ); - controller.clearSnapshots(); - } - : null, + onPressed: controller.hasSnapshots + ? () { + ga.select( + gac.memory, + gac.MemoryEvents.diffClearSnapshots.name, + ); + controller.clearSnapshots(); + } + : null, ); }, ), @@ -186,25 +184,24 @@ class SnapshotListTitle extends StatelessWidget { Text(prettyPrintBytes(theItem.totalSize, includeUnit: true)!), Padding( padding: const EdgeInsets.only(left: ContextMenuButton.densePadding), - child: - selected - ? ContextMenuButton( - menuChildren: [ - MenuItemButton( - onPressed: onEdit, - child: const Text('Rename'), - ), - MenuItemButton( - onPressed: onDelete, - child: const Text('Delete'), - ), - MenuItemButton( - onPressed: onExport, - child: const Text('Export'), - ), - ], - ) - : const SizedBox(width: menuButtonWidth), + child: selected + ? ContextMenuButton( + menuChildren: [ + MenuItemButton( + onPressed: onEdit, + child: const Text('Rename'), + ), + MenuItemButton( + onPressed: onDelete, + child: const Text('Delete'), + ), + MenuItemButton( + onPressed: onExport, + child: const Text('Export'), + ), + ], + ) + : const SizedBox(width: menuButtonWidth), ), ]); } else { @@ -214,8 +211,9 @@ class SnapshotListTitle extends StatelessWidget { return FutureBuilder( future: theItem is SnapshotDataItem ? theItem.process : null, builder: (_, _) { - final isProcessing = - theItem is SnapshotDataItem ? !theItem.isProcessed : false; + final isProcessing = theItem is SnapshotDataItem + ? !theItem.isProcessed + : false; return Padding( padding: const EdgeInsets.symmetric(horizontal: denseRowSpacing), @@ -396,10 +394,9 @@ class _SnapshotListItemsState extends State<_SnapshotListItems> final selected = selectedIndex == index; return Container( height: _headerHeight, - color: - selected - ? Theme.of(context).colorScheme.selectedRowBackgroundColor - : null, + color: selected + ? Theme.of(context).colorScheme.selectedRowBackgroundColor + : null, child: InkWell( canRequestFocus: false, onTap: () { diff --git a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_view.dart b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_view.dart index 217a19c672f..090d1006c23 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_view.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/snapshot_view.dart @@ -58,13 +58,12 @@ class SnapshotView extends StatelessWidget { final pathTable = ValueListenableBuilder( valueListenable: controller.derived.classData, - builder: - (_, classData, _) => HeapClassDetails( - classData: classData, - pathSelection: controller.derived.selectedPath, - isDiff: classes is ClassDataList, - pathController: controller.retainingPathController, - ), + builder: (_, classData, _) => HeapClassDetails( + classData: classData, + pathSelection: controller.derived.selectedPath, + isDiff: classes is ClassDataList, + pathController: controller.retainingPathController, + ), ); return SplitPane( diff --git a/packages/devtools_app/lib/src/screens/memory/panes/profile/instances.dart b/packages/devtools_app/lib/src/screens/memory/panes/profile/instances.dart index 077737edbf2..4c11d85e80b 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/profile/instances.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/profile/instances.dart @@ -63,11 +63,10 @@ class _StoreAllAsVariableMenu extends StatelessWidget { required bool subclasses, required bool implementers, }) => MenuItemButton( - onPressed: - () async => await sampler.allLiveToConsole( - includeImplementers: implementers, - includeSubclasses: subclasses, - ), + onPressed: () async => await sampler.allLiveToConsole( + includeImplementers: implementers, + includeSubclasses: subclasses, + ), child: Text(title), ); @@ -95,10 +94,9 @@ class _StoreAsOneVariableMenu extends StatelessWidget { @override Widget build(BuildContext context) { return MenuItemButton( - onPressed: - () => unawaited( - sampler.oneLiveToConsole(sourceFeature: MemoryAreas.profile.name), - ), + onPressed: () => unawaited( + sampler.oneLiveToConsole(sourceFeature: MemoryAreas.profile.name), + ), child: const Text('Store one instance as a console variable'), ); } diff --git a/packages/devtools_app/lib/src/screens/memory/panes/profile/model.dart b/packages/devtools_app/lib/src/screens/memory/panes/profile/model.dart index 8ad3e9bc6f8..b1c412b5724 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/profile/model.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/profile/model.dart @@ -38,11 +38,10 @@ class AdaptedProfile with Serializable { ) { final adaptedProfile = AdaptedProfile._( total: ProfileRecord.total(profile), - items: - (profile.members ?? []) - .where((e) => (e.instancesCurrent ?? 0) > 0) - .map((e) => ProfileRecord.fromClassHeapStats(e)) - .toList(), + items: (profile.members ?? []) + .where((e) => (e.instancesCurrent ?? 0) > 0) + .map((e) => ProfileRecord.fromClassHeapStats(e)) + .toList(), newSpaceGCStats: profile.newSpaceGCStats, oldSpaceGCStats: profile.oldSpaceGCStats, totalGCStats: profile.totalGCStats, @@ -74,10 +73,9 @@ class AdaptedProfile with Serializable { factory AdaptedProfile.fromJson(Map json) { return AdaptedProfile._( total: ProfileRecord.fromJson(json[_ProfileJson.total]), - items: - (json[_ProfileJson.items] as List) - .map((e) => ProfileRecord.fromJson(e)) - .toList(), + items: (json[_ProfileJson.items] as List) + .map((e) => ProfileRecord.fromJson(e)) + .toList(), newSpaceGCStats: GCStats.fromJson(json[_ProfileJson.newGC]), oldSpaceGCStats: GCStats.fromJson(json[_ProfileJson.oldGC]), totalGCStats: GCStats.fromJson(json[_ProfileJson.totalGC]), diff --git a/packages/devtools_app/lib/src/screens/memory/panes/profile/profile_view.dart b/packages/devtools_app/lib/src/screens/memory/panes/profile/profile_view.dart index ed9c758aace..9b48cee6c45 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/profile/profile_view.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/profile/profile_view.dart @@ -549,10 +549,9 @@ class _AllocationProfileTable extends StatelessWidget { keyFactory: (element) => Key(element.heapClass.fullName), data: profile.records, dataKey: 'allocation-profile', - columnGroups: - vmDeveloperModeEnabled - ? _AllocationProfileTable._vmModeColumnGroups - : null, + columnGroups: vmDeveloperModeEnabled + ? _AllocationProfileTable._vmModeColumnGroups + : null, columns: [ ..._columns, if (vmDeveloperModeEnabled) ..._vmDeveloperModeColumns, @@ -615,12 +614,11 @@ class _ExportAllocationProfileButton extends StatelessWidget { minScreenWidthForTextBeforeScaling: memoryControlsMinVerboseWidth, tooltip: 'Download allocation profile data in CSV format', label: 'CSV', - onPressed: - currentAllocationProfile == null - ? null - : () => allocationProfileController.downloadMemoryTableCsv( - currentAllocationProfile, - ), + onPressed: currentAllocationProfile == null + ? null + : () => allocationProfileController.downloadMemoryTableCsv( + currentAllocationProfile, + ), ); }, ); diff --git a/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_data.dart b/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_data.dart index 3c777d7a6b4..10c6937e12d 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_data.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_data.dart @@ -122,10 +122,9 @@ class TracingIsolateState with Serializable { deserialize(value, CpuProfileData.fromJson), ), ), - classes: - (json[TracingIsolateStateJson.classes.name] as List) - .map((e) => deserialize(e, TracedClass.fromJson)) - .toList(), + classes: (json[TracingIsolateStateJson.classes.name] as List) + .map((e) => deserialize(e, TracedClass.fromJson)) + .toList(), ); } @@ -273,13 +272,12 @@ class TracingIsolateState with Serializable { ); } final service = serviceConnection.serviceManager.service!; - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; final clazz = tracedClass.clazz; // Note: we need to provide `timeExtentMicros` to `getAllocationTraces`, diff --git a/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_tree.dart b/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_tree.dart index d9ffc4ecc4f..45440359f80 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_tree.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/tracing/tracing_tree.dart @@ -196,23 +196,21 @@ class _TracingTreeHeader extends StatelessWidget { ExpandAllButton( gaScreen: gac.memory, gaSelection: gac.MemoryEvents.tracingTreeExpandAll.name, - onPressed: - () => updateTreeStateCallback(() { - for (final root in _currentDataRoots) { - root.expandCascading(); - } - }), + onPressed: () => updateTreeStateCallback(() { + for (final root in _currentDataRoots) { + root.expandCascading(); + } + }), ), const SizedBox(width: denseSpacing), CollapseAllButton( gaScreen: gac.memory, gaSelection: gac.MemoryEvents.tracingTreeCollapseAll.name, - onPressed: - () => updateTreeStateCallback(() { - for (final root in _currentDataRoots) { - root.collapseCascading(); - } - }), + onPressed: () => updateTreeStateCallback(() { + for (final root in _currentDataRoots) { + root.collapseCascading(); + } + }), ), ], ); diff --git a/packages/devtools_app/lib/src/screens/memory/shared/heap/class_filter.dart b/packages/devtools_app/lib/src/screens/memory/shared/heap/class_filter.dart index f5590688cff..62bc541a695 100644 --- a/packages/devtools_app/lib/src/screens/memory/shared/heap/class_filter.dart +++ b/packages/devtools_app/lib/src/screens/memory/shared/heap/class_filter.dart @@ -128,14 +128,13 @@ class ClassFilter with Serializable { int get hashCode => Object.hash(filterType, except, only); Set _filtersAsSet() { - Set stringToSet(String? s) => - s == null - ? {} - : s - .split(RegExp(',|\n')) - .map((e) => e.trim()) - .where((e) => e.isNotEmpty) - .toSet(); + Set stringToSet(String? s) => s == null + ? {} + : s + .split(RegExp(',|\n')) + .map((e) => e.trim()) + .where((e) => e.isNotEmpty) + .toSet(); switch (filterType) { case ClassFilterType.showAll: @@ -237,10 +236,9 @@ class ClassFilter with Serializable { throw StateError('Unexpected task: $task.'); } - final result = - dataToFilter - .where((e) => newFilter.apply(extractClass(e), rootPackage)) - .toList(); + final result = dataToFilter + .where((e) => newFilter.apply(extractClass(e), rootPackage)) + .toList(); return result; } diff --git a/packages/devtools_app/lib/src/screens/memory/shared/heap/sampler.dart b/packages/devtools_app/lib/src/screens/memory/shared/heap/sampler.dart index 9fe6ff3e76a..36b72c1c638 100644 --- a/packages/devtools_app/lib/src/screens/memory/shared/heap/sampler.dart +++ b/packages/devtools_app/lib/src/screens/memory/shared/heap/sampler.dart @@ -137,8 +137,9 @@ class LiveClassSampler { await serviceConnection.consoleService.appendBrowsableInstance( instanceRef: list, isolateRef: _mainIsolateRef, - heapSelection: - selection == null ? null : HeapObject(selection.heap, index: null), + heapSelection: selection == null + ? null + : HeapObject(selection.heap, index: null), ); } diff --git a/packages/devtools_app/lib/src/screens/memory/shared/primitives/memory_timeline.dart b/packages/devtools_app/lib/src/screens/memory/shared/primitives/memory_timeline.dart index b8ba47dba14..8300073fd8f 100644 --- a/packages/devtools_app/lib/src/screens/memory/shared/primitives/memory_timeline.dart +++ b/packages/devtools_app/lib/src/screens/memory/shared/primitives/memory_timeline.dart @@ -17,10 +17,9 @@ class MemoryTimeline extends Disposable with Serializable { factory MemoryTimeline.fromJson(Map json) { return MemoryTimeline( - data: - (json[_jsonData] as List) - .map((e) => HeapSample.fromJson(e as Map)) - .toList(), + data: (json[_jsonData] as List) + .map((e) => HeapSample.fromJson(e as Map)) + .toList(), ); } @@ -93,15 +92,9 @@ class MemoryTimeline extends Disposable with Serializable { Map json, { String? customEventName, }) { - final extensionEvent = - customEventName == null - ? ExtensionEvent(timestamp, eventKind, json) - : ExtensionEvent.custom( - timestamp, - eventKind, - customEventName, - json, - ); + final extensionEvent = customEventName == null + ? ExtensionEvent(timestamp, eventKind, json) + : ExtensionEvent.custom(timestamp, eventKind, customEventName, json); _extensionEvents.add(extensionEvent); } diff --git a/packages/devtools_app/lib/src/screens/memory/shared/primitives/painting.dart b/packages/devtools_app/lib/src/screens/memory/shared/primitives/painting.dart index 17fa2951ae3..91b9c2b5782 100644 --- a/packages/devtools_app/lib/src/screens/memory/shared/primitives/painting.dart +++ b/packages/devtools_app/lib/src/screens/memory/shared/primitives/painting.dart @@ -50,10 +50,9 @@ class DashedLine extends CustomPainter { @override void paint(Canvas canvas, Size size) { double startX = 0; - final paint = - Paint() - ..color = _color - ..strokeWidth = _dashHeight; + final paint = Paint() + ..color = _color + ..strokeWidth = _dashHeight; while (_totalWidth >= 0) { canvas.drawLine(Offset(startX, 0), Offset(startX + _dashWidth, 0), paint); diff --git a/packages/devtools_app/lib/src/screens/memory/shared/widgets/class_filter.dart b/packages/devtools_app/lib/src/screens/memory/shared/widgets/class_filter.dart index 300372b21ee..b9b3a15bb1f 100644 --- a/packages/devtools_app/lib/src/screens/memory/shared/widgets/class_filter.dart +++ b/packages/devtools_app/lib/src/screens/memory/shared/widgets/class_filter.dart @@ -37,12 +37,11 @@ class ClassFilterButton extends StatelessWidget { unawaited( showDialog( context: context, - builder: - (context) => ClassFilterDialog( - filter, - onChanged: data.onChanged, - rootPackage: _rootPackage, - ), + builder: (context) => ClassFilterDialog( + filter, + onChanged: data.onChanged, + rootPackage: _rootPackage, + ), ), ); }, diff --git a/packages/devtools_app/lib/src/screens/network/har_data_entry.dart b/packages/devtools_app/lib/src/screens/network/har_data_entry.dart index 6cb72d9d44f..8e5560e544c 100644 --- a/packages/devtools_app/lib/src/screens/network/har_data_entry.dart +++ b/packages/devtools_app/lib/src/screens/network/har_data_entry.dart @@ -62,72 +62,70 @@ class HarDataEntry { /// serialization. static Map toJson(DartIOHttpRequestData e) { // Implement the logic to convert DartIOHttpRequestData to HAR entry format - final requestCookies = - e.requestCookies.map((cookie) { - return { - NetworkEventKeys.name.name: cookie.name, - NetworkEventKeys.value.name: cookie.value, - NetworkEventKeys.path.name: cookie.path, - NetworkEventKeys.domain.name: cookie.domain, - NetworkEventKeys.expires.name: - cookie.expires?.toUtc().toIso8601String(), - NetworkEventKeys.httpOnly.name: cookie.httpOnly, - NetworkEventKeys.secure.name: cookie.secure, - }; - }).toList(); + final requestCookies = e.requestCookies.map((cookie) { + return { + NetworkEventKeys.name.name: cookie.name, + NetworkEventKeys.value.name: cookie.value, + NetworkEventKeys.path.name: cookie.path, + NetworkEventKeys.domain.name: cookie.domain, + NetworkEventKeys.expires.name: cookie.expires + ?.toUtc() + .toIso8601String(), + NetworkEventKeys.httpOnly.name: cookie.httpOnly, + NetworkEventKeys.secure.name: cookie.secure, + }; + }).toList(); - final requestHeaders = - e.requestHeaders?.entries.map((header) { - var value = header.value; - if (value is List) { - value = value.first; - } - return { - NetworkEventKeys.name.name: header.key, - NetworkEventKeys.value.name: value, - }; - }).toList(); + final requestHeaders = e.requestHeaders?.entries.map((header) { + var value = header.value; + if (value is List) { + value = value.first; + } + return { + NetworkEventKeys.name.name: header.key, + NetworkEventKeys.value.name: value, + }; + }).toList(); - final queryString = - Uri.parse(e.uri).queryParameters.entries.map((param) { - return { - NetworkEventKeys.name.name: param.key, - NetworkEventKeys.value.name: param.value, - }; - }).toList(); + final queryString = Uri.parse(e.uri).queryParameters.entries.map((param) { + return { + NetworkEventKeys.name.name: param.key, + NetworkEventKeys.value.name: param.value, + }; + }).toList(); - final responseCookies = - e.responseCookies.map((cookie) { - return { - NetworkEventKeys.name.name: cookie.name, - NetworkEventKeys.value.name: cookie.value, - NetworkEventKeys.path.name: cookie.path, - NetworkEventKeys.domain.name: cookie.domain, - NetworkEventKeys.expires.name: - cookie.expires?.toUtc().toIso8601String(), - NetworkEventKeys.httpOnly.name: cookie.httpOnly, - NetworkEventKeys.secure.name: cookie.secure, - }; - }).toList(); + final responseCookies = e.responseCookies.map((cookie) { + return { + NetworkEventKeys.name.name: cookie.name, + NetworkEventKeys.value.name: cookie.value, + NetworkEventKeys.path.name: cookie.path, + NetworkEventKeys.domain.name: cookie.domain, + NetworkEventKeys.expires.name: cookie.expires + ?.toUtc() + .toIso8601String(), + NetworkEventKeys.httpOnly.name: cookie.httpOnly, + NetworkEventKeys.secure.name: cookie.secure, + }; + }).toList(); - final responseHeaders = - e.responseHeaders?.entries.map((header) { - var value = header.value; - if (value is List) { - value = value.first; - } - return { - NetworkEventKeys.name.name: header.key, - NetworkEventKeys.value.name: value, - }; - }).toList(); + final responseHeaders = e.responseHeaders?.entries.map((header) { + var value = header.value; + if (value is List) { + value = value.first; + } + return { + NetworkEventKeys.name.name: header.key, + NetworkEventKeys.value.name: value, + }; + }).toList(); final isBinary = !isTextMimeType(e.type); final responseBodyBytes = e.encodedResponse; return { - NetworkEventKeys.startedDateTime.name: - e.startTimestamp.toUtc().toIso8601String(), + NetworkEventKeys.startedDateTime.name: e.startTimestamp + .toUtc() + .toIso8601String(), NetworkEventKeys.time.name: e.duration?.inMilliseconds, // Request NetworkEventKeys.request.name: { diff --git a/packages/devtools_app/lib/src/screens/network/har_network_data.dart b/packages/devtools_app/lib/src/screens/network/har_network_data.dart index 11fd93c0e1d..7895e008e04 100644 --- a/packages/devtools_app/lib/src/screens/network/har_network_data.dart +++ b/packages/devtools_app/lib/src/screens/network/har_network_data.dart @@ -34,10 +34,9 @@ class HarNetworkData with Serializable { as Map)[NetworkEventKeys.entries.name] as List) .map( - (entryJson) => - HarDataEntry.fromJson( - entryJson as Map, - ).toDartIOHttpRequest(), + (entryJson) => HarDataEntry.fromJson( + entryJson as Map, + ).toDartIOHttpRequest(), ) .toList(); diff --git a/packages/devtools_app/lib/src/screens/network/network_controller.dart b/packages/devtools_app/lib/src/screens/network/network_controller.dart index 6f8157e719a..cd922a01ed9 100644 --- a/packages/devtools_app/lib/src/screens/network/network_controller.dart +++ b/packages/devtools_app/lib/src/screens/network/network_controller.dart @@ -70,8 +70,9 @@ class NetworkController extends DevToolsScreenController Future exportAsHarFile() async { await fetchFullDataBeforeExport(); - _httpRequests = - filteredData.value.whereType().toList(); + _httpRequests = filteredData.value + .whereType() + .toList(); if (_httpRequests.isNullOrEmpty) { debugPrint('No valid request data to export'); @@ -509,11 +510,10 @@ class NetworkController extends DevToolsScreenController ); } - Future fetchFullDataBeforeExport() => - filteredData.value - .whereType() - .map((item) => item.getFullRequestData()) - .wait; + Future fetchFullDataBeforeExport() => filteredData.value + .whereType() + .map((item) => item.getFullRequestData()) + .wait; @override FutureOr releaseMemory({bool partial = false}) async { diff --git a/packages/devtools_app/lib/src/screens/network/network_model.dart b/packages/devtools_app/lib/src/screens/network/network_model.dart index d967a4588c2..8a6697fbe65 100644 --- a/packages/devtools_app/lib/src/screens/network/network_model.dart +++ b/packages/devtools_app/lib/src/screens/network/network_model.dart @@ -38,10 +38,9 @@ abstract class NetworkRequest String get durationDisplay { final duration = this.duration; - final text = - duration != null - ? durationText(duration, unit: DurationDisplayUnit.milliseconds) - : 'Pending'; + final text = duration != null + ? durationText(duration, unit: DurationDisplayUnit.milliseconds) + : 'Pending'; return 'Duration: $text'; } @@ -65,9 +64,9 @@ abstract class NetworkRequest port == other.port && (inProgress == other.inProgress ? (endTimestamp == other.endTimestamp && - duration == other.duration && - status == other.status && - didFail == other.didFail) + duration == other.duration && + status == other.status && + didFail == other.didFail) : true); } @@ -124,8 +123,8 @@ class Socket extends NetworkRequest { final endTime = _socket.endTime; return endTime != null ? DateTime.fromMicrosecondsSinceEpoch( - timelineMicrosecondsSinceEpoch(endTime), - ) + timelineMicrosecondsSinceEpoch(endTime), + ) : null; } @@ -133,8 +132,8 @@ class Socket extends NetworkRequest { final lastReadTime = _socket.lastReadTime; return lastReadTime != null ? DateTime.fromMicrosecondsSinceEpoch( - timelineMicrosecondsSinceEpoch(lastReadTime), - ) + timelineMicrosecondsSinceEpoch(lastReadTime), + ) : null; } @@ -142,8 +141,8 @@ class Socket extends NetworkRequest { final lastWriteTime = _socket.lastWriteTime; return lastWriteTime != null ? DateTime.fromMicrosecondsSinceEpoch( - timelineMicrosecondsSinceEpoch(lastWriteTime), - ) + timelineMicrosecondsSinceEpoch(lastWriteTime), + ) : null; } diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector.dart index 0e174a226a4..a2f476487a8 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector.dart @@ -41,23 +41,23 @@ class NetworkRequestInspector extends StatelessWidget { builder: (context, data, _) { return data == null ? RoundedOutlinedBorder( - child: Center( - child: Text( - 'No request selected', - style: Theme.of(context).regularTextStyle, + child: Center( + child: Text( + 'No request selected', + style: Theme.of(context).regularTextStyle, + ), ), - ), - ) + ) : ListenableBuilder( - listenable: data, - builder: (context, _) { - return AnalyticsTabbedView( - analyticsSessionIdentifier: data.id, - tabs: _generateTabs(data), - gaScreen: gac.network, - ); - }, - ); + listenable: data, + builder: (context, _) { + return AnalyticsTabbedView( + analyticsSessionIdentifier: data.id, + tabs: _generateTabs(data), + gaScreen: gac.network, + ); + }, + ); }, ); } @@ -93,8 +93,8 @@ class NetworkRequestInspector extends StatelessWidget { HttpResponseTrailingDropDown( data, currentResponseViewType: controller.currentResponseViewType, - onChanged: - (value) => controller.setResponseViewType = value, + onChanged: (value) => + controller.setResponseViewType = value, ), HttpViewTrailingCopyButton(data, (data) => data.responseBody), ], diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart index 20bc201e231..080cdc245e6 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart @@ -145,21 +145,16 @@ class HttpRequestView extends StatelessWidget { (e) => (e as String).contains('json'), ), String() => requestContentType.contains('json'), - _ => - throw StateError( - "Expected 'content-type' to be a List or String, but got: " - '$requestContentType', - ), + _ => throw StateError( + "Expected 'content-type' to be a List or String, but got: " + '$requestContentType', + ), }; Widget child; - child = - isJson - ? JsonViewer(encodedJson: data.requestBody!) - : TextViewer( - text: data.requestBody!, - style: theme.fixedFontStyle, - ); + child = isJson + ? JsonViewer(encodedJson: data.requestBody!) + : TextViewer(text: data.requestBody!, style: theme.fixedFontStyle); return Padding( padding: const EdgeInsets.all(denseSpacing), child: SingleChildScrollView(child: child), @@ -239,15 +234,12 @@ class HttpResponseTrailingDropDown extends StatelessWidget { builder: (_, currentType, _) { return RoundedDropDownButton( value: currentType, - items: - availableResponseTypes - .map( - (e) => DropdownMenuItem( - value: e, - child: Text(e.toString()), - ), - ) - .toList(), + items: availableResponseTypes + .map( + (e) => + DropdownMenuItem(value: e, child: Text(e.toString())), + ) + .toList(), onChanged: (value) { if (value == null) { return; @@ -345,9 +337,9 @@ class HttpTextResponseViewer extends StatelessWidget { _isJsonDecodable(responseBody) ? JsonViewer(encodedJson: responseBody) : TextViewer( - // We could also include the decoding exception. Or push a notification. - text: responseBody, - ), + // We could also include the decoding exception. Or push a notification. + text: responseBody, + ), NetworkResponseViewType.text => TextViewer( text: responseBody, style: textStyle, @@ -485,10 +477,9 @@ class HttpRequestCookiesView extends StatelessWidget { child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: ConstrainedBox( - constraints: - requestCookies - ? const BoxConstraints() - : BoxConstraints(minWidth: constraints.minWidth), + constraints: requestCookies + ? const BoxConstraints() + : BoxConstraints(minWidth: constraints.minWidth), child: DataTable( key: key, dataRowMinHeight: defaultRowHeight, @@ -633,10 +624,9 @@ class NetworkRequestOverviewView extends StatelessWidget { _buildRow( context: context, title: 'Timing', - child: - data is Socket - ? _buildSocketTimeGraph(context) - : _buildHttpTimeGraph(), + child: data is Socket + ? _buildSocketTimeGraph(context) + : _buildHttpTimeGraph(), ), const SizedBox(height: denseSpacing), _buildRow( @@ -668,8 +658,8 @@ class NetworkRequestOverviewView extends StatelessWidget { } Widget _buildTimingRow(Color color, String label, Duration duration) { - final flex = - (duration.inMicroseconds / data.duration!.inMicroseconds * 100).round(); + final flex = (duration.inMicroseconds / data.duration!.inMicroseconds * 100) + .round(); return Flexible( flex: flex, child: DevToolsTooltip( @@ -795,19 +785,17 @@ class NetworkRequestOverviewView extends StatelessWidget { _buildRow( context: context, title: 'Last read time', - child: - lastReadTimestamp != null - ? _valueText(formatDateTime(lastReadTimestamp)) - : _valueText('--'), + child: lastReadTimestamp != null + ? _valueText(formatDateTime(lastReadTimestamp)) + : _valueText('--'), ), const SizedBox(height: defaultSpacing), _buildRow( context: context, title: 'Last write time', - child: - lastWriteTimestamp != null - ? _valueText(formatDateTime(lastWriteTimestamp)) - : _valueText('--'), + child: lastWriteTimestamp != null + ? _valueText(formatDateTime(lastWriteTimestamp)) + : _valueText('--'), ), ]; } diff --git a/packages/devtools_app/lib/src/screens/network/network_screen.dart b/packages/devtools_app/lib/src/screens/network/network_screen.dart index f9b38850e9a..97bd753c811 100644 --- a/packages/devtools_app/lib/src/screens/network/network_screen.dart +++ b/packages/devtools_app/lib/src/screens/network/network_screen.dart @@ -86,12 +86,11 @@ class NetworkScreen extends Screen { return SizedBox( width: smallProgressSize, height: smallProgressSize, - child: - recording - ? SmallCircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(color), - ) - : const SizedBox(), + child: recording + ? SmallCircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(color), + ) + : const SizedBox(), ); }, ), @@ -154,8 +153,8 @@ class _NetworkScreenBodyState extends State return Column( children: [ OfflineAwareControls( - controlsBuilder: - (offline) => _NetworkProfilerControls(offline: offline), + controlsBuilder: (offline) => + _NetworkProfilerControls(offline: offline), gaScreen: gac.network, ), const SizedBox(height: intermediateSpacing), @@ -212,10 +211,9 @@ class _NetworkProfilerControlsState extends State<_NetworkProfilerControls> StartStopRecordingButton( recording: _recording, onPressed: () async => await controller.togglePolling(!_recording), - tooltipOverride: - _recording - ? 'Stop recording network traffic' - : 'Resume recording network traffic', + tooltipOverride: _recording + ? 'Stop recording network traffic' + : 'Resume recording network traffic', minScreenWidthForTextBeforeScaling: double.infinity, gaScreen: gac.network, gaSelection: _recording ? gac.pause : gac.resume, @@ -234,10 +232,9 @@ class _NetworkProfilerControlsState extends State<_NetworkProfilerControls> child: SearchField( searchController: controller, searchFieldEnabled: hasRequests, - searchFieldWidth: - screenWidth <= MediaSize.xs - ? defaultSearchFieldWidth - : wideSearchFieldWidth, + searchFieldWidth: screenWidth <= MediaSize.xs + ? defaultSearchFieldWidth + : wideSearchFieldWidth, ), ), const SizedBox(width: denseSpacing), @@ -252,8 +249,8 @@ class _NetworkProfilerControlsState extends State<_NetworkProfilerControls> OpenSaveButtonGroup( screenId: ScreenMetaData.network.id, saveFormats: const [SaveFormat.devtools, SaveFormat.har], - gaItemForSaveFormatSelection: - (SaveFormat format) => switch (format) { + gaItemForSaveFormatSelection: (SaveFormat format) => + switch (format) { SaveFormat.devtools => gac.saveFile, SaveFormat.har => gac.NetworkEvent.downloadAsHar.name, }, @@ -503,10 +500,9 @@ class StatusColumn extends ColumnData final theme = Theme.of(context); return Text( getDisplayValue(data), - style: - data.didFail - ? TextStyle(color: theme.colorScheme.error) - : theme.regularTextStyle, + style: data.didFail + ? TextStyle(color: theme.colorScheme.error) + : theme.regularTextStyle, ); } } diff --git a/packages/devtools_app/lib/src/screens/network/network_service.dart b/packages/devtools_app/lib/src/screens/network/network_service.dart index 4368d11faaf..0d75ff8c8d8 100644 --- a/packages/devtools_app/lib/src/screens/network/network_service.dart +++ b/packages/devtools_app/lib/src/screens/network/network_service.dart @@ -29,8 +29,8 @@ class NetworkService { bool alreadyRecordingSocketData = false, }) async { // Set the current timeline time as the time of the last refresh. - final timestampObj = - await serviceConnection.serviceManager.service!.getVMTimelineMicros(); + final timestampObj = await serviceConnection.serviceManager.service! + .getVMTimelineMicros(); final timestamp = timestampObj.timestamp!; if (!alreadyRecordingSocketData) { @@ -68,8 +68,8 @@ class NetworkService { DebounceCancelledCallback? cancelledCallback, }) async { if (serviceConnection.serviceManager.service == null) return; - final timestampObj = - await serviceConnection.serviceManager.service!.getVMTimelineMicros(); + final timestampObj = await serviceConnection.serviceManager.service! + .getVMTimelineMicros(); if (cancelledCallback?.call() ?? false) return; final timestamp = timestampObj.timestamp!; diff --git a/packages/devtools_app/lib/src/screens/network/offline_network_data.dart b/packages/devtools_app/lib/src/screens/network/offline_network_data.dart index 63c34bb3a94..ce6855ac382 100644 --- a/packages/devtools_app/lib/src/screens/network/offline_network_data.dart +++ b/packages/devtools_app/lib/src/screens/network/offline_network_data.dart @@ -83,11 +83,13 @@ class OfflineNetworkData with Serializable { @override Map toJson() { return { - _OfflineDataKeys.httpRequestData.name: - httpRequestData.map((e) => e.toJson()).toList(), + _OfflineDataKeys.httpRequestData.name: httpRequestData + .map((e) => e.toJson()) + .toList(), _OfflineDataKeys.selectedRequestId.name: selectedRequestId, - _OfflineDataKeys.socketData.name: - socketData.map((e) => e.toJson()).toList(), + _OfflineDataKeys.socketData.name: socketData + .map((e) => e.toJson()) + .toList(), _OfflineDataKeys.timelineMicrosOffset.name: timelineMicrosOffset, }; } diff --git a/packages/devtools_app/lib/src/screens/network/utils/http_utils.dart b/packages/devtools_app/lib/src/screens/network/utils/http_utils.dart index 4225665af94..9efd5482a73 100644 --- a/packages/devtools_app/lib/src/screens/network/utils/http_utils.dart +++ b/packages/devtools_app/lib/src/screens/network/utils/http_utils.dart @@ -13,16 +13,15 @@ int calculateHeadersSize(Map? headers) { if (headers == null) return -1; // Combine headers into a single string with CRLF endings - String headersString = - headers.entries.map((entry) { - final key = entry.key; - var value = entry.value; - // If the value is a List, join it with a comma - if (value is List) { - value = value.join(', '); - } - return '$key: $value\r\n'; - }).join(); + String headersString = headers.entries.map((entry) { + final key = entry.key; + var value = entry.value; + // If the value is a List, join it with a comma + if (value is List) { + value = value.join(', '); + } + return '$key: $value\r\n'; + }).join(); // Add final CRLF to indicate end of headers headersString += '\r\n'; diff --git a/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart b/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart index 68776c60de0..7b858a52107 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing.dart @@ -181,17 +181,16 @@ class _TraceWidgetBuildsSettingState extends State ServiceExtensionState newState, TraceWidgetBuildsScope type, ) async { - final otherState = - serviceConnection.serviceManager.serviceExtensionManager - .getServiceExtensionState(type.opposite.extensionForScope.extension) - .value - .enabled; - final traceAllWidgets = - type == TraceWidgetBuildsScope.all ? newState.enabled : otherState; - final traceUserWidgets = - type == TraceWidgetBuildsScope.userCreated - ? newState.enabled - : otherState; + final otherState = serviceConnection.serviceManager.serviceExtensionManager + .getServiceExtensionState(type.opposite.extensionForScope.extension) + .value + .enabled; + final traceAllWidgets = type == TraceWidgetBuildsScope.all + ? newState.enabled + : otherState; + final traceUserWidgets = type == TraceWidgetBuildsScope.userCreated + ? newState.enabled + : otherState; await _updateTracing( traceAllWidgets: traceAllWidgets, traceUserWidgets: traceUserWidgets, @@ -220,10 +219,9 @@ class _TraceWidgetBuildsSettingState extends State // Double nested conditinoal expressions are hard to read. // ignore: prefer-conditional-expression if (_tracingEnabled.value) { - _selectedScope.value = - traceUserWidgets - ? TraceWidgetBuildsScope.userCreated - : TraceWidgetBuildsScope.all; + _selectedScope.value = traceUserWidgets + ? TraceWidgetBuildsScope.userCreated + : TraceWidgetBuildsScope.all; } else { _selectedScope.value = null; } diff --git a/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing_controller.dart b/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing_controller.dart index 91bcfe168da..458a43ea9f4 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing_controller.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/controls/enhance_tracing/enhance_tracing_controller.dart @@ -60,8 +60,9 @@ class EnhanceTracingController extends DisposableController .listen((event) { if (event.extensionKind == 'Flutter.Frame' && _firstLiveFrameId == null) { - _firstLiveFrameId = - FlutterFrame.fromJson(event.extensionData!.data).id; + _firstLiveFrameId = FlutterFrame.fromJson( + event.extensionData!.data, + ).id; unawaited(_firstFrameEventSubscription!.cancel()); _firstFrameEventSubscription = null; } diff --git a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frame_model.dart b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frame_model.dart index 7ba1605930c..ee3e547b5a8 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frame_model.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frame_model.dart @@ -27,10 +27,9 @@ class FlutterFrame { final timeStart = Duration(microseconds: json[startTimeKey]! as int); final timeEnd = timeStart + Duration(microseconds: json[elapsedKey]! as int); - final frameTime = - TimeRange() - ..start = timeStart - ..end = timeEnd; + final frameTime = TimeRange() + ..start = timeStart + ..end = timeEnd; return FlutterFrame._( id: json[numberKey]! as int, timeFromFrameTiming: frameTime, diff --git a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart index 1a42f8bcf2d..4ef2fa82fc3 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_chart.dart @@ -113,10 +113,9 @@ class _FlutterFramesChartState extends State<_FlutterFramesChart> { } void _maybeShowShaderJankMessage() { - final shaderJankFrames = - widget.frames - .where((frame) => frame.hasShaderJank(widget.displayRefreshRate)) - .toList(); + final shaderJankFrames = widget.frames + .where((frame) => frame.hasShaderJank(widget.displayRefreshRate)) + .toList(); if (shaderJankFrames.isNotEmpty) { final Duration shaderJankDuration = shaderJankFrames.fold( Duration.zero, @@ -124,10 +123,9 @@ class _FlutterFramesChartState extends State<_FlutterFramesChart> { ); bannerMessages.addMessage( ShaderJankMessage( - screenId: - offlineDataController.showingOfflineData.value - ? ScreenMetaData.simple.id - : ScreenMetaData.performance.id, + screenId: offlineDataController.showingOfflineData.value + ? ScreenMetaData.simple.id + : ScreenMetaData.performance.id, jankyFramesCount: shaderJankFrames.length, jankDuration: shaderJankDuration, ), @@ -302,18 +300,17 @@ class _FramesChartState extends State with AutoDisposeMixin { scrollDirection: Axis.horizontal, itemCount: widget.frames.length, itemExtent: _defaultFrameWidthWithPadding, - itemBuilder: - (context, index) => FlutterFramesChartItem( - framesController: widget.framesController, - index: index, - frame: widget.frames[index], - selected: widget.frames[index] == _selectedFrame, - msPerPx: _msPerPx, - availableChartHeight: - defaultChartHeight - 2 * _outlineBorderWidth, - displayRefreshRate: widget.displayRefreshRate, - onSelected: (index) => _selectedFrameIndex = index, - ), + itemBuilder: (context, index) => FlutterFramesChartItem( + framesController: widget.framesController, + index: index, + frame: widget.frames[index], + selected: widget.frames[index] == _selectedFrame, + msPerPx: _msPerPx, + availableChartHeight: + defaultChartHeight - 2 * _outlineBorderWidth, + displayRefreshRate: widget.displayRefreshRate, + onSelected: (index) => _selectedFrameIndex = index, + ), ), ), ), @@ -345,7 +342,10 @@ class _FramesChartState extends State with AutoDisposeMixin { return Stack( children: [ chartAxisPainter, - Padding(padding: EdgeInsets.only(left: _yAxisUnitsSpace), child: chart), + Padding( + padding: EdgeInsets.only(left: _yAxisUnitsSpace), + child: chart, + ), fpsLinePainter, ValueListenableBuilder( valueListenable: widget.impellerEnabled, @@ -567,8 +567,9 @@ class FlutterFramesChartItem extends StatelessWidget { hasShaderJank: hasShaderJank, child: Container( padding: const EdgeInsets.symmetric(horizontal: densePadding), - color: - selected ? colorScheme.selectedFrameBackgroundColor : null, + color: selected + ? colorScheme.selectedFrameBackgroundColor + : null, child: Column( children: [ // Dummy child so that the InkWell does not take up the entire column. @@ -600,16 +601,19 @@ class FlutterFramesChartItem extends StatelessWidget { ); return index % 2 == 0 ? Stack( - children: [ - content, - Container( - margin: EdgeInsets.only(top: defaultChartHeight), - height: _FlutterFramesChart.frameNumberSectionHeight, - alignment: AlignmentDirectional.center, - child: Text('${frame.id}', style: themeData.subtleChartTextStyle), - ), - ], - ) + children: [ + content, + Container( + margin: EdgeInsets.only(top: defaultChartHeight), + height: _FlutterFramesChart.frameNumberSectionHeight, + alignment: AlignmentDirectional.center, + child: Text( + '${frame.id}', + style: themeData.subtleChartTextStyle, + ), + ), + ], + ) : content; } @@ -622,12 +626,11 @@ class FlutterFramesChartItem extends StatelessWidget { ga.select( gac.performance, gac.PerformanceEvents.selectFlutterFrame.name, - screenMetricsProvider: - () => PerformanceScreenMetrics( - uiDuration: frame.buildTime, - rasterDuration: frame.rasterTime, - shaderCompilationDuration: frame.shaderDuration, - ), + screenMetricsProvider: () => PerformanceScreenMetrics( + uiDuration: frame.buildTime, + rasterDuration: frame.rasterTime, + shaderCompilationDuration: frame.shaderDuration, + ), ); } framesController.handleSelectedFrame(frame); @@ -668,10 +671,9 @@ class FlutterFrameTooltip extends StatelessWidget { 'UI: ${durationText(frame.buildTime, unit: DurationDisplayUnit.milliseconds, allowRoundingToZero: false)}'; final rasterText = 'Raster: ${durationText(frame.rasterTime, unit: DurationDisplayUnit.milliseconds, allowRoundingToZero: false)}'; - final shaderText = - hasShaderJank - ? 'Shader Compilation: ${durationText(frame.shaderDuration, unit: DurationDisplayUnit.milliseconds, allowRoundingToZero: false)} -' - : ''; + final shaderText = hasShaderJank + ? 'Shader Compilation: ${durationText(frame.shaderDuration, unit: DurationDisplayUnit.milliseconds, allowRoundingToZero: false)} -' + : ''; return HoverCardData( position: HoverCardPosition.element, width: _calculateTooltipWidth([ @@ -700,11 +702,10 @@ class FlutterFrameTooltip extends StatelessWidget { MoreInfoLink( url: preCompileShadersDocsUrl, gaScreenName: gac.performance, - gaSelectedItemDescription: - gac - .PerformanceDocs - .shaderCompilationDocsTooltipLink - .name, + gaSelectedItemDescription: gac + .PerformanceDocs + .shaderCompilationDocsTooltipLink + .name, ), ], ), diff --git a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_controller.dart b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_controller.dart index e4dda55a1a0..0c83414cf28 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_controller.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/flutter_frames/flutter_frames_controller.dart @@ -75,10 +75,9 @@ class FlutterFramesController extends PerformanceFeatureController { // Default to true for profile builds only. _badgeTabForJankyFrames.value = await connectedApp.isProfileBuild; - final refreshRate = - connectedApp.isFlutterAppNow! - ? await serviceConnection.queryDisplayRefreshRate - : defaultRefreshRate; + final refreshRate = connectedApp.isFlutterAppNow! + ? await serviceConnection.queryDisplayRefreshRate + : defaultRefreshRate; _displayRefreshRate.value = refreshRate ?? defaultRefreshRate; } diff --git a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis_model.dart b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis_model.dart index 5658c339ee0..eaa84ac5c1c 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis_model.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_analysis_model.dart @@ -109,13 +109,11 @@ class FrameAnalysis { late FramePhase longestUiPhase = _calculateLongestFramePhase(); - bool get hasUiData => - _hasUiData ??= - [ - ...buildPhase.events, - ...layoutPhase.events, - ...paintPhase.events, - ].isNotEmpty; + bool get hasUiData => _hasUiData ??= [ + ...buildPhase.events, + ...layoutPhase.events, + ...paintPhase.events, + ].isNotEmpty; bool? _hasUiData; diff --git a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_hints.dart b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_hints.dart index 58edaccb87f..46e7f7f85a1 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_hints.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_hints.dart @@ -47,34 +47,32 @@ class FrameHints extends StatelessWidget { final theme = Theme.of(context); final saveLayerCount = frameAnalysis.saveLayerCount; final intrinsicOperationsCount = frameAnalysis.intrinsicOperationsCount; - final uiHints = - showUiJankHints - ? [ - Text('UI Jank Detected', style: theme.errorTextStyle), - const SizedBox(height: denseSpacing), - EnhanceTracingHint( - longestPhase: frameAnalysis.longestUiPhase, - enhanceTracingState: frameAnalysis.frame.enhanceTracingState, - enhanceTracingController: enhanceTracingController, - ), - const SizedBox(height: densePadding), - if (intrinsicOperationsCount > 0) - IntrinsicOperationsHint(intrinsicOperationsCount), - ] - : []; - final rasterHints = - showRasterJankHints - ? [ - Text('Raster Jank Detected', style: theme.errorTextStyle), - const SizedBox(height: denseSpacing), - if (saveLayerCount > 0) CanvasSaveLayerHint(saveLayerCount), - const SizedBox(height: denseSpacing), - if (frame.hasShaderTime) - ShaderCompilationHint(shaderTime: frame.shaderDuration), - const SizedBox(height: denseSpacing), - const GeneralRasterJankHint(), - ] - : []; + final uiHints = showUiJankHints + ? [ + Text('UI Jank Detected', style: theme.errorTextStyle), + const SizedBox(height: denseSpacing), + EnhanceTracingHint( + longestPhase: frameAnalysis.longestUiPhase, + enhanceTracingState: frameAnalysis.frame.enhanceTracingState, + enhanceTracingController: enhanceTracingController, + ), + const SizedBox(height: densePadding), + if (intrinsicOperationsCount > 0) + IntrinsicOperationsHint(intrinsicOperationsCount), + ] + : []; + final rasterHints = showRasterJankHints + ? [ + Text('Raster Jank Detected', style: theme.errorTextStyle), + const SizedBox(height: denseSpacing), + if (saveLayerCount > 0) CanvasSaveLayerHint(saveLayerCount), + const SizedBox(height: denseSpacing), + if (frame.hasShaderTime) + ShaderCompilationHint(shaderTime: frame.shaderDuration), + const SizedBox(height: denseSpacing), + const GeneralRasterJankHint(), + ] + : []; return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -340,28 +338,27 @@ class ShaderCompilationHint extends StatelessWidget { ), ], ), - childrenSpans: - serviceConnection.serviceManager.connectedApp!.isIosApp - ? [ - TextSpan( - text: - ' Note: pre-compiling shaders is a legacy solution with many ' - 'pitfalls. Try ', - style: theme.regularTextStyle, - ), - GaLinkTextSpan( - link: GaLink( - display: 'Impeller', - url: impellerDocsUrl, - gaScreenName: gac.performance, - gaSelectedItemDescription: - gac.PerformanceDocs.impellerDocsLink.name, - ), - context: context, + childrenSpans: serviceConnection.serviceManager.connectedApp!.isIosApp + ? [ + TextSpan( + text: + ' Note: pre-compiling shaders is a legacy solution with many ' + 'pitfalls. Try ', + style: theme.regularTextStyle, + ), + GaLinkTextSpan( + link: GaLink( + display: 'Impeller', + url: impellerDocsUrl, + gaScreenName: gac.performance, + gaSelectedItemDescription: + gac.PerformanceDocs.impellerDocsLink.name, ), - TextSpan(text: ' instead!', style: theme.regularTextStyle), - ] - : [], + context: context, + ), + TextSpan(text: ' instead!', style: theme.regularTextStyle), + ] + : [], ), ); } diff --git a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_time_visualizer.dart b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_time_visualizer.dart index d3c5a38c58f..44584c2464e 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_time_visualizer.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/frame_analysis/frame_time_visualizer.dart @@ -178,7 +178,11 @@ class _FrameBlockGroup extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [Text(title), const SizedBox(height: denseSpacing), content], + children: [ + Text(title), + const SizedBox(height: denseSpacing), + content, + ], ); } @@ -191,12 +195,9 @@ class _FrameBlockGroup extends StatelessWidget { BoxConstraints constraints, int totalFlex, ) { - final unadjustedBlockWidths = - data - .map( - (blockData) => constraints.maxWidth * blockData.flex / totalFlex, - ) - .toList(); + final unadjustedBlockWidths = data + .map((blockData) => constraints.maxWidth * blockData.flex / totalFlex) + .toList(); var adjustment = 0.0; var widestBlockIndex = 0; @@ -211,13 +212,11 @@ class _FrameBlockGroup extends StatelessWidget { } } - final adjustedBlockWidths = - unadjustedBlockWidths - .map( - (blockWidth) => - math.max(blockWidth, _FramePhaseBlock.minBlockWidth), - ) - .toList(); + final adjustedBlockWidths = unadjustedBlockWidths + .map( + (blockWidth) => math.max(blockWidth, _FramePhaseBlock.minBlockWidth), + ) + .toList(); final widest = adjustedBlockWidths[widestBlockIndex]; adjustedBlockWidths[widestBlockIndex] = math.max( widest - adjustment, @@ -303,14 +302,13 @@ class _FramePhaseBlockData { final IconData icon; String get display { - final text = - duration != Duration.zero - ? durationText( - duration, - unit: DurationDisplayUnit.milliseconds, - allowRoundingToZero: false, - ) - : '--'; + final text = duration != Duration.zero + ? durationText( + duration, + unit: DurationDisplayUnit.milliseconds, + allowRoundingToZero: false, + ) + : '--'; return '$title - $text'; } } diff --git a/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart b/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart index 254c19e2974..4a2521d921c 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats.dart @@ -208,9 +208,8 @@ class _RebuildTableState extends State { dataKey: 'RebuildMetricsTable', columns: _columns, data: widget.metrics, - keyFactory: - (RebuildLocationStats location) => - ValueKey('${location.location.id}'), + keyFactory: (RebuildLocationStats location) => + ValueKey('${location.location.id}'), defaultSortColumn: _metricsColumns.first, defaultSortDirection: sortDirection, onItemSelected: (item) async { diff --git a/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats_model.dart b/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats_model.dart index e6a5c1eb7fd..153778fa520 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats_model.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/rebuild_stats/rebuild_stats_model.dart @@ -186,8 +186,8 @@ class RebuildCountModel { RebuildCountModel.fromJson(Map json) { if (json.isEmpty) return; locationMap.processLocationMap(json[_locationsKey] as Map); - final frames = - (json[_framesKey] as List).cast>(); + final frames = (json[_framesKey] as List) + .cast>(); frames.forEach(processRebuildsForFrame); } diff --git a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/_perfetto_controller_web.dart b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/_perfetto_controller_web.dart index 937149ed605..ed9bc3a6f3e 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/_perfetto_controller_web.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/_perfetto_controller_web.dart @@ -169,12 +169,11 @@ class PerfettoControllerImpl extends PerfettoController { ); _initialized = true; - _perfettoIFrame = - HTMLIFrameElement() - // This url is safe because we built it ourselves and it does not include - // any user input. - ..src = perfettoUrl - ..allow = 'usb'; + _perfettoIFrame = HTMLIFrameElement() + // This url is safe because we built it ourselves and it does not include + // any user input. + ..src = perfettoUrl + ..allow = 'usb'; _perfettoIFrame.style ..border = 'none' ..height = '100%' diff --git a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/tracing/model.dart b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/tracing/model.dart index de836a1614b..c2ec2f4d12b 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/tracing/model.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/perfetto/tracing/model.dart @@ -39,10 +39,9 @@ class PerfettoTrackDescriptorEvent extends _PerfettoTracePacket { final TrackDescriptor trackDescriptor; - String get name => - trackDescriptor.name.isNotEmpty - ? trackDescriptor.name - : trackDescriptor.thread.threadName; + String get name => trackDescriptor.name.isNotEmpty + ? trackDescriptor.name + : trackDescriptor.thread.threadName; Int64 get id => trackDescriptor.uuid; diff --git a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_event_processor.dart b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_event_processor.dart index ae1071e26e0..a6b4e4ce1a4 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_event_processor.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_event_processor.dart @@ -34,8 +34,8 @@ class FlutterTimelineEventProcessor { /// The Flutter frame range that we have processed track events for. Range? get frameRangeFromTimelineEvents => _startFrameId == null || _endFrameId == null - ? null - : Range(_startFrameId!, _endFrameId!); + ? null + : Range(_startFrameId!, _endFrameId!); int? _startFrameId; int? _endFrameId; diff --git a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart index b1a88145451..f016506bde3 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart @@ -52,8 +52,9 @@ class TimelineEventsController extends PerformanceFeatureController static const gpuThreadSuffix = '.gpu'; static const platformThreadSuffix = '.platform'; static const flutterTestThreadSuffix = '.flutter.test..ui'; - static final _refreshWorkTrackerDelay = - const Duration(milliseconds: 500).inMicroseconds; + static final _refreshWorkTrackerDelay = const Duration( + milliseconds: 500, + ).inMicroseconds; /// Controller that contains business logic for the Perfetto trace viewer. late final PerfettoController perfettoController; @@ -83,8 +84,11 @@ class TimelineEventsController extends PerformanceFeatureController /// Size limit in GB for [traceRingBuffer] that determines when traces should /// be removed from the queue. - final _traceRingBufferSize = - convertBytes(1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + final _traceRingBufferSize = convertBytes( + 1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); /// Track events that we have received from the VM, but have not yet /// processed. @@ -357,12 +361,11 @@ class TimelineEventsController extends PerformanceFeatureController ga.timeSync( gac.performance, gac.PerformanceEvents.perfettoModeTraceEventProcessingTime.nameOverride!, - syncOperation: - () => perfettoController.processor.processTrackEvents( - _unprocessedTrackEvents, - ), - screenMetricsProvider: - () => PerformanceScreenMetrics(traceEventCount: eventCount), + syncOperation: () => perfettoController.processor.processTrackEvents( + _unprocessedTrackEvents, + ), + screenMetricsProvider: () => + PerformanceScreenMetrics(traceEventCount: eventCount), ); _unprocessedTrackEvents.clear(); } @@ -488,7 +491,7 @@ class TimelineEventsController extends PerformanceFeatureController return offlineDataController.showingOfflineData.value ? offlineData != null && offlineData.frames.isNotEmpty : serviceConnection.serviceManager.connectedApp?.isFlutterAppNow ?? - false; + false; } void _maybePushNoTimelineEventsWarning() { diff --git a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_view.dart b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_view.dart index 1a44da58283..682b3702817 100644 --- a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_view.dart +++ b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_view.dart @@ -181,10 +181,9 @@ class RefreshTimelineEventsButton extends StatelessWidget { return RefreshButton( iconOnly: true, outlined: false, - onPressed: - status == EventsControllerStatus.refreshing - ? null - : controller.forceRefresh, + onPressed: status == EventsControllerStatus.refreshing + ? null + : controller.forceRefresh, tooltip: 'Refresh timeline events', gaScreen: gac.performance, gaSelection: gac.PerformanceEvents.refreshTimelineEvents.name, @@ -249,7 +248,9 @@ class _TimelineSettingsDialogState extends State List _defaultRecordedStreams(ThemeData theme) { return [ ...dialogSubHeader(theme, 'Trace categories'), - RichText(text: TextSpan(text: 'Default', style: theme.subtleTextStyle)), + RichText( + text: TextSpan(text: 'Default', style: theme.subtleTextStyle), + ), ..._timelineStreams(advanced: false), // Special case "Network Traffic" because it is not implemented as a // Timeline recorded stream in the VM. The user does not need to be aware of @@ -258,41 +259,40 @@ class _TimelineSettingsDialogState extends State title: 'Network', description: 'Http traffic', notifier: _httpLogging, - onChanged: - (value) => unawaited( - http_service.toggleHttpRequestLogging(value ?? false), - ), + onChanged: (value) => + unawaited(http_service.toggleHttpRequestLogging(value ?? false)), ), ]; } List _advancedStreams(ThemeData theme) { return [ - RichText(text: TextSpan(text: 'Advanced', style: theme.subtleTextStyle)), + RichText( + text: TextSpan(text: 'Advanced', style: theme.subtleTextStyle), + ), ..._timelineStreams(advanced: true), ]; } List _timelineStreams({required bool advanced}) { - final streams = - advanced - ? serviceConnection.timelineStreamManager.advancedStreams - : serviceConnection.timelineStreamManager.basicStreams; - final settings = - streams - .map( - (stream) => CheckboxSetting( - title: stream.name, - description: stream.description, - notifier: stream.recorded as ValueNotifier, - onChanged: - (newValue) => unawaited( - serviceConnection.timelineStreamManager - .updateTimelineStream(stream, newValue ?? false), - ), + final streams = advanced + ? serviceConnection.timelineStreamManager.advancedStreams + : serviceConnection.timelineStreamManager.basicStreams; + final settings = streams + .map( + (stream) => CheckboxSetting( + title: stream.name, + description: stream.description, + notifier: stream.recorded as ValueNotifier, + onChanged: (newValue) => unawaited( + serviceConnection.timelineStreamManager.updateTimelineStream( + stream, + newValue ?? false, ), - ) - .toList(); + ), + ), + ) + .toList(); return settings; } } diff --git a/packages/devtools_app/lib/src/screens/performance/performance_controller.dart b/packages/devtools_app/lib/src/screens/performance/performance_controller.dart index c15d9311494..cfb4469afca 100644 --- a/packages/devtools_app/lib/src/screens/performance/performance_controller.dart +++ b/packages/devtools_app/lib/src/screens/performance/performance_controller.dart @@ -280,14 +280,13 @@ class PerformanceController extends DevToolsScreenController @override OfflineScreenData prepareOfflineScreenData() => OfflineScreenData( screenId: PerformanceScreen.id, - data: - OfflinePerformanceData( - perfettoTraceBinary: timelineEventsController.fullPerfettoTrace, - frames: flutterFramesController.flutterFrames.value, - selectedFrame: flutterFramesController.selectedFrame.value, - rebuildCountModel: rebuildCountModel, - displayRefreshRate: flutterFramesController.displayRefreshRate.value, - ).toJson(), + data: OfflinePerformanceData( + perfettoTraceBinary: timelineEventsController.fullPerfettoTrace, + frames: flutterFramesController.flutterFrames.value, + selectedFrame: flutterFramesController.selectedFrame.value, + rebuildCountModel: rebuildCountModel, + displayRefreshRate: flutterFramesController.displayRefreshRate.value, + ).toJson(), ); @override diff --git a/packages/devtools_app/lib/src/screens/performance/performance_model.dart b/packages/devtools_app/lib/src/screens/performance/performance_model.dart index b7b51cd814d..fbd4b4eaee8 100644 --- a/packages/devtools_app/lib/src/screens/performance/performance_model.dart +++ b/packages/devtools_app/lib/src/screens/performance/performance_model.dart @@ -69,8 +69,8 @@ class OfflinePerformanceData { extension type _PerformanceDataJson(Map json) { Uint8List? get traceBinary { - final value = - (json[OfflinePerformanceData.traceBinaryKey] as List?)?.cast(); + final value = (json[OfflinePerformanceData.traceBinaryKey] as List?) + ?.cast(); return value == null ? null : Uint8List.fromList(value); } @@ -138,10 +138,9 @@ class FlutterTimelineEvent extends TreeNode { } copy ..type = type - ..time = - (TimeRange() - ..start = time.start - ..end = time.end); + ..time = (TimeRange() + ..start = time.start + ..end = time.end); return copy; } diff --git a/packages/devtools_app/lib/src/screens/performance/performance_screen.dart b/packages/devtools_app/lib/src/screens/performance/performance_screen.dart index acf70f17942..ac10baf610d 100644 --- a/packages/devtools_app/lib/src/screens/performance/performance_screen.dart +++ b/packages/devtools_app/lib/src/screens/performance/performance_screen.dart @@ -180,7 +180,8 @@ const profileModeLink = 'https://flutter.dev/to/profile-mode'; const performancePanelLink = 'https://developer.chrome.com/docs/devtools/performance'; -const flutterWebInstructionsMd = ''' +const flutterWebInstructionsMd = + ''' ## How to use Chrome DevTools for performance profiling The Flutter framework emits timeline events as it works to build frames, draw @@ -206,7 +207,8 @@ performance analysis. your application, and start recording to capture timeline events. '''; -const dartWebInstructionsMd = ''' +const dartWebInstructionsMd = + ''' ## How to use Chrome DevTools for performance profiling Any events emitted using the `dart:developer` [Timeline]($timelineLink) and diff --git a/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart b/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart index f9f15a924f8..05eef54cd1c 100644 --- a/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart +++ b/packages/devtools_app/lib/src/screens/performance/tabbed_performance_view.dart @@ -73,12 +73,12 @@ class _TabbedPerformanceViewState extends State showFrameAnalysis: showFrameAnalysis, showRebuildStats: showRebuildStats, ); - final tabs = - tabsAndControllers - .map((t) => (tab: t.tab, tabView: t.tabView)) - .toList(); - final featureControllers = - tabsAndControllers.map((t) => t.featureController).toList(); + final tabs = tabsAndControllers + .map((t) => (tab: t.tab, tabView: t.tabView)) + .toList(); + final featureControllers = tabsAndControllers + .map((t) => t.featureController) + .toList(); // If there is not an active feature, activate the first. if (featureControllers.firstWhereOrNull( @@ -125,19 +125,18 @@ class _TabbedPerformanceViewState extends State ( tab: _buildTab(tabName: 'Frame Analysis'), tabView: KeepAliveWrapper( - child: - _selectedFlutterFrame != null - ? FlutterFrameAnalysisView( - frame: _selectedFlutterFrame!, - enhanceTracingController: - controller.enhanceTracingController, - rebuildCountModel: controller.rebuildCountModel, - displayRefreshRateNotifier: - controller.flutterFramesController.displayRefreshRate, - ) - : const CenteredMessage( - message: 'Select a frame above to view analysis data.', - ), + child: _selectedFlutterFrame != null + ? FlutterFrameAnalysisView( + frame: _selectedFlutterFrame!, + enhanceTracingController: + controller.enhanceTracingController, + rebuildCountModel: controller.rebuildCountModel, + displayRefreshRateNotifier: + controller.flutterFramesController.displayRefreshRate, + ) + : const CenteredMessage( + message: 'Select a frame above to view analysis data.', + ), ), featureController: null, ), diff --git a/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart b/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart index b05bc7fa821..060c2c79b90 100644 --- a/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart +++ b/packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart @@ -190,14 +190,13 @@ class CpuProfileData with Serializable { sampleCount: json.sampleCount ?? 0, samplePeriod: samplePeriod, stackDepth: json.stackDepth ?? 0, - time: - (json.timeOriginMicros != null && json.timeExtentMicros != null) - ? (TimeRange() - ..start = Duration(microseconds: json.timeOriginMicros!) - ..end = Duration( - microseconds: json.timeOriginMicros! + json.timeExtentMicros!, - )) - : null, + time: (json.timeOriginMicros != null && json.timeExtentMicros != null) + ? (TimeRange() + ..start = Duration(microseconds: json.timeOriginMicros!) + ..end = Duration( + microseconds: json.timeOriginMicros! + json.timeExtentMicros!, + )) + : null, ); // Initialize all stack frames. @@ -241,14 +240,13 @@ class CpuProfileData with Serializable { ) { // Each sample in [subSamples] will have the leaf stack // frame id for a cpu sample within [subTimeRange]. - final subSamples = - superProfile.cpuSamples - .where( - (sample) => subTimeRange.contains( - Duration(microseconds: sample.timestampMicros!), - ), - ) - .toList(); + final subSamples = superProfile.cpuSamples + .where( + (sample) => subTimeRange.contains( + Duration(microseconds: sample.timestampMicros!), + ), + ) + .toList(); final subStackFrames = {}; for (final sample in subSamples) { @@ -348,10 +346,9 @@ class CpuProfileData with Serializable { profileMetaData: metaData, parentId: parentId, ); - final parentStackFrameJson = - parentId != null - ? originalData.stackFrames[currentStackFrame.parentId] - : null; + final parentStackFrameJson = parentId != null + ? originalData.stackFrames[currentStackFrame.parentId] + : null; updatedId = parentId; currentStackFrame = parentStackFrameJson; } @@ -384,12 +381,9 @@ class CpuProfileData with Serializable { return CpuProfileData.empty(); } - final samplesWithTag = - originalData.cpuSamples - .where( - (sample) => (useUserTag ? sample.userTag : sample.vmTag) == tag, - ) - .toList(); + final samplesWithTag = originalData.cpuSamples + .where((sample) => (useUserTag ? sample.userTag : sample.vmTag) == tag) + .toList(); assert(samplesWithTag.isNotEmpty); final microsPerSample = originalData.profileMetaData.samplePeriod; @@ -400,15 +394,13 @@ class CpuProfileData with Serializable { // for this profile data, and the samples included in this data could be // sparse over the original profile's time range, so true start and end // times wouldn't be helpful. - time: - TimeRange() - ..start = const Duration() - ..end = Duration( - microseconds: - microsPerSample.isInfinite - ? 0 - : (newSampleCount * microsPerSample).round(), - ), + time: TimeRange() + ..start = const Duration() + ..end = Duration( + microseconds: microsPerSample.isInfinite + ? 0 + : (newSampleCount * microsPerSample).round(), + ), ); final stackFramesWithTag = {}; @@ -423,8 +415,9 @@ class CpuProfileData with Serializable { profileMetaData: metaData, ); final parentId = currentStackFrame.parentId; - final parentStackFrameJson = - parentId != null ? originalData.stackFrames[parentId] : null; + final parentStackFrameJson = parentId != null + ? originalData.stackFrames[parentId] + : null; currentId = parentId; currentStackFrame = parentStackFrameJson; } @@ -506,15 +499,13 @@ class CpuProfileData with Serializable { // for this profile data, and the samples included in this data could be // sparse over the original profile's time range, so true start and end // times wouldn't be helpful. - time: - TimeRange() - ..start = const Duration() - ..end = Duration( - microseconds: - microsPerSample.isInfinite || microsPerSample.isNaN - ? 0 - : (filteredCpuSamples.length * microsPerSample).round(), - ), + time: TimeRange() + ..start = const Duration() + ..end = Duration( + microseconds: microsPerSample.isInfinite || microsPerSample.isNaN + ? 0 + : (filteredCpuSamples.length * microsPerSample).round(), + ), ); void walkAndFilter(CpuStackFrame stackFrame) { @@ -834,8 +825,8 @@ class CpuSampleEvent extends ChromeTraceEvent { factory CpuSampleEvent.fromJson(Map traceJson) { final leafId = traceJson[CpuProfileData.stackFrameIdKey]! as String; - final args = - (traceJson[ChromeTraceEvent.argsKey] as Map?)?.cast(); + final args = (traceJson[ChromeTraceEvent.argsKey] as Map?) + ?.cast(); final userTag = args?[CpuProfileData.userTagKey] as String?; final vmTag = args?[CpuProfileData.vmTagKey] as String?; return CpuSampleEvent( @@ -963,27 +954,24 @@ class CpuStackFrame extends TreeNode /// samples are being grouped by tag. final bool isTag; - bool get isNative => - _isNative ??= - id != CpuProfileData.rootId && - packageUri.isEmpty && - !name.startsWith(PackagePrefixes.flutterEngine) && - !isTag; + bool get isNative => _isNative ??= + id != CpuProfileData.rootId && + packageUri.isEmpty && + !name.startsWith(PackagePrefixes.flutterEngine) && + !isTag; bool? _isNative; - bool get isDartCore => - _isDartCore ??= - packageUri.startsWith(PackagePrefixes.dart) && - !packageUri.startsWith(PackagePrefixes.dartUi); + bool get isDartCore => _isDartCore ??= + packageUri.startsWith(PackagePrefixes.dart) && + !packageUri.startsWith(PackagePrefixes.dartUi); bool? _isDartCore; - bool get isFlutterCore => - _isFlutterCore ??= - packageUri.startsWith(PackagePrefixes.flutterPackage) || - name.startsWith(PackagePrefixes.flutterEngine) || - packageUri.startsWith(PackagePrefixes.dartUi); + bool get isFlutterCore => _isFlutterCore ??= + packageUri.startsWith(PackagePrefixes.flutterPackage) || + name.startsWith(PackagePrefixes.flutterEngine) || + packageUri.startsWith(PackagePrefixes.dartUi); bool? _isFlutterCore; @@ -1206,8 +1194,9 @@ class _CpuProfileTimelineTree { // TODO(bkonyi): handle truncated? for (final sample in cpuSamples.samples ?? []) { current = root; - final stack = - asCodeProfileTimelineTree ? sample.codeStack : sample.stack!; + final stack = asCodeProfileTimelineTree + ? sample.codeStack + : sample.stack!; // Build an inclusive trie. for (final index in stack.reversed) { current = current._getChild(index); @@ -1264,14 +1253,13 @@ class _CpuProfileTimelineTree { return null; } - String? get resolvedUrl => - isCodeTree && _function is vm_service.FuncRef? - ? - // TODO(bkonyi): not sure if this is a resolved URL or not, but it's not - // critical since this is only displayed when VM developer mode is - // enabled. - (_function as vm_service.FuncRef?)?.location?.script?.uri - : samples.functions?[index].resolvedUrl; + String? get resolvedUrl => isCodeTree && _function is vm_service.FuncRef? + ? + // TODO(bkonyi): not sure if this is a resolved URL or not, but it's not + // critical since this is only displayed when VM developer mode is + // enabled. + (_function as vm_service.FuncRef?)?.location?.script?.uri + : samples.functions?[index].resolvedUrl; int? get sourceLine { final function = _function; diff --git a/packages/devtools_app/lib/src/screens/profiler/cpu_profile_service.dart b/packages/devtools_app/lib/src/screens/profiler/cpu_profile_service.dart index f65506d4e0d..4628cee67fe 100644 --- a/packages/devtools_app/lib/src/screens/profiler/cpu_profile_service.dart +++ b/packages/devtools_app/lib/src/screens/profiler/cpu_profile_service.dart @@ -18,13 +18,12 @@ extension CpuProfilerExtension on VmService { // Grab the value of this flag before doing asynchronous work. final vmDeveloperModeEnabled = preferences.vmDeveloperModeEnabled.value; - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; final cpuSamples = await serviceConnection.serviceManager.service! .getCpuSamples(isolateId, startMicros, extentMicros); @@ -37,8 +36,8 @@ extension CpuProfilerExtension on VmService { const kSamples = 'samples'; const kCodeStack = '_codeStack'; - final rawSamples = - (cpuSamples.json![kSamples] as List).cast>(); + final rawSamples = (cpuSamples.json![kSamples] as List) + .cast>(); bool buildCodeProfile = false; if (rawSamples.isNotEmpty && rawSamples.first.containsKey(kCodeStack)) { diff --git a/packages/devtools_app/lib/src/screens/profiler/cpu_profiler.dart b/packages/devtools_app/lib/src/screens/profiler/cpu_profiler.dart index 0a2953f7845..23c9d93dad5 100644 --- a/packages/devtools_app/lib/src/screens/profiler/cpu_profiler.dart +++ b/packages/devtools_app/lib/src/screens/profiler/cpu_profiler.dart @@ -283,9 +283,8 @@ class _CpuProfilerState extends State unawaited( showDialog( context: context, - builder: - (context) => - FilterDialog(controller: widget.controller), + builder: (context) => + FilterDialog(controller: widget.controller), ), ); } @@ -324,10 +323,9 @@ class _CpuProfilerState extends State void Function(CpuStackFrame root) callback, Tab currentTab, ) { - final roots = - currentTab.key == ProfilerTab.callTree.key - ? widget.callTreeRoots - : widget.bottomUpRoots; + final roots = currentTab.key == ProfilerTab.callTree.key + ? widget.callTreeRoots + : widget.bottomUpRoots; setState(() { roots.forEach(callback); }); @@ -348,10 +346,9 @@ class CpuProfileStats extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); final samplePeriodValid = metadata.samplePeriod > 0; - final samplingPeriodDisplay = - samplePeriodValid - ? const Duration(seconds: 1).inMicroseconds ~/ metadata.samplePeriod - : '--'; + final samplingPeriodDisplay = samplePeriodValid + ? const Duration(seconds: 1).inMicroseconds ~/ metadata.samplePeriod + : '--'; return RoundedOutlinedBorder.onlyBottom( child: Container( height: _statsRowHeight, diff --git a/packages/devtools_app/lib/src/screens/profiler/cpu_profiler_controller.dart b/packages/devtools_app/lib/src/screens/profiler/cpu_profiler_controller.dart index 9b5bb32a8d5..4caea9b1072 100644 --- a/packages/devtools_app/lib/src/screens/profiler/cpu_profiler_controller.dart +++ b/packages/devtools_app/lib/src/screens/profiler/cpu_profiler_controller.dart @@ -224,10 +224,9 @@ class CpuProfilerController extends DisposableController /// Clients interested in the current value of [profilerFlagNotifier] should /// use this getter. Otherwise, clients subscribing to change notifications, /// should listen to [profilerFlagNotifier]. - bool get profilerEnabled => - offlineDataController.showingOfflineData.value - ? true - : profilerFlagNotifier?.value.valueAsString == 'true'; + bool get profilerEnabled => offlineDataController.showingOfflineData.value + ? true + : profilerFlagNotifier?.value.valueAsString == 'true'; Future enableCpuProfiler() { return serviceConnection.serviceManager.service!.enableCpuProfiler(); @@ -271,11 +270,10 @@ class CpuProfilerController extends DisposableController gac.cpuProfiler, gac.CpuProfilerEvents.cpuProfileProcessingTime.name, asyncOperation: pullAndProcessHelper, - screenMetricsProvider: - () => ProfilerScreenMetrics( - cpuSampleCount: cpuProfiles.profileMetaData.sampleCount, - cpuStackDepth: cpuProfiles.profileMetaData.stackDepth, - ), + screenMetricsProvider: () => ProfilerScreenMetrics( + cpuSampleCount: cpuProfiles.profileMetaData.sampleCount, + cpuStackDepth: cpuProfiles.profileMetaData.stackDepth, + ), ); } on ProcessCancelledException catch (_) { // Do nothing for instances of [ProcessCancelledException]. @@ -543,14 +541,12 @@ class CpuProfilerController extends DisposableController label: tag, createIfAbsent: () { final fullData = cpuProfileStore.lookupProfile(label: userTagNone)!; - final tagType = - tag == groupByUserTag - ? CpuProfilerTagType.user - : CpuProfilerTagType.vm; - final data = - tag == groupByUserTag || tag == groupByVmTag - ? CpuProfilePair.withTagRoots(fullData, tagType) - : CpuProfilePair.fromUserTag(fullData, tag); + final tagType = tag == groupByUserTag + ? CpuProfilerTagType.user + : CpuProfilerTagType.vm; + final data = tag == groupByUserTag || tag == groupByVmTag + ? CpuProfilePair.withTagRoots(fullData, tagType) + : CpuProfilePair.fromUserTag(fullData, tag); cpuProfileStore.storeProfile(data, label: tag); return data; }, diff --git a/packages/devtools_app/lib/src/screens/profiler/panes/bottom_up.dart b/packages/devtools_app/lib/src/screens/profiler/panes/bottom_up.dart index 3cf2cecf6bb..d12cfe5af77 100644 --- a/packages/devtools_app/lib/src/screens/profiler/panes/bottom_up.dart +++ b/packages/devtools_app/lib/src/screens/profiler/panes/bottom_up.dart @@ -18,15 +18,13 @@ class CpuBottomUpTable extends StatelessWidget { static final methodColumn = MethodAndSourceColumn(); static final selfTimeColumn = SelfTimeColumn( titleTooltip: selfTimeTooltip, - dataTooltipProvider: - (stackFrame, context) => - _bottomUpTimeTooltipBuilder(_TimeType.self, stackFrame, context), + dataTooltipProvider: (stackFrame, context) => + _bottomUpTimeTooltipBuilder(_TimeType.self, stackFrame, context), ); static final totalTimeColumn = TotalTimeColumn( titleTooltip: totalTimeTooltip, - dataTooltipProvider: - (stackFrame, context) => - _bottomUpTimeTooltipBuilder(_TimeType.total, stackFrame, context), + dataTooltipProvider: (stackFrame, context) => + _bottomUpTimeTooltipBuilder(_TimeType.total, stackFrame, context), ); static final columns = List>.unmodifiable([ totalTimeColumn, diff --git a/packages/devtools_app/lib/src/screens/profiler/panes/controls/cpu_profiler_controls.dart b/packages/devtools_app/lib/src/screens/profiler/panes/controls/cpu_profiler_controls.dart index 5d62d2ba543..88e818e204e 100644 --- a/packages/devtools_app/lib/src/screens/profiler/panes/controls/cpu_profiler_controls.dart +++ b/packages/devtools_app/lib/src/screens/profiler/panes/controls/cpu_profiler_controls.dart @@ -24,10 +24,9 @@ class UserTagDropdown extends StatelessWidget { valueListenable: controller.userTagFilter, builder: (context, userTag, _) { final userTags = controller.userTags; - final tooltip = - userTags.isNotEmpty - ? 'Filter the CPU profile by the given UserTag' - : 'No UserTags found for this CPU profile'; + final tooltip = userTags.isNotEmpty + ? 'Filter the CPU profile by the given UserTag' + : 'No UserTags found for this CPU profile'; return SizedBox( height: defaultButtonHeight, child: DevToolsTooltip( @@ -67,10 +66,10 @@ class UserTagDropdown extends StatelessWidget { ], onChanged: userTags.isEmpty || - (userTags.length == 1 && - userTags.first == UserTag.defaultTag.label) - ? null - : (String? tag) => _onUserTagChanged(tag!), + (userTags.length == 1 && + userTags.first == UserTag.defaultTag.label) + ? null + : (String? tag) => _onUserTagChanged(tag!), ); }, ), @@ -109,13 +108,12 @@ class ModeDropdown extends StatelessWidget { return ValueListenableBuilder( valueListenable: controller.viewType, builder: (context, viewType, _) { - final tooltip = - viewType == CpuProfilerViewType.function - ? 'Display the profile in terms of the Dart call stack ' - '(i.e., inlined frames are expanded)' - : 'Display the profile in terms of native stack frames ' - '(i.e., inlined frames are not expanded, display code objects ' - 'rather than individual functions)'; + final tooltip = viewType == CpuProfilerViewType.function + ? 'Display the profile in terms of the Dart call stack ' + '(i.e., inlined frames are expanded)' + : 'Display the profile in terms of native stack frames ' + '(i.e., inlined frames are not expanded, display code objects ' + 'rather than individual functions)'; return SizedBox( height: defaultButtonHeight, child: DevToolsTooltip( diff --git a/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart b/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart index 0ac0e2c8129..b3d1714c33e 100644 --- a/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart +++ b/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart @@ -71,8 +71,9 @@ class _PrimaryControls extends StatelessWidget { gaSelection: recording ? gac.stop : gac.record, minScreenWidthForTextBeforeScaling: _primaryControlsMinIncludeTextWidth, - onPressed: - recording ? controller.stopRecording : controller.startRecording, + onPressed: recording + ? controller.stopRecording + : controller.startRecording, ), const SizedBox(width: denseSpacing), ClearButton( @@ -119,10 +120,9 @@ class _SecondaryControls extends StatelessWidget { gaSelection: gac.CpuProfilerEvents.profileAppStartUp.name, minScreenWidthForTextBeforeScaling: _profilingControlsMinScreenWidthForText, - onPressed: - !profilerBusy - ? controller.cpuProfilerController.loadAppStartUpProfile - : null, + onPressed: !profilerBusy + ? controller.cpuProfilerController.loadAppStartUpProfile + : null, ), const SizedBox(width: denseSpacing), RefreshButton( @@ -133,10 +133,9 @@ class _SecondaryControls extends StatelessWidget { gaSelection: gac.CpuProfilerEvents.loadAllCpuSamples.name, minScreenWidthForTextBeforeScaling: _profilingControlsMinScreenWidthForText, - onPressed: - !profilerBusy - ? controller.cpuProfilerController.loadAllSamples - : null, + onPressed: !profilerBusy + ? controller.cpuProfilerController.loadAllSamples + : null, ), const SizedBox(width: denseSpacing), CpuSamplingRateDropdown( @@ -149,10 +148,10 @@ class _SecondaryControls extends StatelessWidget { screenId: ScreenMetaData.cpuProfiler.id, onSave: !profilerBusy && - controller.cpuProfileData != null && - controller.cpuProfileData?.isEmpty == false - ? (_) => _exportPerformance() - : null, + controller.cpuProfileData != null && + controller.cpuProfileData?.isEmpty == false + ? (_) => _exportPerformance() + : null, ), ], ); diff --git a/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table.dart b/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table.dart index aab1240699a..6c87dc8e10b 100644 --- a/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table.dart +++ b/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table.dart @@ -114,12 +114,12 @@ class _MethodGraphState extends State<_MethodGraph> with AutoDisposeMixin { _callers = []; _callees = []; } else { - _callers = - _selectedGraphNode!.predecessors - .cast() - .toList(); - _callees = - _selectedGraphNode!.successors.cast().toList(); + _callers = _selectedGraphNode!.predecessors + .cast() + .toList(); + _callees = _selectedGraphNode!.successors + .cast() + .toList(); } } @@ -304,8 +304,8 @@ class _CallerTimeColumn extends TimeAndPercentageColumn { : super( title: 'Caller %', percentageOnly: true, - percentAsDoubleProvider: - (node) => methodTableController.callerPercentageFor(node), + percentAsDoubleProvider: (node) => + methodTableController.callerPercentageFor(node), secondaryCompare: (node) => node.name, columnWidth: _callGraphColumnWidth, ); @@ -316,8 +316,8 @@ class _CalleeTimeColumn extends TimeAndPercentageColumn { : super( title: 'Callee %', percentageOnly: true, - percentAsDoubleProvider: - (node) => methodTableController.calleePercentageFor(node), + percentAsDoubleProvider: (node) => + methodTableController.calleePercentageFor(node), secondaryCompare: (node) => node.name, columnWidth: _callGraphColumnWidth, ); diff --git a/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table_controller.dart b/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table_controller.dart index 8f9409a8771..14ec9c082f5 100644 --- a/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table_controller.dart +++ b/packages/devtools_app/lib/src/screens/profiler/panes/method_table/method_table_controller.dart @@ -75,20 +75,20 @@ class MethodTableController extends DisposableController action: (CpuStackFrame frame) { final parentNode = frame.parent != null && - frame.parentId != CpuProfileData.rootId && - !frame.parent!.isTag - // Since we are performing a DFS, the parent should always be in - // the map. - ? methodMap[frame.parent!.methodTableId]! - : null; + frame.parentId != CpuProfileData.rootId && + !frame.parent!.isTag + // Since we are performing a DFS, the parent should always be in + // the map. + ? methodMap[frame.parent!.methodTableId]! + : null; var graphNode = MethodTableGraphNode.fromStackFrame(frame); final existingNode = methodMap[frame.methodTableId]; if (existingNode != null) { // Do not merge the total time if the [existingNode] already counted // the total time for one of [frame]'s ancestors. - final shouldMergeTotalTime = - !existingNode.stackFrameIds.containsAny(frame.ancestorIds); + final shouldMergeTotalTime = !existingNode.stackFrameIds + .containsAny(frame.ancestorIds); // If the graph node already exists, merge the new one with the old // one and use the existing instance. existingNode.merge(graphNode, mergeTotalTime: shouldMergeTotalTime); diff --git a/packages/devtools_app/lib/src/screens/profiler/profiler_screen.dart b/packages/devtools_app/lib/src/screens/profiler/profiler_screen.dart index 2cfd453af77..cf473f55f24 100644 --- a/packages/devtools_app/lib/src/screens/profiler/profiler_screen.dart +++ b/packages/devtools_app/lib/src/screens/profiler/profiler_screen.dart @@ -131,12 +131,11 @@ class _ProfilerScreenBodyState extends State child: const CenteredCircularProgressIndicator(), ); } - final status = - recording || profilerBusy - ? (recording - ? const RecordingStatus() - : ProfilerBusyStatus(status: profilerBusyStatus)) - : null; + final status = recording || profilerBusy + ? (recording + ? const RecordingStatus() + : ProfilerBusyStatus(status: profilerBusyStatus)) + : null; return Column( children: [ ProfilerScreenControls( diff --git a/packages/devtools_app/lib/src/screens/profiler/profiler_screen_controller.dart b/packages/devtools_app/lib/src/screens/profiler/profiler_screen_controller.dart index 221005bace3..ed392daca19 100644 --- a/packages/devtools_app/lib/src/screens/profiler/profiler_screen_controller.dart +++ b/packages/devtools_app/lib/src/screens/profiler/profiler_screen_controller.dart @@ -67,12 +67,11 @@ class ProfilerScreenController extends DevToolsScreenController addAutoDisposeListener( serviceConnection.serviceManager.isolateManager.selectedIsolate, () { - final selectedIsolate = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value; + final selectedIsolate = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value; if (selectedIsolate != null) { switchToIsolate(selectedIsolate); } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/isolate_statistics/isolate_statistics_view.dart b/packages/devtools_app/lib/src/screens/vm_developer/isolate_statistics/isolate_statistics_view.dart index e2b3668a4d0..77bd8d42c2f 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/isolate_statistics/isolate_statistics_view.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/isolate_statistics/isolate_statistics_view.dart @@ -210,17 +210,16 @@ class TagStatisticsWidget extends StatelessWidget { title: 'Execution Time', roundedTopBorder: false, table: Flexible( - child: - controller.cpuProfilerController.profilerEnabled - ? FlatTable( - keyFactory: (VMTag tag) => ValueKey(tag.name), - data: controller.tags, - dataKey: 'tag-statistics', - columns: _columns, - defaultSortColumn: _percentage, - defaultSortDirection: SortDirection.descending, - ) - : CpuProfilerDisabled(controller.cpuProfilerController), + child: controller.cpuProfilerController.profilerEnabled + ? FlatTable( + keyFactory: (VMTag tag) => ValueKey(tag.name), + data: controller.tags, + dataKey: 'tag-statistics', + columns: _columns, + defaultSortColumn: _percentage, + defaultSortDirection: SortDirection.descending, + ) + : CpuProfilerDisabled(controller.cpuProfilerController), ), ), ); @@ -295,29 +294,25 @@ class StackTraceViewerWidget extends StatelessWidget { return ValueListenableBuilder( valueListenable: stackTrace, builder: (context, stackTrace, _) { - final lines = - stackTrace?.allocationLocation?.valueAsString - ?.split('\n') - .where((e) => e.isNotEmpty) - .toList(); + final lines = stackTrace?.allocationLocation?.valueAsString + ?.split('\n') + .where((e) => e.isNotEmpty) + .toList(); return VMInfoList( title: 'Allocation Location', roundedTopBorder: false, - table: - lines == null - ? const Expanded( - child: Center(child: Text('No port selected')), - ) - : Flexible( - child: FlatTable( - keyFactory: (String s) => ValueKey(s), - data: lines, - dataKey: 'stack-trace-viewer', - columns: [frame], - defaultSortColumn: frame, - defaultSortDirection: SortDirection.ascending, - ), + table: lines == null + ? const Expanded(child: Center(child: Text('No port selected'))) + : Flexible( + child: FlatTable( + keyFactory: (String s) => ValueKey(s), + data: lines, + dataKey: 'stack-trace-viewer', + columns: [frame], + defaultSortColumn: frame, + defaultSortDirection: SortDirection.ascending, ), + ), ); }, ); @@ -363,9 +358,8 @@ class _IsolatePortsWidgetState extends State { ), Flexible( child: FlatTable( - keyFactory: - (InstanceRef? port) => - ValueKey(port!.debugName!), + keyFactory: (InstanceRef? port) => + ValueKey(port!.debugName!), data: ports, dataKey: 'isolate-ports', columns: _columns, diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer.dart index 474126ab8fe..08cd597357e 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer.dart @@ -32,11 +32,10 @@ class ClassHierarchyExplorer extends StatelessWidget { return TreeView( dataRootsListenable: controller.classHierarchyController.selectedIsolateClassHierarchy, - dataDisplayProvider: - (node, onPressed) => VmServiceObjectLink( - object: node.cls, - onTap: controller.findAndSelectNodeForObject, - ), + dataDisplayProvider: (node, onPressed) => VmServiceObjectLink( + object: node.cls, + onTap: controller.findAndSelectNodeForObject, + ), emptyTreeViewBuilder: () => const CenteredCircularProgressIndicator(), ); } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer_controller.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer_controller.dart index 11b7cad4541..04433788139 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer_controller.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/class_hierarchy_explorer_controller.dart @@ -27,11 +27,10 @@ class ClassHierarchyExplorerController extends DisposableController { final isolateId = isolate.id!; final classList = await service.getClassList(isolateId); // TODO(bkonyi): we should cache the class list like we do the script list - final classes = - await [ - for (final cls in classList.classes!) - service.getObject(isolateId, cls.id!).then((e) => e as Class), - ].wait; + final classes = await [ + for (final cls in classList.classes!) + service.getObject(isolateId, cls.id!).then((e) => e as Class), + ].wait; buildHierarchy(classes); } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_inspector_view.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_inspector_view.dart index 8938136e11d..76249c3402e 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_inspector_view.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_inspector_view.dart @@ -45,8 +45,8 @@ class _ObjectInspectorViewState extends State<_ObjectInspectorView> void didChangeDependencies() { super.didChangeDependencies(); - final vmDeveloperToolsController = - screenControllers.lookup(); + final vmDeveloperToolsController = screenControllers + .lookup(); controller = vmDeveloperToolsController.objectInspectorViewController; unawaited(controller.init()); } @@ -83,8 +83,8 @@ class _ObjectInspectorSelectorState extends State { @override void didChangeDependencies() { super.didChangeDependencies(); - final vmDeveloperToolsController = - screenControllers.lookup(); + final vmDeveloperToolsController = screenControllers + .lookup(); controller = vmDeveloperToolsController.objectInspectorViewController; unawaited(controller.init()); } @@ -117,10 +117,9 @@ class _ObjectInspectorSelectorState extends State { gac.classHierarchy, ), ], - onChanged: - (newValue) => setState(() { - value = newValue!; - }), + onChanged: (newValue) => setState(() { + value = newValue!; + }), ), Expanded( child: RoundedOutlinedBorder( diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_viewport.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_viewport.dart index fc23701d265..37084d17a67 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_viewport.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/object_viewport.dart @@ -45,10 +45,9 @@ class ObjectViewport extends StatelessWidget { child = const CenteredCircularProgressIndicator(); } else { final currentObject = controller.objectHistory.current.value; - child = - currentObject == null - ? const SizedBox.shrink() - : buildObjectDisplay(currentObject); + child = currentObject == null + ? const SizedBox.shrink() + : buildObjectDisplay(currentObject); } return Expanded(child: child); diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_field_display.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_field_display.dart index 92214383070..c30182d6407 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_field_display.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_field_display.dart @@ -79,8 +79,9 @@ class VmFieldDisplay extends StatelessWidget { type = 'Observed types not found'; } - final nullable = - field.guardNullable == null ? '' : _nullMessage(field.guardNullable!); + final nullable = field.guardNullable == null + ? '' + : _nullMessage(field.guardNullable!); return '$type$nullable'; } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_ic_data_display.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_ic_data_display.dart index 99323e858ef..c718d5368d9 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_ic_data_display.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_ic_data_display.dart @@ -69,13 +69,12 @@ class _VmICDataDisplayState extends State { return; } - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; final service = serviceConnection.serviceManager.service!; final argumentsDescriptorFuture = service .getObject(isolateId, icData.argumentsDescriptor.id!) @@ -83,8 +82,10 @@ class _VmICDataDisplayState extends State { final entriesFuture = service .getObject(isolateId, icData.entries.id!) .then((e) => e as Instance); - final (argDescriptor, entryList) = - await (argumentsDescriptorFuture, entriesFuture).wait; + final (argDescriptor, entryList) = await ( + argumentsDescriptorFuture, + entriesFuture, + ).wait; populateLists(argDescriptor, entryList); _initializingCompleter.complete(); } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_instance_display.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_instance_display.dart index 3250f359190..492ad9f8139 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_instance_display.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_instance_display.dart @@ -180,12 +180,11 @@ class DisplayProvider extends StatelessWidget { SelectableText.rich( TextSpan( text: hasName ? variable.name : null, - style: - variable.artificialName - ? theme.subtleFixedFontStyle - : theme.fixedFontStyle.apply( - color: theme.colorScheme.controlFlowSyntaxColor, - ), + style: variable.artificialName + ? theme.subtleFixedFontStyle + : theme.fixedFontStyle.apply( + color: theme.colorScheme.controlFlowSyntaxColor, + ), children: [ if (hasName) TextSpan(text: ': ', style: theme.fixedFontStyle), if (variable.ref!.value is Sentinel) diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_library_display.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_library_display.dart index a21ca800cf3..71529a9eb3e 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_library_display.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_library_display.dart @@ -52,8 +52,9 @@ class VmLibraryDisplay extends StatelessWidget { controller: controller, key: 'URI', preferUri: true, - object: - (library.obj.uri?.isEmpty ?? false) ? library.script! : library.obj, + object: (library.obj.uri?.isEmpty ?? false) + ? library.script! + : library.obj, ), selectableTextBuilderMapEntry('VM Name', library.vmName), ]; diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_object_model.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_object_model.dart index de6408cd57c..c570ddabcf8 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_object_model.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_object_model.dart @@ -72,10 +72,9 @@ abstract class VmObject { _isolate = serviceConnection.serviceManager.isolateManager.selectedIsolate.value!; - _obj = - ref is Obj - ? ref as Obj - : await _service.getObject(_isolate!.id!, ref.id!); + _obj = ref is Obj + ? ref as Obj + : await _service.getObject(_isolate!.id!, ref.id!); if (_sourceLocation != null) { _sourceScript = @@ -198,8 +197,8 @@ class FuncObject extends VmObject { return funcKind == null ? null : FunctionKind.values.firstWhereOrNull( - (element) => element.kind() == funcKind, - ); + (element) => element.kind() == funcKind, + ); } int? get deoptimizations => obj.deoptimizations; @@ -252,8 +251,9 @@ class FieldObject extends VmObject { guardClassKind = obj.guardClassKind(); - guardClass = - guardClassKind == GuardClassKind.single ? await obj.guardClass : null; + guardClass = guardClassKind == GuardClassKind.single + ? await obj.guardClass + : null; } } @@ -327,13 +327,12 @@ class CodeObject extends VmObject { await super.initialize(); final service = serviceConnection.serviceManager.service!; - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; // Attempt to retrieve the CPU profile data for this code object. try { diff --git a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_simple_list_display.dart b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_simple_list_display.dart index 10dcd5df619..e81e1236a17 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_simple_list_display.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/object_inspector/vm_simple_list_display.dart @@ -59,13 +59,12 @@ class _VmSimpleListDisplayState extends State { return; } - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value! - .id!; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value! + .id!; final service = serviceConnection.serviceManager.service!; _initialized = service .getObject(isolateId, elementsInstance.id!) diff --git a/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_tree_columns.dart b/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_tree_columns.dart index 05e9053ac24..80e02f48fb1 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_tree_columns.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_tree_columns.dart @@ -28,7 +28,7 @@ class MemoryColumn extends SizeAndPercentageColumn { : super( title: 'Memory Usage', sizeProvider: (node) => node.byteSize, - percentAsDoubleProvider: - (node) => node.byteSize / controller.treeRoot.value!.byteSize, + percentAsDoubleProvider: (node) => + node.byteSize / controller.treeRoot.value!.byteSize, ); } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_view.dart b/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_view.dart index 11d0899bfe5..2e861886251 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_view.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/process_memory/process_memory_view.dart @@ -193,9 +193,8 @@ class _ProcessMemoryTree extends StatelessWidget { valueListenable: controller.treeRoot, builder: (context, root, _) { return TreeTable( - keyFactory: - (e) => - PageStorageKey('${e.name}+${e.depth}+${e.byteSize}'), + keyFactory: (e) => + PageStorageKey('${e.name}+${e.depth}+${e.byteSize}'), displayTreeGuidelines: true, dataRoots: [if (root != null) root], dataKey: 'process-memory-tree', diff --git a/packages/devtools_app/lib/src/screens/vm_developer/vm_developer_common_widgets.dart b/packages/devtools_app/lib/src/screens/vm_developer/vm_developer_common_widgets.dart index 5ca094fb2f3..dfc2036466a 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/vm_developer_common_widgets.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/vm_developer_common_widgets.dart @@ -212,28 +212,28 @@ class RequestableSizeWidget extends StatelessWidget { final size = sizeProvider(); return size == null ? GaDevToolsButton( - icon: Icons.call_made, - label: 'Request', - outlined: false, - gaScreen: gac.vmTools, - gaSelection: gac.requestSize, - onPressed: requestFunction, - ) + icon: Icons.call_made, + label: 'Request', + outlined: false, + gaScreen: gac.vmTools, + gaSelection: gac.requestSize, + onPressed: requestFunction, + ) : Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text( - size.valueAsString == null - ? '--' - : prettyPrintBytes( - int.parse(size.valueAsString!), - includeUnit: true, - maxBytes: 512, - )!, - ), - ToolbarRefresh(onPressed: requestFunction), - ], - ); + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + size.valueAsString == null + ? '--' + : prettyPrintBytes( + int.parse(size.valueAsString!), + includeUnit: true, + maxBytes: 512, + )!, + ), + ToolbarRefresh(onPressed: requestFunction), + ], + ); } }, ); @@ -368,10 +368,9 @@ class RetainingPathWidget extends StatelessWidget { return ValueListenableBuilder( valueListenable: retainingPath, builder: (context, retainingPath, _) { - final retainingObjects = - retainingPath == null - ? const [] - : _retainingPathList(context, retainingPath); + final retainingObjects = retainingPath == null + ? const [] + : _retainingPathList(context, retainingPath); return VmExpansionTile( title: 'Retaining Path', onExpanded: onExpanded, @@ -379,11 +378,11 @@ class RetainingPathWidget extends StatelessWidget { retainingPath == null ? const SizedCircularProgressIndicator() : SizedBox.fromSize( - size: Size.fromHeight( - retainingObjects.length * defaultRowHeight + densePadding, + size: Size.fromHeight( + retainingObjects.length * defaultRowHeight + densePadding, + ), + child: Column(children: retainingObjects), ), - child: Column(children: retainingObjects), - ), ], ); }, @@ -405,13 +404,12 @@ class RetainingPathWidget extends StatelessWidget { final emptyList = Text('No retaining objects', style: theme.fixedFontStyle); if (retainingPath.elements == null) return [emptyList]; - final firstRetainingObject = - retainingPath.elements!.isNotEmpty - ? VmServiceObjectLink( - object: retainingPath.elements!.first.value, - onTap: onTap, - ) - : emptyList; + final firstRetainingObject = retainingPath.elements!.isNotEmpty + ? VmServiceObjectLink( + object: retainingPath.elements!.first.value, + onTap: onTap, + ) + : emptyList; final retainingObjects = [ Row(children: [firstRetainingObject]), @@ -557,11 +555,8 @@ class InboundReferencesTree extends StatelessWidget { builder: (context, references, _) { return TreeView( dataRootsListenable: object.inboundReferencesTree, - dataDisplayProvider: - (node, _) => InboundReferenceWidget( - controller: controller, - node: node, - ), + dataDisplayProvider: (node, _) => + InboundReferenceWidget(controller: controller, node: node), emptyTreeViewBuilder: () { return Padding( padding: EdgeInsets.all(defaultRowHeight / 2), @@ -704,16 +699,15 @@ class VmServiceObjectLink extends StatelessWidget { return TextSpan( text: text, style: style.apply(overflow: TextOverflow.ellipsis), - recognizer: - isServiceObject - ? (TapGestureRecognizer() - ..onTap = () async { - final obj = object; - if (obj is ObjRef) { - await onTap(obj); - } - }) - : null, + recognizer: isServiceObject + ? (TapGestureRecognizer() + ..onTap = () async { + final obj = object; + if (obj is ObjRef) { + await onTap(obj); + } + }) + : null, ); } @@ -969,8 +963,9 @@ class _ObjectInspectorCodeViewState extends State { location.endTokenPos != null) { final script = currentParsedScript.script; final startLine = location.line!; - final endLine = - script.getLineNumberFromTokenPos(location.endTokenPos!)!; + final endLine = script.getLineNumberFromTokenPos( + location.endTokenPos!, + )!; lineRange = LineRange(startLine, endLine); } } diff --git a/packages/devtools_app/lib/src/screens/vm_developer/vm_service_private_extensions.dart b/packages/devtools_app/lib/src/screens/vm_developer/vm_service_private_extensions.dart index 92239bc404e..725bae84c5d 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/vm_service_private_extensions.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/vm_service_private_extensions.dart @@ -69,8 +69,8 @@ extension InboundReferenceExtension on InboundReferences { int? parentWordOffset(int inboundReferenceIndex) { final references = (json![_referencesKey] as List?)?.cast(); - final inboundReference = - (references?[inboundReferenceIndex] as Map?)?.cast(); + final inboundReference = (references?[inboundReferenceIndex] as Map?) + ?.cast(); return inboundReference?[_parentWordOffsetKey] as int?; } } @@ -100,14 +100,12 @@ extension ClassHeapStatsPrivateViewExtension on ClassHeapStats { static const _newSpaceKey = '_new'; static const _oldSpaceKey = '_old'; - HeapStats get newSpace => - json!.containsKey(_newSpaceKey) - ? HeapStats.parse((json![_newSpaceKey] as List).cast()) - : const HeapStats.empty(); - HeapStats get oldSpace => - json!.containsKey(_oldSpaceKey) - ? HeapStats.parse((json![_oldSpaceKey] as List).cast()) - : const HeapStats.empty(); + HeapStats get newSpace => json!.containsKey(_newSpaceKey) + ? HeapStats.parse((json![_newSpaceKey] as List).cast()) + : const HeapStats.empty(); + HeapStats get oldSpace => json!.containsKey(_oldSpaceKey) + ? HeapStats.parse((json![_oldSpaceKey] as List).cast()) + : const HeapStats.empty(); } extension AllocationProfilePrivateViewExtension on AllocationProfile { @@ -251,8 +249,8 @@ class WeakArray extends WeakArrayRef implements Obj { json: json, length: json['length'], size: json['size'], - elements: - (createServiceObject(json['elements'], []) as List).cast(), + elements: (createServiceObject(json['elements'], []) as List) + .cast(), classRef: createServiceObject(json['class'], [])! as ClassRef, ); @@ -412,10 +410,9 @@ class Instruction { return; } final rawObject = data[3] as Map; - object = - (rawObject['type'] as List).contains('Instance') - ? InstanceRef.parse(rawObject) - : createServiceObject(data[3], const []) as Response?; + object = (rawObject['type'] as List).contains('Instance') + ? InstanceRef.parse(rawObject) + : createServiceObject(data[3], const []) as Response?; } /// The instruction's address in memory. @@ -479,8 +476,8 @@ extension FunctionPrivateViewExtension on Func { String? get vmName => json!['_vmName']; Future get icDataArray async { - final icDataArray = - (json![_icDataArrayKey] as Map?)?.cast(); + final icDataArray = (json![_icDataArrayKey] as Map?) + ?.cast(); final icDataArrayId = icDataArray?['id'] as String?; if (icDataArrayId != null) { final service = serviceConnection.serviceManager.service!; @@ -576,11 +573,10 @@ class InliningData { factory InliningData.fromJson(Map json) { final startAddress = int.parse(json[kStartAddressKey], radix: 16); final intervals = (json[kInlinedIntervals] as List).cast(); - final functions = - (json[kInlinedFunctions] as List) - .cast>() - .map((e) => FuncRef.parse(e)!) - .toList(); + final functions = (json[kInlinedFunctions] as List) + .cast>() + .map((e) => FuncRef.parse(e)!) + .toList(); final entries = []; @@ -654,10 +650,9 @@ class ObjectPool extends ObjectPoolRef implements Obj { return ObjectPool( json: json, id: json[ObjectPoolRef._idKey], - entries: - (json[_entriesKey] as List) - .map((e) => ObjectPoolEntry.parse(e)) - .toList(), + entries: (json[_entriesKey] as List) + .map((e) => ObjectPoolEntry.parse(e)) + .toList(), length: json[ObjectPoolRef._lengthKey], ); } @@ -925,11 +920,10 @@ extension CpuSamplesPrivateView on CpuSamples { } List get codes { - return _expando[this] ??= - (json![_kCodesKey] as List) - .cast>() - .map((e) => ProfileCode.parse(e)!) - .toList(); + return _expando[this] ??= (json![_kCodesKey] as List) + .cast>() + .map((e) => ProfileCode.parse(e)!) + .toList(); } } @@ -961,20 +955,17 @@ class ProfileReportRange { ProfileReportRange._fromJson(Script script, _ProfileReportRangeJson json) { final inclusiveTicks = json.inclusiveTicks; final exclusiveTicks = json.exclusiveTicks; - final lines = - json.positions - .map( - // It's possible to get a synthetic token position which will either - // be a negative value or a String (e.g., 'ParallelMove' or - // 'NoSource'). We'll just use -1 as a placeholder since we won't - // display anything for these tokens anyway. - (e) => - e is int - ? script.getLineNumberFromTokenPos(e) ?? - _kNoSourcePosition - : _kNoSourcePosition, - ) - .toList(); + final lines = json.positions + .map( + // It's possible to get a synthetic token position which will either + // be a negative value or a String (e.g., 'ParallelMove' or + // 'NoSource'). We'll just use -1 as a placeholder since we won't + // display anything for these tokens anyway. + (e) => e is int + ? script.getLineNumberFromTokenPos(e) ?? _kNoSourcePosition + : _kNoSourcePosition, + ) + .toList(); for (int i = 0; i < lines.length; ++i) { final line = lines[i]; entries[line] = ProfileReportEntry( @@ -1016,17 +1007,16 @@ extension type _ProfileReportRangeJson(Map json) { /// information for a given [Script]. class ProfileReport { ProfileReport._fromJson(Script script, Map json) - : _profileRanges = - (json['ranges'] as List) - .cast>() - .where((e) => e.containsKey('profile')) - .map( - (e) => ProfileReportRange._fromJson( - script, - _ProfileReportRangeJson(e), - ), - ) - .toList(); + : _profileRanges = (json['ranges'] as List) + .cast>() + .where((e) => e.containsKey('profile')) + .map( + (e) => ProfileReportRange._fromJson( + script, + _ProfileReportRangeJson(e), + ), + ) + .toList(); List get profileRanges => _profileRanges; final List _profileRanges; diff --git a/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view.dart b/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view.dart index 7861438632e..2845e469e7e 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view.dart @@ -120,8 +120,8 @@ class GeneralVMStatisticsWidget extends StatelessWidget { vm == null ? null : formatDateTime( - DateTime.fromMillisecondsSinceEpoch(vm.startTime!), - ), + DateTime.fromMillisecondsSinceEpoch(vm.startTime!), + ), ), selectableTextBuilderMapEntry('Profiler Mode', vm?.profilerMode), selectableTextBuilderMapEntry( @@ -281,8 +281,9 @@ class IsolatesPreviewWidget extends StatelessWidget { @override Widget build(BuildContext context) { final title = systemIsolates ? 'System Isolates' : 'Isolates'; - final isolates = - systemIsolates ? controller.systemIsolates : controller.isolates; + final isolates = systemIsolates + ? controller.systemIsolates + : controller.isolates; return OutlineDecoration( showLeft: false, showTop: !systemIsolates, diff --git a/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view_controller.dart b/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view_controller.dart index b0a60db4d14..ef9fc361b8a 100644 --- a/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view_controller.dart +++ b/packages/devtools_app/lib/src/screens/vm_developer/vm_statistics/vm_statistics_view_controller.dart @@ -22,8 +22,9 @@ class VMStatisticsViewController extends DisposableController { final vm = await _service.getVM(); _vm = vm; _isolates = await vm.isolates!.map((i) => _service.getIsolate(i.id!)).wait; - _systemIsolates = - await vm.systemIsolates!.map((i) => _service.getIsolate(i.id!)).wait; + _systemIsolates = await vm.systemIsolates! + .map((i) => _service.getIsolate(i.id!)) + .wait; _refreshing.value = false; } diff --git a/packages/devtools_app/lib/src/service/json_to_service_cache.dart b/packages/devtools_app/lib/src/service/json_to_service_cache.dart index f888d2e0114..40d703f543e 100644 --- a/packages/devtools_app/lib/src/service/json_to_service_cache.dart +++ b/packages/devtools_app/lib/src/service/json_to_service_cache.dart @@ -84,8 +84,9 @@ class JsonToServiceCache { id: _nextId(), offset: offset, count: count, - associations: - obj.associations!.getRange(offset, offset + count).toList(), + associations: obj.associations! + .getRange(offset, offset + count) + .toList(), ); return map; } diff --git a/packages/devtools_app/lib/src/service/service_extension_widgets.dart b/packages/devtools_app/lib/src/service/service_extension_widgets.dart index 22823a646cb..3d3f3c95c46 100644 --- a/packages/devtools_app/lib/src/service/service_extension_widgets.dart +++ b/packages/devtools_app/lib/src/service/service_extension_widgets.dart @@ -166,10 +166,9 @@ class _ServiceExtensionButtonGroupState .setServiceExtensionState( extensionState.description.extension, enabled: !wasSelected, - value: - wasSelected - ? extensionState.description.disabledValue - : extensionState.description.enabledValue, + value: wasSelected + ? extensionState.description.disabledValue + : extensionState.description.enabledValue, ), ); }); @@ -205,8 +204,8 @@ class ServiceExtensionButton extends StatelessWidget { padding: EdgeInsets.symmetric( horizontal: isScreenWiderThan(context, minScreenWidthForTextBeforeScaling) - ? defaultSpacing - : 0.0, + ? defaultSpacing + : 0.0, ), child: ImageIconLabel( ServiceExtensionIcon(extensionState: extensionState), @@ -239,14 +238,14 @@ class HotReloadButton extends StatelessWidget { // reload directly on the VM service (e.g. for Dart CLI apps). ? _HotReloadScaffoldAction() : DevToolsTooltip( - message: _hotReloadTooltip, - child: _RegisteredServiceExtensionButton._( - serviceDescription: hotReload, - action: _callHotReload, - completedText: 'Hot reload completed.', - describeError: (error) => 'Unable to hot reload the app: $error', - ), - ); + message: _hotReloadTooltip, + child: _RegisteredServiceExtensionButton._( + serviceDescription: hotReload, + action: _callHotReload, + completedText: 'Hot reload completed.', + describeError: (error) => 'Unable to hot reload the app: $error', + ), + ); } } @@ -368,17 +367,16 @@ class _RegisteredServiceExtensionButtonState if (_hidden) return const SizedBox.shrink(); return InkWell( - onTap: - () => unawaited( - invokeAndCatchErrors(() async { - final gaScreenName = widget.serviceDescription.gaScreenName; - final gaItem = widget.serviceDescription.gaItem; - if (gaScreenName != null && gaItem != null) { - ga.select(gaScreenName, gaItem); - } - await widget.action(); - }), - ), + onTap: () => unawaited( + invokeAndCatchErrors(() async { + final gaScreenName = widget.serviceDescription.gaScreenName; + final gaItem = widget.serviceDescription.gaItem; + if (gaScreenName != null && gaItem != null) { + ga.select(gaScreenName, gaItem); + } + await widget.action(); + }), + ), child: Container( constraints: BoxConstraints.tightFor( width: actionWidgetSize, @@ -402,8 +400,8 @@ class StructuredErrorsToggle extends StatelessWidget { Widget build(BuildContext context) { return _ServiceExtensionToggle( service: structuredErrors, - describeError: - (error) => 'Failed to update structuredError settings: $error', + describeError: (error) => + 'Failed to update structuredError settings: $error', ); } } @@ -482,10 +480,9 @@ class _ServiceExtensionToggleState extends State<_ServiceExtensionToggle> .setServiceExtensionState( widget.service.extension, enabled: value, - value: - value - ? widget.service.enabledValue - : widget.service.disabledValue, + value: value + ? widget.service.enabledValue + : widget.service.disabledValue, ); }), ); @@ -502,8 +499,8 @@ class ServiceExtensionCheckbox extends ServiceExtensionWidget { this.showDescription = true, }) : super( completedText: null, - describeError: - (error) => _errorMessage(serviceExtension.extension, error), + describeError: (error) => + _errorMessage(serviceExtension.extension, error), ); static String _errorMessage(String extensionName, Object? error) { @@ -571,8 +568,9 @@ class _ServiceExtensionCheckboxState extends State void _setValueFromState(ServiceExtensionState state) { final valueFromState = state.enabled; - value.value = - widget.serviceExtension.inverted ? !valueFromState : valueFromState; + value.value = widget.serviceExtension.inverted + ? !valueFromState + : valueFromState; } @override @@ -587,10 +585,9 @@ class _ServiceExtensionCheckboxState extends State child: CheckboxSetting( notifier: value, title: widget.serviceExtension.title, - description: - widget.showDescription - ? widget.serviceExtension.description - : null, + description: widget.showDescription + ? widget.serviceExtension.description + : null, tooltip: widget.serviceExtension.tooltip, onChanged: _onChanged, enabled: available, @@ -624,10 +621,9 @@ class _ServiceExtensionCheckboxState extends State .setServiceExtensionState( widget.serviceExtension.extension, enabled: enabled, - value: - enabled - ? widget.serviceExtension.enabledValue - : widget.serviceExtension.disabledValue, + value: enabled + ? widget.serviceExtension.enabledValue + : widget.serviceExtension.disabledValue, ); }), ); @@ -1077,10 +1073,9 @@ class ServiceExtensionIcon extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final color = - extensionState.isSelected - ? theme.colorScheme.primary - : theme.colorScheme.onSurface; + final color = extensionState.isSelected + ? theme.colorScheme.primary + : theme.colorScheme.onSurface; final description = extensionState.description; if (description.iconData != null) { return Icon(description.iconData, color: color); diff --git a/packages/devtools_app/lib/src/service/service_extensions.dart b/packages/devtools_app/lib/src/service/service_extensions.dart index 70aaea9dc84..8f9332be328 100644 --- a/packages/devtools_app/lib/src/service/service_extensions.dart +++ b/packages/devtools_app/lib/src/service/service_extensions.dart @@ -57,8 +57,10 @@ class ToggleableServiceExtensionDescription this.iconAsset, this.iconData, this.shortTitle, - }) : displayValues = - [enabledValue, disabledValue].map((v) => v.toString()).toList(), + }) : displayValues = [ + enabledValue, + disabledValue, + ].map((v) => v.toString()).toList(), assert((iconAsset == null) != (iconData == null)), assert((documentationUrl == null) == (gaDocsItem == null)); @@ -295,9 +297,7 @@ final profileWidgetBuilds = ToggleableServiceExtensionDescription.from( gaDocsItem: gac.PerformanceDocs.trackWidgetBuildsDocs.name, ); -final profileUserWidgetBuilds = ToggleableServiceExtensionDescription< - bool ->.from( +final profileUserWidgetBuilds = ToggleableServiceExtensionDescription.from( extensions.profileUserWidgetBuilds, title: 'Trace user-created widget builds', iconAsset: 'icons/trackwidget-white.png', @@ -409,9 +409,7 @@ option disabled, try to reduce the use of opacity effects in your app.''', gaDocsItem: gac.PerformanceDocs.disableOpacityLayersDocs.name, ); -final disablePhysicalShapeLayers = ToggleableServiceExtensionDescription< - bool ->.from( +final disablePhysicalShapeLayers = ToggleableServiceExtensionDescription.from( extensions.disablePhysicalShapeLayers, title: 'Render Physical Shape layers', iconData: Icons.format_shapes, @@ -438,20 +436,19 @@ final httpEnableTimelineLogging = ); // Legacy extension to show the inspector and enable inspector select mode. -final toggleOnDeviceWidgetInspector = ToggleableServiceExtensionDescription< - bool ->.from( - extensions.toggleOnDeviceWidgetInspector, - // Technically this enables the on-device widget inspector but for older - // versions of package:flutter it makes sense to describe this extension as - // toggling widget select mode as it is the only way to toggle that mode. - title: 'Select Widget Mode', - shortTitle: 'Select', - iconAsset: 'icons/widget-select-white.png', - gaScreenName: gac.inspector, - gaItem: gac.showOnDeviceInspector, - tooltip: 'Toggle select widget mode', -); +final toggleOnDeviceWidgetInspector = + ToggleableServiceExtensionDescription.from( + extensions.toggleOnDeviceWidgetInspector, + // Technically this enables the on-device widget inspector but for older + // versions of package:flutter it makes sense to describe this extension as + // toggling widget select mode as it is the only way to toggle that mode. + title: 'Select Widget Mode', + shortTitle: 'Select', + iconAsset: 'icons/widget-select-white.png', + gaScreenName: gac.inspector, + gaItem: gac.showOnDeviceInspector, + tooltip: 'Toggle select widget mode', + ); // TODO(kenz): remove this if it is not needed. According to the comments, // [toggleOnDeviceWidgetInspector] should be the legacy extension, but that is @@ -509,9 +506,7 @@ summary of these counts using the Rebuild Stats tool.''', // TODO(https://github.com/flutter/website/issues/10666): link docs ); -final profilePlatformChannels = ToggleableServiceExtensionDescription< - bool ->.from( +final profilePlatformChannels = ToggleableServiceExtensionDescription.from( extensions.profilePlatformChannels, title: 'Trace platform channels', iconAsset: 'icons/trackwidget-white.png', diff --git a/packages/devtools_app/lib/src/service/service_manager.dart b/packages/devtools_app/lib/src/service/service_manager.dart index fb389ef6f52..6702d8684d2 100644 --- a/packages/devtools_app/lib/src/service/service_manager.dart +++ b/packages/devtools_app/lib/src/service/service_manager.dart @@ -36,30 +36,29 @@ const defaultRefreshRate = 60.0; class ServiceConnectionManager { ServiceConnectionManager() { - serviceManager = - ServiceManager() - ..registerLifecycleCallback( - ServiceManagerLifecycle.beforeOpenVmService, - _beforeOpenVmService, - ) - ..registerLifecycleCallback( - ServiceManagerLifecycle.afterOpenVmService, - _afterOpenVmService, - ) - ..registerLifecycleCallback( - ServiceManagerLifecycle.beforeCloseVmService, - _beforeCloseVmService, - ) - ..registerLifecycleCallback( - ServiceManagerLifecycle.afterCloseVmService, - _afterCloseVmService, - ) - ..registerOverride( - ServiceManagerOverride.initIsolates, - (service) async => await serviceManager.isolateManager.init( - serviceManager.vm?.isolatesForDevToolsMode() ?? [], - ), - ); + serviceManager = ServiceManager() + ..registerLifecycleCallback( + ServiceManagerLifecycle.beforeOpenVmService, + _beforeOpenVmService, + ) + ..registerLifecycleCallback( + ServiceManagerLifecycle.afterOpenVmService, + _afterOpenVmService, + ) + ..registerLifecycleCallback( + ServiceManagerLifecycle.beforeCloseVmService, + _beforeCloseVmService, + ) + ..registerLifecycleCallback( + ServiceManagerLifecycle.afterCloseVmService, + _afterCloseVmService, + ) + ..registerOverride( + ServiceManagerOverride.initIsolates, + (service) async => await serviceManager.isolateManager.init( + serviceManager.vm?.isolatesForDevToolsMode() ?? [], + ), + ); } late final ServiceManager serviceManager; @@ -116,8 +115,8 @@ class ServiceConnectionManager { // Set up analytics dimensions for the connected app. ga.setupUserApplicationDimensions(); - _inspectorService = - devToolsEnvironmentParameters.inspectorServiceProvider(); + _inspectorService = devToolsEnvironmentParameters + .inspectorServiceProvider(); _appState?.dispose(); _appState = AppState(serviceManager.isolateManager.selectedIsolate); @@ -138,10 +137,9 @@ class ServiceConnectionManager { // Set [offlineController.previousConnectedApp] in case we need it for // viewing data after disconnect. This must be done before resetting the // rest of the service manager state. - final previousConnectedApp = - serviceManager.connectedApp != null - ? OfflineConnectedApp.parse(serviceManager.connectedApp!.toJson()) - : null; + final previousConnectedApp = serviceManager.connectedApp != null + ? OfflineConnectedApp.parse(serviceManager.connectedApp!.toJson()) + : null; offlineDataController.previousConnectedApp = previousConnectedApp; // This must be called before we close the VM service so that @@ -193,9 +191,8 @@ class ServiceConnectionManager { Future get flutterViewId async { final flutterViewListResponse = await serviceManager .callServiceExtensionOnMainIsolate(registrations.flutterListViews); - final views = - (flutterViewListResponse.json!['views'] as List) - .cast>(); + final views = (flutterViewListResponse.json!['views'] as List) + .cast>(); // Each isolate should only have one FlutterView. final flutterView = views.firstWhereOrNull( diff --git a/packages/devtools_app/lib/src/service/timeline_streams.dart b/packages/devtools_app/lib/src/service/timeline_streams.dart index b3d743b5e7a..57e51d1d12f 100644 --- a/packages/devtools_app/lib/src/service/timeline_streams.dart +++ b/packages/devtools_app/lib/src/service/timeline_streams.dart @@ -153,10 +153,9 @@ class TimelineStreamManager with DisposerMixin { /// Sends an update to the VM service that the new recorded value for [stream] /// should match [value]. Future updateTimelineStream(TimelineStream stream, bool value) async { - final recordedStreamNames = - _streams.keys - .where((streamName) => _streams[streamName]!.recorded.value) - .toList(); + final recordedStreamNames = _streams.keys + .where((streamName) => _streams[streamName]!.recorded.value) + .toList(); final alreadyBeingRecorded = recordedStreamNames.contains(stream.name); if (alreadyBeingRecorded && !value) { recordedStreamNames.remove(stream.name); diff --git a/packages/devtools_app/lib/src/service/vm_flags.dart b/packages/devtools_app/lib/src/service/vm_flags.dart index 9881e7c3bca..3e803ca3603 100644 --- a/packages/devtools_app/lib/src/service/vm_flags.dart +++ b/packages/devtools_app/lib/src/service/vm_flags.dart @@ -43,13 +43,12 @@ class VmFlagManager with DisposerMixin { if (event.kind == EventKind.kVMFlagUpdate) { if (_flagNotifiers.containsKey(event.flag)) { final currentFlag = _flagNotifiers[event.flag]!.value; - _flagNotifiers[event.flag]!.value = - Flag.parse({ - 'name': currentFlag.name, - 'comment': currentFlag.comment, - 'modified': true, - 'valueAsString': event.newValue, - })!; + _flagNotifiers[event.flag]!.value = Flag.parse({ + 'name': currentFlag.name, + 'comment': currentFlag.comment, + 'modified': true, + 'valueAsString': event.newValue, + })!; _flags.value = await service.getFlagList(); } } diff --git a/packages/devtools_app/lib/src/service/vm_service_wrapper.dart b/packages/devtools_app/lib/src/service/vm_service_wrapper.dart index 4da7282b238..521ffcba6b1 100644 --- a/packages/devtools_app/lib/src/service/vm_service_wrapper.dart +++ b/packages/devtools_app/lib/src/service/vm_service_wrapper.dart @@ -89,12 +89,11 @@ class VmServiceWrapper extends VmService { Future get allFuturesCompleted => _allFuturesCompleter.future; - Completer _allFuturesCompleter = - Completer() - // Mark the future as completed by default so if we don't track any - // futures but someone tries to wait on [allFuturesCompleted] they don't - // hang. The first tracked future will replace this with a new completer. - ..complete(true); + Completer _allFuturesCompleter = Completer() + // Mark the future as completed by default so if we don't track any + // futures but someone tries to wait on [allFuturesCompleted] they don't + // hang. The first tracked future will replace this with a new completer. + ..complete(true); // A local cache of "fake" service objects. Used to convert JSON objects to // VM service response formats to be used with APIs that require them. diff --git a/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart b/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart index 56fe39e83b7..9a2e497826f 100644 --- a/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart +++ b/packages/devtools_app/lib/src/shared/analytics/_analytics_web.dart @@ -147,71 +147,57 @@ extension type GtagEventDevTools._(JSObject _) implements GtagEvent { ide_launched_feature: ideLaunchedFeature, is_wasm: kIsWasm.toString(), // [PerformanceScreenMetrics] - ui_duration_micros: - screenMetrics is PerformanceScreenMetrics - ? screenMetrics.uiDuration?.inMicroseconds - : null, - raster_duration_micros: - screenMetrics is PerformanceScreenMetrics - ? screenMetrics.rasterDuration?.inMicroseconds - : null, + ui_duration_micros: screenMetrics is PerformanceScreenMetrics + ? screenMetrics.uiDuration?.inMicroseconds + : null, + raster_duration_micros: screenMetrics is PerformanceScreenMetrics + ? screenMetrics.rasterDuration?.inMicroseconds + : null, shader_compilation_duration_micros: screenMetrics is PerformanceScreenMetrics - ? screenMetrics.shaderCompilationDuration?.inMicroseconds - : null, - trace_event_count: - screenMetrics is PerformanceScreenMetrics - ? screenMetrics.traceEventCount - : null, + ? screenMetrics.shaderCompilationDuration?.inMicroseconds + : null, + trace_event_count: screenMetrics is PerformanceScreenMetrics + ? screenMetrics.traceEventCount + : null, // [ProfilerScreenMetrics] - cpu_sample_count: - screenMetrics is ProfilerScreenMetrics - ? screenMetrics.cpuSampleCount - : null, - cpu_stack_depth: - screenMetrics is ProfilerScreenMetrics - ? screenMetrics.cpuStackDepth - : null, + cpu_sample_count: screenMetrics is ProfilerScreenMetrics + ? screenMetrics.cpuSampleCount + : null, + cpu_stack_depth: screenMetrics is ProfilerScreenMetrics + ? screenMetrics.cpuStackDepth + : null, // [MemoryScreenMetrics] - heap_diff_objects_before: - screenMetrics is MemoryScreenMetrics - ? screenMetrics.heapDiffObjectsBefore - : null, - heap_diff_objects_after: - screenMetrics is MemoryScreenMetrics - ? screenMetrics.heapDiffObjectsAfter - : null, - heap_objects_total: - screenMetrics is MemoryScreenMetrics - ? screenMetrics.heapObjectsTotal - : null, + heap_diff_objects_before: screenMetrics is MemoryScreenMetrics + ? screenMetrics.heapDiffObjectsBefore + : null, + heap_diff_objects_after: screenMetrics is MemoryScreenMetrics + ? screenMetrics.heapDiffObjectsAfter + : null, + heap_objects_total: screenMetrics is MemoryScreenMetrics + ? screenMetrics.heapObjectsTotal + : null, // [InspectorScreenMetrics] - root_set_count: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.rootSetCount - : null, - row_count: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.rowCount - : null, - inspector_tree_controller_id: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.inspectorTreeControllerId - : null, + root_set_count: screenMetrics is InspectorScreenMetrics + ? screenMetrics.rootSetCount + : null, + row_count: screenMetrics is InspectorScreenMetrics + ? screenMetrics.rowCount + : null, + inspector_tree_controller_id: screenMetrics is InspectorScreenMetrics + ? screenMetrics.inspectorTreeControllerId + : null, // [DeepLinkScreenMetrics] - android_app_id: - screenMetrics is DeepLinkScreenMetrics - ? screenMetrics.androidAppId - : null, - ios_bundle_id: - screenMetrics is DeepLinkScreenMetrics - ? screenMetrics.iosBundleId - : null, + android_app_id: screenMetrics is DeepLinkScreenMetrics + ? screenMetrics.androidAppId + : null, + ios_bundle_id: screenMetrics is DeepLinkScreenMetrics + ? screenMetrics.iosBundleId + : null, // [InspectorScreenMetrics] - is_v2_inspector: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.isV2.toString() - : null, + is_v2_inspector: screenMetrics is InspectorScreenMetrics + ? screenMetrics.isV2.toString() + : null, ); } @@ -329,71 +315,57 @@ extension type GtagExceptionDevTools._(JSObject _) implements GtagException { ide_launched_feature: ideLaunchedFeature, is_wasm: kIsWasm.toString(), // [PerformanceScreenMetrics] - ui_duration_micros: - screenMetrics is PerformanceScreenMetrics - ? screenMetrics.uiDuration?.inMicroseconds - : null, - raster_duration_micros: - screenMetrics is PerformanceScreenMetrics - ? screenMetrics.rasterDuration?.inMicroseconds - : null, - trace_event_count: - screenMetrics is PerformanceScreenMetrics - ? screenMetrics.traceEventCount - : null, + ui_duration_micros: screenMetrics is PerformanceScreenMetrics + ? screenMetrics.uiDuration?.inMicroseconds + : null, + raster_duration_micros: screenMetrics is PerformanceScreenMetrics + ? screenMetrics.rasterDuration?.inMicroseconds + : null, + trace_event_count: screenMetrics is PerformanceScreenMetrics + ? screenMetrics.traceEventCount + : null, shader_compilation_duration_micros: screenMetrics is PerformanceScreenMetrics - ? screenMetrics.shaderCompilationDuration?.inMicroseconds - : null, + ? screenMetrics.shaderCompilationDuration?.inMicroseconds + : null, // [ProfilerScreenMetrics] - cpu_sample_count: - screenMetrics is ProfilerScreenMetrics - ? screenMetrics.cpuSampleCount - : null, - cpu_stack_depth: - screenMetrics is ProfilerScreenMetrics - ? screenMetrics.cpuStackDepth - : null, + cpu_sample_count: screenMetrics is ProfilerScreenMetrics + ? screenMetrics.cpuSampleCount + : null, + cpu_stack_depth: screenMetrics is ProfilerScreenMetrics + ? screenMetrics.cpuStackDepth + : null, // [MemoryScreenMetrics] - heap_diff_objects_before: - screenMetrics is MemoryScreenMetrics - ? screenMetrics.heapDiffObjectsBefore - : null, - heap_diff_objects_after: - screenMetrics is MemoryScreenMetrics - ? screenMetrics.heapDiffObjectsAfter - : null, - heap_objects_total: - screenMetrics is MemoryScreenMetrics - ? screenMetrics.heapObjectsTotal - : null, + heap_diff_objects_before: screenMetrics is MemoryScreenMetrics + ? screenMetrics.heapDiffObjectsBefore + : null, + heap_diff_objects_after: screenMetrics is MemoryScreenMetrics + ? screenMetrics.heapDiffObjectsAfter + : null, + heap_objects_total: screenMetrics is MemoryScreenMetrics + ? screenMetrics.heapObjectsTotal + : null, // [InspectorScreenMetrics] - root_set_count: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.rootSetCount - : null, - row_count: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.rowCount - : null, - inspector_tree_controller_id: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.inspectorTreeControllerId - : null, + root_set_count: screenMetrics is InspectorScreenMetrics + ? screenMetrics.rootSetCount + : null, + row_count: screenMetrics is InspectorScreenMetrics + ? screenMetrics.rowCount + : null, + inspector_tree_controller_id: screenMetrics is InspectorScreenMetrics + ? screenMetrics.inspectorTreeControllerId + : null, // [DeepLinkScreenMetrics] - android_app_id: - screenMetrics is DeepLinkScreenMetrics - ? screenMetrics.androidAppId - : null, - ios_bundle_id: - screenMetrics is DeepLinkScreenMetrics - ? screenMetrics.iosBundleId - : null, + android_app_id: screenMetrics is DeepLinkScreenMetrics + ? screenMetrics.androidAppId + : null, + ios_bundle_id: screenMetrics is DeepLinkScreenMetrics + ? screenMetrics.iosBundleId + : null, // [InspectorScreenMetrics] - is_v2_inspector: - screenMetrics is InspectorScreenMetrics - ? screenMetrics.isV2.toString() - : null, + is_v2_inspector: screenMetrics is InspectorScreenMetrics + ? screenMetrics.isV2.toString() + : null, ); } @@ -520,8 +492,9 @@ void timeEnd( screenName, timedOperation, durationMicros: durationMicros, - screenMetrics: - screenMetricsProvider != null ? screenMetricsProvider() : null, + screenMetrics: screenMetricsProvider != null + ? screenMetricsProvider() + : null, ); } @@ -560,8 +533,9 @@ void timeSync( screenName, timedOperation, durationMicros: durationMicros, - screenMetrics: - screenMetricsProvider != null ? screenMetricsProvider() : null, + screenMetrics: screenMetricsProvider != null + ? screenMetricsProvider() + : null, ); } @@ -590,8 +564,9 @@ Future timeAsync( screenName, timedOperation, durationMicros: durationMicros, - screenMetrics: - screenMetricsProvider != null ? screenMetricsProvider() : null, + screenMetrics: screenMetricsProvider != null + ? screenMetricsProvider() + : null, ); } @@ -640,8 +615,9 @@ void select( value: value, non_interaction: nonInteraction, send_to: gaDevToolsPropertyId(), - screenMetrics: - screenMetricsProvider != null ? screenMetricsProvider() : null, + screenMetrics: screenMetricsProvider != null + ? screenMetricsProvider() + : null, ); _sendEvent(gtagEvent); } @@ -665,8 +641,9 @@ void impression( event_label: item, non_interaction: true, send_to: gaDevToolsPropertyId(), - screenMetrics: - screenMetricsProvider != null ? screenMetricsProvider() : null, + screenMetrics: screenMetricsProvider != null + ? screenMetricsProvider() + : null, ); _sendEvent(gtagEvent); } @@ -799,8 +776,9 @@ void _computeUserApplicationCustomGTagData() { userAppType = appTypeDartCLI; } - userBuildType = - connectedApp.isProfileBuildNow! ? buildTypeProfile : buildTypeDebug; + userBuildType = connectedApp.isProfileBuildNow! + ? buildTypeProfile + : buildTypeDebug; _analyticsComputed = true; } @@ -1031,22 +1009,21 @@ final class _DevToolsEventMetrics extends ua.CustomMetrics { final String? iosBundleId; @override - Map toMap() => - ({ - 'uiDurationMicros': uiDurationMicros, - 'rasterDurationMicros': rasterDurationMicros, - 'shaderCompilationDurationMicros': shaderCompilationDurationMicros, - 'traceEventCount': traceEventCount, - 'cpuSampleCount': cpuSampleCount, - 'cpuStackDepth': cpuStackDepth, - 'heapDiffObjectsBefore': heapDiffObjectsBefore, - 'heapDiffObjectsAfter': heapDiffObjectsAfter, - 'heapObjectsTotal': heapObjectsTotal, - 'rootSetCount': rootSetCount, - 'rowCount': rowCount, - 'inspectorTreeControllerId': inspectorTreeControllerId, - 'isV2Inspector': isV2Inspector, - 'androidAppId': androidAppId, - 'iosBundleId': iosBundleId, - }..removeWhere((key, value) => value == null)).cast(); + Map toMap() => ({ + 'uiDurationMicros': uiDurationMicros, + 'rasterDurationMicros': rasterDurationMicros, + 'shaderCompilationDurationMicros': shaderCompilationDurationMicros, + 'traceEventCount': traceEventCount, + 'cpuSampleCount': cpuSampleCount, + 'cpuStackDepth': cpuStackDepth, + 'heapDiffObjectsBefore': heapDiffObjectsBefore, + 'heapDiffObjectsAfter': heapDiffObjectsAfter, + 'heapObjectsTotal': heapObjectsTotal, + 'rootSetCount': rootSetCount, + 'rowCount': rowCount, + 'inspectorTreeControllerId': inspectorTreeControllerId, + 'isV2Inspector': isV2Inspector, + 'androidAppId': androidAppId, + 'iosBundleId': iosBundleId, + }..removeWhere((key, value) => value == null)).cast(); } diff --git a/packages/devtools_app/lib/src/shared/analytics/analytics_common.dart b/packages/devtools_app/lib/src/shared/analytics/analytics_common.dart index ec0c4471af0..a76196f497b 100644 --- a/packages/devtools_app/lib/src/shared/analytics/analytics_common.dart +++ b/packages/devtools_app/lib/src/shared/analytics/analytics_common.dart @@ -61,10 +61,9 @@ Map createStackTraceForAnalytics( const maxCharacterLimit = stackTraceChunksLimit * ga4ParamValueCharacterLimit; // Reduce whitespace characters to optimize available space. - final trimmedStackFrames = - stackTrace.frames - .map((f) => '${_normalizePath(f.location)} | ${f.member}\n') - .toList(); + final trimmedStackFrames = stackTrace.frames + .map((f) => '${_normalizePath(f.location)} | ${f.member}\n') + .toList(); final stackTraceAsString = trimmedStackFrames.join(); var stackTraceChunksForGa = chunkForGa( diff --git a/packages/devtools_app/lib/src/shared/analytics/prompt.dart b/packages/devtools_app/lib/src/shared/analytics/prompt.dart index 73a2272e730..5cd7ce6f604 100644 --- a/packages/devtools_app/lib/src/shared/analytics/prompt.dart +++ b/packages/devtools_app/lib/src/shared/analytics/prompt.dart @@ -44,7 +44,10 @@ class _AnalyticsPromptState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [if (showPrompt) child!, Expanded(child: widget.child)], + children: [ + if (showPrompt) child!, + Expanded(child: widget.child), + ], ); }, child: Card( @@ -86,10 +89,9 @@ class _AnalyticsPromptState extends State { } Widget _analyticsDescription(ThemeData theme) { - final consentMessageRegExpResults = - parseAnalyticsConsentMessage( - controller.consentMessage, - )?.map((e) => adjustLineBreaks(e)).toList(); + final consentMessageRegExpResults = parseAnalyticsConsentMessage( + controller.consentMessage, + )?.map((e) => adjustLineBreaks(e)).toList(); // When failing to parse the consent message, fallback to displaying the // consent message in its regular form. diff --git a/packages/devtools_app/lib/src/shared/charts/chart.dart b/packages/devtools_app/lib/src/shared/charts/chart.dart index 90497a69614..c2bdfcfc899 100644 --- a/packages/devtools_app/lib/src/shared/charts/chart.dart +++ b/packages/devtools_app/lib/src/shared/charts/chart.dart @@ -95,28 +95,25 @@ class ChartState extends State with AutoDisposeMixin { return RepaintBoundary( child: LayoutBuilder( // Inner container - builder: - (_, constraints) => GestureDetector( - onTapDown: (TapDownDetails details) { - final xLocalPosition = details.localPosition.dx; - final timestampIndex = controller.xCoordToTimestampIndex( - xLocalPosition, - ); - final timestamp = controller.xCoordToTimestamp(xLocalPosition); - controller.tapLocation.value = TapLocation( - details, - timestamp, - timestampIndex, - ); - }, - child: SizedBox( - width: constraints.widthConstraints().maxWidth, - height: constraints.widthConstraints().maxHeight, - child: CustomPaint( - painter: ChartPainter(controller, colorScheme), - ), - ), - ), + builder: (_, constraints) => GestureDetector( + onTapDown: (TapDownDetails details) { + final xLocalPosition = details.localPosition.dx; + final timestampIndex = controller.xCoordToTimestampIndex( + xLocalPosition, + ); + final timestamp = controller.xCoordToTimestamp(xLocalPosition); + controller.tapLocation.value = TapLocation( + details, + timestamp, + timestampIndex, + ); + }, + child: SizedBox( + width: constraints.widthConstraints().maxWidth, + height: constraints.widthConstraints().maxHeight, + child: CustomPaint(painter: ChartPainter(controller, colorScheme)), + ), + ), ), ); } @@ -154,10 +151,9 @@ class ChartPainter extends CustomPainter { // sampling 1 point per horizontal pixel. final startTime = DateTime.now(); - final axis = - Paint() - ..strokeWidth = axisWidth - ..color = Colors.grey; + final axis = Paint() + ..strokeWidth = axisWidth + ..color = Colors.grey; if (size != chartController.size) { chartController.size = size; @@ -241,8 +237,9 @@ class ChartPainter extends CustomPainter { drawTranslate(canvas, xTranslation, yTranslation, (canvas) { final xCoord = xCanvasCoord; final yCoord = chartController.yPositionToYCanvasCoord(yValue); - final hasMultipleExtensionEvents = - traceData is DataAggregate ? traceData.count > 1 : false; + final hasMultipleExtensionEvents = traceData is DataAggregate + ? traceData.count > 1 + : false; // Is the visible Y-axis max larger. if (yValue > visibleYMax) { @@ -442,10 +439,9 @@ class ChartPainter extends CustomPainter { } void drawSelection(Canvas canvas, double x) { - final paint = - Paint() - ..strokeWidth = 2.0 - ..color = colorScheme.hoverSelectionBarColor; + final paint = Paint() + ..strokeWidth = 2.0 + ..color = colorScheme.hoverSelectionBarColor; // Draw the vertical selection bar. canvas.drawLine( @@ -597,14 +593,12 @@ class ChartPainter extends CustomPainter { break; } - final paintFirst = - Paint() - ..style = firstStyle - ..strokeWidth = characteristics.strokeWidth - ..color = - aggregateEvents - ? characteristics.colorAggregate! - : characteristics.color; + final paintFirst = Paint() + ..style = firstStyle + ..strokeWidth = characteristics.strokeWidth + ..color = aggregateEvents + ? characteristics.colorAggregate! + : characteristics.color; switch (characteristics.symbol) { case ChartSymbol.dashedLine: @@ -625,15 +619,13 @@ class ChartPainter extends CustomPainter { canvas.drawCircle(Offset(x, y), characteristics.diameter, paintFirst); // Inner disc. - final paintSecond = - Paint() - ..style = secondStyle - ..strokeWidth = 0 - // TODO(terry): Aggregate for concentric maybe needed someday. - ..color = - aggregateEvents - ? characteristics.colorAggregate! - : characteristics.concentricCenterColor; + final paintSecond = Paint() + ..style = secondStyle + ..strokeWidth = 0 + // TODO(terry): Aggregate for concentric maybe needed someday. + ..color = aggregateEvents + ? characteristics.colorAggregate! + : characteristics.concentricCenterColor; canvas.drawCircle( Offset(x, y), characteristics.concentricCenterDiameter, @@ -675,11 +667,10 @@ class ChartPainter extends CustomPainter { double endX, double endY, ) { - final paint = - Paint() - ..style = PaintingStyle.stroke - ..strokeWidth = characteristics.strokeWidth - ..color = characteristics.color; + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = characteristics.strokeWidth + ..color = characteristics.color; canvas.drawLine(Offset(startX, startY), Offset(endX, endY), paint); } @@ -691,11 +682,10 @@ class ChartPainter extends CustomPainter { double y, double tickWidth, ) { - final paint = - Paint() - ..style = PaintingStyle.stroke - ..strokeWidth = characteristics.strokeWidth - ..color = characteristics.color; + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = characteristics.strokeWidth + ..color = characteristics.color; canvas.drawLine(Offset(x, y), Offset(x + tickWidth, y), paint); } @@ -712,18 +702,16 @@ class ChartPainter extends CustomPainter { double y1, double y1Bottom, ) { - final paint = - Paint() - ..style = PaintingStyle.fill - ..strokeWidth = characteristics.strokeWidth - ..color = characteristics.color.withAlpha(140); - - final fillArea = - Path() - ..moveTo(x0, y0) - ..lineTo(x1, y1) - ..lineTo(x1, y1Bottom) - ..lineTo(x0, y0Bottom); + final paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = characteristics.strokeWidth + ..color = characteristics.color.withAlpha(140); + + final fillArea = Path() + ..moveTo(x0, y0) + ..lineTo(x1, y1) + ..lineTo(x1, y1Bottom) + ..lineTo(x0, y0Bottom); fillArea.close(); canvas.drawPath(fillArea, paint); diff --git a/packages/devtools_app/lib/src/shared/charts/chart_controller.dart b/packages/devtools_app/lib/src/shared/charts/chart_controller.dart index c70f41f0922..923ac1b2630 100644 --- a/packages/devtools_app/lib/src/shared/charts/chart_controller.dart +++ b/packages/devtools_app/lib/src/shared/charts/chart_controller.dart @@ -233,10 +233,9 @@ class ChartController extends DisposableController return false; }); - final ticksVisible = - startOfLastNMinutes != null - ? timestampsLength - timestamps.indexOf(startOfLastNMinutes) - : timestampsLength + 1; + final ticksVisible = startOfLastNMinutes != null + ? timestampsLength - timestamps.indexOf(startOfLastNMinutes) + : timestampsLength + 1; _tickWidth = canvasChartWidth / ticksVisible; } else { // No but lets scale x-axis based on the last two timestamps diffs we have. @@ -367,8 +366,9 @@ class ChartController extends DisposableController timestamps.last, ); - final nSeconds = - rightMostTimestampDT.difference(rightMostLabelDT).inSeconds; + final nSeconds = rightMostTimestampDT + .difference(rightMostLabelDT) + .inSeconds; if (nSeconds >= labelInterval) { late int foundTimestamp; diff --git a/packages/devtools_app/lib/src/shared/charts/chart_trace.dart b/packages/devtools_app/lib/src/shared/charts/chart_trace.dart index e4fc8db1fbf..d95f0b2e861 100644 --- a/packages/devtools_app/lib/src/shared/charts/chart_trace.dart +++ b/packages/devtools_app/lib/src/shared/charts/chart_trace.dart @@ -357,17 +357,16 @@ class AxisScale { // Fractional part of range. final fraction = range / pow(10, exponent); // Nice, rounded fraction. - final niceFraction = - round - ? fraction.roundToDouble() - : switch (fraction) { - <= 1 => 1.0, - <= 2 => 2.0, - <= 3 => 3.0, - <= 5 => 5.0, - <= 7 => 7.0, - _ => 10.0, - }; + final niceFraction = round + ? fraction.roundToDouble() + : switch (fraction) { + <= 1 => 1.0, + <= 2 => 2.0, + <= 3 => 3.0, + <= 5 => 5.0, + <= 7 => 7.0, + _ => 10.0, + }; return niceFraction * pow(10, exponent); } diff --git a/packages/devtools_app/lib/src/shared/charts/flame_chart.dart b/packages/devtools_app/lib/src/shared/charts/flame_chart.dart index 5cc26b7066e..5151208b286 100644 --- a/packages/devtools_app/lib/src/shared/charts/flame_chart.dart +++ b/packages/devtools_app/lib/src/shared/charts/flame_chart.dart @@ -159,13 +159,12 @@ abstract class FlameChartState< TimeRange get visibleTimeRange { final horizontalScrollOffset = horizontalControllerGroup.offset; - final startMicros = - horizontalScrollOffset < widget.startInset - ? startTimeOffset - : startTimeOffset + - (horizontalScrollOffset - widget.startInset) / - currentZoom / - startingPxPerMicro; + final startMicros = horizontalScrollOffset < widget.startInset + ? startTimeOffset + : startTimeOffset + + (horizontalScrollOffset - widget.startInset) / + currentZoom / + startingPxPerMicro; final endMicros = startTimeOffset + @@ -236,9 +235,8 @@ abstract class FlameChartState< )..addListener(_handleZoomControllerValueUpdate); verticalExtentDelegate = FixedExtentDelegate( - computeExtent: - (index) => - rows[index].nodes.isEmpty ? sectionSpacing : rowHeightWithPadding, + computeExtent: (index) => + rows[index].nodes.isEmpty ? sectionSpacing : rowHeightWithPadding, computeLength: () => rows.length, ); @@ -396,11 +394,10 @@ abstract class FlameChartState< return; } - final hoverNodeData = - _binarySearchForNode( - x: event.localPosition.dx + horizontalControllerGroup.offset, - nodesInRow: nodes, - )?.data; + final hoverNodeData = _binarySearchForNode( + x: event.localPosition.dx + horizontalControllerGroup.offset, + nodesInRow: nodes, + )?.data; _hoveredNodeNotifier.value = hoverNodeData; } @@ -506,13 +503,10 @@ abstract class FlameChartState< final fixedX = safeMouseHoverX + lastScrollOffset - widget.startInset; // Calculate the new horizontal scroll position. - final newScrollOffset = - fixedX >= 0 - ? fixedX * newZoom / previousZoom + - widget.startInset - - safeMouseHoverX - // We are in the fixed portion of the window - no need to transform. - : lastScrollOffset; + final newScrollOffset = fixedX >= 0 + ? fixedX * newZoom / previousZoom + widget.startInset - safeMouseHoverX + // We are in the fixed portion of the window - no need to transform. + : lastScrollOffset; setState(() { currentZoom = zoomController.value; @@ -940,12 +934,11 @@ class FlameChartUtils { // Node right with zoom and insets taken into consideration. final nodeRight = (node.rect.right - chartStartInset) * nodeZoom + chartStartInset; - final padding = - nextNode == null - ? chartWidth - nodeRight - : ((nextNode.rect.left - chartStartInset) * nextNodeZoom + - chartStartInset) - - nodeRight; + final padding = nextNode == null + ? chartWidth - nodeRight + : ((nextNode.rect.left - chartStartInset) * nextNodeZoom + + chartStartInset) - + nodeRight; // Floating point rounding error can result in slightly negative padding. return math.max(0.0, padding); } @@ -1090,22 +1083,21 @@ class FlameChartNode> { activeSearchMatch: activeSearchMatch, colorScheme: theme.colorScheme, ), - child: - zoomedWidth >= _minWidthForText - ? Text( - text, - textAlign: TextAlign.left, - overflow: TextOverflow.ellipsis, - style: theme.regularTextStyleWithColor( - _textColor( - selected: selected, - searchMatch: searchMatch, - activeSearchMatch: activeSearchMatch, - colorScheme: theme.colorScheme, - ), + child: zoomedWidth >= _minWidthForText + ? Text( + text, + textAlign: TextAlign.left, + overflow: TextOverflow.ellipsis, + style: theme.regularTextStyleWithColor( + _textColor( + selected: selected, + searchMatch: searchMatch, + activeSearchMatch: activeSearchMatch, + colorScheme: theme.colorScheme, ), - ) - : const SizedBox(), + ), + ) + : const SizedBox(), ); return (hovered || !selectable) ? DevToolsTooltip(key: key, message: data.tooltip, child: node) @@ -1346,11 +1338,9 @@ class TimelineGridPainter extends FlameChartPainter { final microsPerInterval = _microsPerInterval(intervalWidth); int timestampMicros = _startingTimestamp(intervalWidth, microsPerInterval); double lineX; - lineX = - visible.left <= chartStartInset - ? chartStartInset - visible.left - : intervalWidth - - ((visible.left - chartStartInset) % intervalWidth); + lineX = visible.left <= chartStartInset + ? chartStartInset - visible.left + : intervalWidth - ((visible.left - chartStartInset) % intervalWidth); while (lineX < constraints.maxWidth) { _paintTimestamp(canvas, timestampMicros, intervalWidth, lineX); @@ -1422,10 +1412,9 @@ class TimelineGridPainter extends FlameChartPainter { } int _startingTimestamp(double intervalWidth, int microsPerInterval) { - final startingIntervalIndex = - horizontalScrollOffset < chartStartInset - ? 0 - : (horizontalScrollOffset - chartStartInset) ~/ intervalWidth + 1; + final startingIntervalIndex = horizontalScrollOffset < chartStartInset + ? 0 + : (horizontalScrollOffset - chartStartInset) ~/ intervalWidth + 1; return startingIntervalIndex * microsPerInterval; } diff --git a/packages/devtools_app/lib/src/shared/charts/treemap.dart b/packages/devtools_app/lib/src/shared/charts/treemap.dart index 7789bac53b4..9b0db9a44ac 100644 --- a/packages/devtools_app/lib/src/shared/charts/treemap.dart +++ b/packages/devtools_app/lib/src/shared/charts/treemap.dart @@ -234,15 +234,13 @@ class _TreemapState extends State { final pivotAndList2Ratio = (pivotByteSize + list2Size) / totalByteSize; final pivotRatio = pivotByteSize / (pivotByteSize + list2Size); - final pivotWidth = - isHorizontalRectangle - ? pivotAndList2Ratio * width - : pivotRatio * width; + final pivotWidth = isHorizontalRectangle + ? pivotAndList2Ratio * width + : pivotRatio * width; - final pivotHeight = - isHorizontalRectangle - ? pivotRatio * height - : pivotAndList2Ratio * height; + final pivotHeight = isHorizontalRectangle + ? pivotRatio * height + : pivotAndList2Ratio * height; final pivotAspectRatio = pivotWidth / pivotHeight; @@ -269,14 +267,12 @@ class _TreemapState extends State { final pivotAndList2Ratio = (pivotByteSize + list2ByteSize) / totalByteSize; final pivotRatio = pivotByteSize / (pivotByteSize + list2ByteSize); - pivotBestWidth = - isHorizontalRectangle - ? pivotAndList2Ratio * width - : pivotRatio * width; - pivotBestHeight = - isHorizontalRectangle - ? pivotRatio * height - : pivotAndList2Ratio * height; + pivotBestWidth = isHorizontalRectangle + ? pivotAndList2Ratio * width + : pivotRatio * width; + pivotBestHeight = isHorizontalRectangle + ? pivotRatio * height + : pivotAndList2Ratio * height; } final positionedTreemaps = []; @@ -284,8 +280,9 @@ class _TreemapState extends State { // Construct list 1 sub-treemap. final list1SizeRatio = list1ByteSize / totalByteSize; final list1Width = isHorizontalRectangle ? width * list1SizeRatio : width; - final list1Height = - isHorizontalRectangle ? height : height * list1SizeRatio; + final list1Height = isHorizontalRectangle + ? height + : height * list1SizeRatio; if (list1.isNotEmpty) { positionedTreemaps.addAll( buildTreemaps( @@ -299,10 +296,12 @@ class _TreemapState extends State { } // Construct list 2 sub-treemap. - final list2Width = - isHorizontalRectangle ? pivotBestWidth : width - pivotBestWidth; - final list2Height = - isHorizontalRectangle ? height - pivotBestHeight : pivotBestHeight; + final list2Width = isHorizontalRectangle + ? pivotBestWidth + : width - pivotBestWidth; + final list2Height = isHorizontalRectangle + ? height - pivotBestHeight + : pivotBestHeight; final list2XCoord = isHorizontalRectangle ? list1Width : 0.0; final list2YCoord = isHorizontalRectangle ? pivotBestHeight : list1Height; if (list2.isNotEmpty) { @@ -344,10 +343,12 @@ class _TreemapState extends State { final list3Ratio = list3ByteSize / totalByteSize; final list3Width = isHorizontalRectangle ? list3Ratio * width : width; final list3Height = isHorizontalRectangle ? height : list3Ratio * height; - final list3XCoord = - isHorizontalRectangle ? list1Width + pivotBestWidth : 0.0; - final list3YCoord = - isHorizontalRectangle ? 0.0 : list1Height + pivotBestHeight; + final list3XCoord = isHorizontalRectangle + ? list1Width + pivotBestWidth + : 0.0; + final list3YCoord = isHorizontalRectangle + ? 0.0 + : list1Height + pivotBestHeight; if (list3.isNotEmpty) { positionedTreemaps.addAll( @@ -489,14 +490,13 @@ class _TreemapState extends State { onRootChangedCallback: widget.onRootChangedCallback, ), Expanded( - child: - widget.isOutermostLevel - ? child - : _SelectableTreemapNode( - node: rootNode, - onRootChangedCallback: widget.onRootChangedCallback, - child: child, - ), + child: widget.isOutermostLevel + ? child + : _SelectableTreemapNode( + node: rootNode, + onRootChangedCallback: widget.onRootChangedCallback, + child: child, + ), ), ], ); @@ -537,14 +537,13 @@ class _TreeMapCell extends StatelessWidget { border: Border.all(color: Colors.black87), ), child: Center( - child: - treeMapHeight > Treemap.minHeightToDisplayCellText - ? _NameAndSizeText( - node: node, - color: node.showDiff ? Colors.white : Colors.black, - singleLine: false, - ) - : const SizedBox(), + child: treeMapHeight > Treemap.minHeightToDisplayCellText + ? _NameAndSizeText( + node: node, + color: node.showDiff ? Colors.white : Colors.black, + singleLine: false, + ) + : const SizedBox(), ), ); } @@ -631,10 +630,9 @@ class _BreadcrumbNavigator extends StatelessWidget { builder: (context, index) { final node = pathFromRoot[index]; return Breadcrumb( - text: - index < pathFromRoot.length - 1 - ? node.name - : node.displayText(), + text: index < pathFromRoot.length - 1 + ? node.name + : node.displayText(), isRoot: index == 0, onPressed: () => onRootChangedCallback(node), ); @@ -870,10 +868,9 @@ class MultiCellPainter extends CustomPainter { rectPaint.color = node.displayColor; canvas.drawRect(bounds, rectPaint); - final borderPaint = - Paint() - ..color = Colors.black45 - ..style = PaintingStyle.stroke; + final borderPaint = Paint() + ..color = Colors.black45 + ..style = PaintingStyle.stroke; canvas.drawRect(bounds, borderPaint); if (positionedCell.width! > Treemap.minWidthToDisplayCellText && diff --git a/packages/devtools_app/lib/src/shared/config_specific/drag_and_drop/drag_and_drop.dart b/packages/devtools_app/lib/src/shared/config_specific/drag_and_drop/drag_and_drop.dart index f469c107f99..2b26dd69e65 100644 --- a/packages/devtools_app/lib/src/shared/config_specific/drag_and_drop/drag_and_drop.dart +++ b/packages/devtools_app/lib/src/shared/config_specific/drag_and_drop/drag_and_drop.dart @@ -151,19 +151,18 @@ class DragAndDropState extends State { _refreshDragAndDropManager(View.of(context).viewId); return MetaData( metaData: DragAndDropMetaData(state: this), - child: - widget.handleDrop != null - ? ValueListenableBuilder( - valueListenable: _dragging, - builder: (context, dragging, _) { - // TODO(kenz): use AnimatedOpacity instead. - return Opacity( - opacity: dragging ? 0.5 : 1.0, - child: widget.child, - ); - }, - ) - : widget.child, + child: widget.handleDrop != null + ? ValueListenableBuilder( + valueListenable: _dragging, + builder: (context, dragging, _) { + // TODO(kenz): use AnimatedOpacity instead. + return Opacity( + opacity: dragging ? 0.5 : 1.0, + child: widget.child, + ); + }, + ) + : widget.child, ); } diff --git a/packages/devtools_app/lib/src/shared/console/console.dart b/packages/devtools_app/lib/src/shared/console/console.dart index 273d4d70b74..ea3cc46bda3 100644 --- a/packages/devtools_app/lib/src/shared/console/console.dart +++ b/packages/devtools_app/lib/src/shared/console/console.dart @@ -48,7 +48,10 @@ class ConsoleFrame extends StatelessWidget { padding: const EdgeInsets.only(bottom: densePadding), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, - children: [if (title != null) title!, Expanded(child: child)], + children: [ + if (title != null) title!, + Expanded(child: child), + ], ), ); } diff --git a/packages/devtools_app/lib/src/shared/console/eval/auto_complete.dart b/packages/devtools_app/lib/src/shared/console/eval/auto_complete.dart index 5e151be0505..5cfc2aa3ab7 100644 --- a/packages/devtools_app/lib/src/shared/console/eval/auto_complete.dart +++ b/packages/devtools_app/lib/src/shared/console/eval/auto_complete.dart @@ -170,11 +170,10 @@ Future> libraryMemberAutocompletes( LibraryRef libraryRef, { required bool includePrivates, }) async { - var result = - (await _appState.cache.libraryMemberAutocomplete.putIfAbsent( - libraryRef, - () => _libraryMemberAutocompletes(evalService, libraryRef), - )).nonNulls; + var result = (await _appState.cache.libraryMemberAutocomplete.putIfAbsent( + libraryRef, + () => _libraryMemberAutocompletes(evalService, libraryRef), + )).nonNulls; if (!includePrivates) { result = result.where((name) => !isPrivateMember(name)); } diff --git a/packages/devtools_app/lib/src/shared/console/eval/eval_service.dart b/packages/devtools_app/lib/src/shared/console/eval/eval_service.dart index 90b3b38fe91..97aaf706131 100644 --- a/packages/devtools_app/lib/src/shared/console/eval/eval_service.dart +++ b/packages/devtools_app/lib/src/shared/console/eval/eval_service.dart @@ -185,10 +185,12 @@ class EvalService extends DisposableController with AutoDisposeControllerMixin { ) async { final isolateId = isolateRef.id!; - final theClass = (await serviceConnection.serviceManager.service! - .getClassList(isolateId)).classes!.firstWhereOrNull( - (ref) => object.className?.matches(ref) ?? false, - ); + final theClass = + (await serviceConnection.serviceManager.service!.getClassList( + isolateId, + )).classes!.firstWhereOrNull( + (ref) => object.className?.matches(ref) ?? false, + ); return await findInstance(isolateId, theClass?.id, object.code); } diff --git a/packages/devtools_app/lib/src/shared/console/widgets/console_pane.dart b/packages/devtools_app/lib/src/shared/console/widgets/console_pane.dart index 7c4d80fb33f..5a40db7b21f 100644 --- a/packages/devtools_app/lib/src/shared/console/widgets/console_pane.dart +++ b/packages/devtools_app/lib/src/shared/console/widgets/console_pane.dart @@ -24,8 +24,8 @@ class ConsolePaneHeader extends AreaPaneHeader { const ConsoleHelpLink(), const SizedBox(width: densePadding), CopyToClipboardControl( - dataProvider: - () => serviceConnection.consoleService.stdio.value.join('\n'), + dataProvider: () => + serviceConnection.consoleService.stdio.value.join('\n'), buttonKey: ConsolePane.copyToClipboardButtonKey, ), const SizedBox(width: densePadding), @@ -62,7 +62,11 @@ class ConsolePane extends StatelessWidget { } return Column( - children: [Expanded(child: Console(lines: stdio, footer: footer))], + children: [ + Expanded( + child: Console(lines: stdio, footer: footer), + ), + ], ); } } diff --git a/packages/devtools_app/lib/src/shared/console/widgets/description.dart b/packages/devtools_app/lib/src/shared/console/widgets/description.dart index 70b88a2dc72..ac885f86a36 100644 --- a/packages/devtools_app/lib/src/shared/console/widgets/description.dart +++ b/packages/devtools_app/lib/src/shared/console/widgets/description.dart @@ -192,59 +192,55 @@ class DiagnosticsNodeDescription extends StatelessWidget { diagnostic?.descriptionTextStyleFromBuild = textStyle; final textSpan = TextSpan( - children: - buildDescriptionTextSpans( - description: description, - textStyle: textStyle, - colorScheme: colorScheme, - diagnostic: diagnostic, - searchValue: searchValue, - nodeDescriptionHighlightStyle: nodeDescriptionHighlightStyle, - ).toList(), + children: buildDescriptionTextSpans( + description: description, + textStyle: textStyle, + colorScheme: colorScheme, + diagnostic: diagnostic, + searchValue: searchValue, + nodeDescriptionHighlightStyle: nodeDescriptionHighlightStyle, + ).toList(), ); final diagnosticLocal = diagnostic!; final inspectorService = serviceConnection.inspectorService!; return HoverCardTooltip.async( - enabled: - () => - preferences.inspector.hoverEvalModeEnabled.value && - diagnosticLocal.objectGroupApi != null && - !isPrimitiveValueOrNull(description), - asyncGenerateHoverCardData: ({ - required event, - required isHoverStale, - }) async { - final group = inspectorService.createObjectGroup('hover'); - - if (isHoverStale()) return Future.value(); - final value = await group.toObservatoryInstanceRef( - diagnosticLocal.valueRef, - ); - - final variable = DartObjectNode.fromValue( - value: value, - isolateRef: inspectorService.isolateRef, - diagnostic: diagnosticLocal, - ); - - if (isHoverStale()) return Future.value(); - await buildVariablesTree(variable); - final tasks = >[]; - for (final child in variable.children) { - tasks.add(() async { - if (!isHoverStale()) await buildVariablesTree(child); - }()); - } - await tasks.wait; - variable.expand(); - - return HoverCardData( - title: diagnosticLocal.toStringShort(), - contents: Material(child: ExpandableVariable(variable: variable)), - ); - }, + enabled: () => + preferences.inspector.hoverEvalModeEnabled.value && + diagnosticLocal.objectGroupApi != null && + !isPrimitiveValueOrNull(description), + asyncGenerateHoverCardData: + ({required event, required isHoverStale}) async { + final group = inspectorService.createObjectGroup('hover'); + + if (isHoverStale()) return Future.value(); + final value = await group.toObservatoryInstanceRef( + diagnosticLocal.valueRef, + ); + + final variable = DartObjectNode.fromValue( + value: value, + isolateRef: inspectorService.isolateRef, + diagnostic: diagnosticLocal, + ); + + if (isHoverStale()) return Future.value(); + await buildVariablesTree(variable); + final tasks = >[]; + for (final child in variable.children) { + tasks.add(() async { + if (!isHoverStale()) await buildVariablesTree(child); + }()); + } + await tasks.wait; + variable.expand(); + + return HoverCardData( + title: diagnosticLocal.toStringShort(), + contents: Material(child: ExpandableVariable(variable: variable)), + ); + }, child: DescriptionDisplay( text: textSpan, multiline: multiline, @@ -265,10 +261,9 @@ class DiagnosticsNodeDescription extends StatelessWidget { final theme = Theme.of(context); final colorScheme = theme.colorScheme; - final icon = - customIconName != null - ? RemoteDiagnosticsNode.iconMaker.fromWidgetName(customIconName) - : diagnosticLocal.icon; + final icon = customIconName != null + ? RemoteDiagnosticsNode.iconMaker.fromWidgetName(customIconName) + : diagnosticLocal.icon; final children = []; @@ -329,10 +324,9 @@ class DiagnosticsNodeDescription extends StatelessWidget { final green = JsonUtils.getIntMember(properties, 'green'); final blue = JsonUtils.getIntMember(properties, 'blue'); String radix(int chan) => chan.toRadixString(16).padLeft(2, '0'); - description = - alpha == 255 - ? '#${radix(red)}${radix(green)}${radix(blue)}' - : '#${radix(alpha)}${radix(red)}${radix(green)}${radix(blue)}'; + description = alpha == 255 + ? '#${radix(red)}${radix(green)}${radix(blue)}' + : '#${radix(alpha)}${radix(red)}${radix(green)}${radix(blue)}'; final color = Color.fromARGB(alpha, red, green, blue); children.add(_paddedIcon(_colorIconMaker.getCustomIcon(color))); @@ -479,10 +473,9 @@ class DiagnosticsNodeDescription extends StatelessWidget { text: errorText, // When the node is selected, the background will be an error // color so don't render the text the same color. - style: - isSelected - ? DiagnosticsTextStyles.regular(colorScheme) - : DiagnosticsTextStyles.error(colorScheme), + style: isSelected + ? DiagnosticsTextStyles.regular(colorScheme) + : DiagnosticsTextStyles.error(colorScheme), ), ), ); diff --git a/packages/devtools_app/lib/src/shared/console/widgets/display_provider.dart b/packages/devtools_app/lib/src/shared/console/widgets/display_provider.dart index 5eccdde4f70..2fed4f1c9b4 100644 --- a/packages/devtools_app/lib/src/shared/console/widgets/display_provider.dart +++ b/packages/devtools_app/lib/src/shared/console/widgets/display_provider.dart @@ -91,21 +91,19 @@ class _DisplayProviderState extends State { overflow: TextOverflow.ellipsis, TextSpan( text: hasName ? widget.variable.name : null, - style: - widget.variable.artificialName - ? theme.subtleFixedFontStyle - : theme.fixedFontStyle.apply( - color: theme.colorScheme.controlFlowSyntaxColor, - ), + style: widget.variable.artificialName + ? theme.subtleFixedFontStyle + : theme.fixedFontStyle.apply( + color: theme.colorScheme.controlFlowSyntaxColor, + ), children: [ if (hasName) TextSpan(text: ': ', style: theme.fixedFontStyle), TextSpan( text: displayValue, - style: - widget.variable.artificialValue - ? theme.subtleFixedFontStyle - : _variableDisplayStyle(theme, widget.variable), + style: widget.variable.artificialValue + ? theme.subtleFixedFontStyle + : _variableDisplayStyle(theme, widget.variable), ), ], ), @@ -344,8 +342,9 @@ class _InteractivityWrapperState extends State { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: _onTap, - onSecondaryTapUp: - contextMenuOnSecondaryTapEnabled ? _onSecondaryTapUp : null, + onSecondaryTapUp: contextMenuOnSecondaryTapEnabled + ? _onSecondaryTapUp + : null, child: widget.child, ); } diff --git a/packages/devtools_app/lib/src/shared/console/widgets/evaluate.dart b/packages/devtools_app/lib/src/shared/console/widgets/evaluate.dart index 6bdbadf78ed..e7c07d9704a 100644 --- a/packages/devtools_app/lib/src/shared/console/widgets/evaluate.dart +++ b/packages/devtools_app/lib/src/shared/console/widgets/evaluate.dart @@ -161,8 +161,8 @@ class ExpressionEvalFieldState extends State final matches = parts.activeWord.startsWith(_activeWord) && _activeWord.isNotEmpty - ? _filterMatches(_matches, parts.activeWord) - : await widget.getAutoCompleteResults(parts, evalService); + ? _filterMatches(_matches, parts.activeWord) + : await widget.getAutoCompleteResults(parts, evalService); _matches = matches; _activeWord = parts.activeWord; @@ -174,11 +174,10 @@ class ExpressionEvalFieldState extends State ..clearSearchAutoComplete() ..clearCurrentSuggestion(); } else { - final results = - matches - .sublist(0, min(defaultTopMatchesLimit, matches.length)) - .map((match) => AutoCompleteMatch(match)) - .toList(); + final results = matches + .sublist(0, min(defaultTopMatchesLimit, matches.length)) + .map((match) => AutoCompleteMatch(match)) + .toList(); _autoCompleteController ..searchAutoComplete.value = results @@ -231,21 +230,18 @@ class ExpressionEvalFieldState extends State labelText: 'Eval. Enter "?" for help.', labelStyle: Theme.of(context).subtleTextStyle, ), - overlayXPositionBuilder: ( - String inputValue, - TextStyle? inputStyle, - ) { - // X-coordinate is equivalent to the width of the input text - // up to the last "." or the insertion point (cursor): - final indexOfDot = inputValue.lastIndexOf('.'); - final textSegment = - indexOfDot != -1 + overlayXPositionBuilder: + (String inputValue, TextStyle? inputStyle) { + // X-coordinate is equivalent to the width of the input text + // up to the last "." or the insertion point (cursor): + final indexOfDot = inputValue.lastIndexOf('.'); + final textSegment = indexOfDot != -1 ? inputValue.substring(0, indexOfDot + 1) : inputValue; - return calculateTextSpanWidth( - TextSpan(text: textSegment, style: inputStyle), - ); - }, + return calculateTextSpanWidth( + TextSpan(text: textSegment, style: inputStyle), + ); + }, // Disable ligatures, so the suggestions of the auto complete work correcly. style: Theme.of(context).fixedFontStyle.copyWith( fontFeatures: [const FontFeature.disable('liga')], @@ -444,20 +440,18 @@ class ExpressionEvalFieldState extends State return kSuccess; } - final isolateId = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value - ?.id; - final isolateName = - serviceConnection - .serviceManager - .isolateManager - .selectedIsolate - .value - ?.name; + final isolateId = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value + ?.id; + final isolateName = serviceConnection + .serviceManager + .isolateManager + .selectedIsolate + .value + ?.name; if (isolateId == null || isolateName == null) { _emitToConsole('Selected isolate cannot be detected.'); diff --git a/packages/devtools_app/lib/src/shared/development_helpers.dart b/packages/devtools_app/lib/src/shared/development_helpers.dart index 48c54a4d20b..770016a560d 100644 --- a/packages/devtools_app/lib/src/shared/development_helpers.dart +++ b/packages/devtools_app/lib/src/shared/development_helpers.dart @@ -66,8 +66,9 @@ ExtensionEnabledState debugHandleExtensionEnabledState({ bool? enable, }) { if (enable != null) { - stubExtensionEnabledStates[extensionName] = - enable ? ExtensionEnabledState.enabled : ExtensionEnabledState.disabled; + stubExtensionEnabledStates[extensionName] = enable + ? ExtensionEnabledState.enabled + : ExtensionEnabledState.disabled; } return stubExtensionEnabledStates.putIfAbsent( extensionName, diff --git a/packages/devtools_app/lib/src/shared/diagnostics/dart_object_node.dart b/packages/devtools_app/lib/src/shared/diagnostics/dart_object_node.dart index d3bd6dbd6c6..b7279fb7b9f 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/dart_object_node.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/dart_object_node.dart @@ -313,10 +313,9 @@ class DartObjectNode extends TreeNode { // to `children.length` if it's not provide (this means we don't get // the count until the record is expanded): final count = value.length ?? children.length; - valueStr = - count == 0 - ? 'Record' - : 'Record ($count ${pluralize('field', count)})'; + valueStr = count == 0 + ? 'Record' + : 'Record ($count ${pluralize('field', count)})'; } else if (value.valueAsString == null) { valueStr = value.classRef?.name ?? ''; } else { @@ -374,8 +373,9 @@ class DartObjectNode extends TreeNode { if (text != null) return text!; final instanceRef = ref!.instanceRef; - final value = - instanceRef is InstanceRef ? instanceRef.valueAsString : instanceRef; + final value = instanceRef is InstanceRef + ? instanceRef.valueAsString + : instanceRef; return '$name - $value'; } diff --git a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart index ff7c99ead9f..f84cca86db1 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart @@ -128,9 +128,9 @@ abstract class InspectorServiceBase extends DisposableController return useDaemonApi ? await invokeServiceMethodDaemonNoGroupArgs(methodName) == true : (await invokeServiceMethodObservatoryNoGroup( - methodName, - ))?.valueAsString == - 'true'; + methodName, + ))?.valueAsString == + 'true'; } Future invokeServiceMethodDaemonNoGroupArgs( @@ -338,8 +338,10 @@ class InspectorService extends InspectorServiceBase { // here. assert(!directory.startsWith('package:')); - final parts = - directory.split('/').where((element) => element.isNotEmpty).toList(); + final parts = directory + .split('/') + .where((element) => element.isNotEmpty) + .toList(); final libIndex = parts.lastIndexOf('lib'); final path = libIndex > 0 ? parts.sublist(0, libIndex) : parts; // Special case handling of bazel packages. @@ -500,13 +502,12 @@ abstract class InspectorObjectGroupBase @override Future dispose() { // No need to dispose the group if the isolate is already gone. - final disposeComplete = - inspectorService.isolateRef != null - ? invokeVoidServiceMethod( - WidgetInspectorServiceExtensions.disposeGroup.name, - groupName, - ) - : Future.value(); + final disposeComplete = inspectorService.isolateRef != null + ? invokeVoidServiceMethod( + WidgetInspectorServiceExtensions.disposeGroup.name, + groupName, + ) + : Future.value(); disposed = true; return disposeComplete; } @@ -518,11 +519,11 @@ abstract class InspectorObjectGroupBase if (disposed) return null; return useDaemonApi ? parseDiagnosticsNodeDaemon( - invokeServiceMethodDaemonInspectorRef(methodName, ref), - ) + invokeServiceMethodDaemonInspectorRef(methodName, ref), + ) : parseDiagnosticsNodeObservatory( - invokeServiceMethodObservatoryInspectorRef(methodName, ref), - ); + invokeServiceMethodObservatoryInspectorRef(methodName, ref), + ); } Future invokeServiceMethodWithArgReturningNode( @@ -532,11 +533,11 @@ abstract class InspectorObjectGroupBase if (disposed) return null; return useDaemonApi ? parseDiagnosticsNodeDaemon( - invokeServiceMethodDaemonArg(methodName, arg, groupName), - ) + invokeServiceMethodDaemonArg(methodName, arg, groupName), + ) : parseDiagnosticsNodeObservatory( - invokeServiceMethodObservatoryWithGroupName1(methodName, arg), - ); + invokeServiceMethodObservatoryWithGroupName1(methodName, arg), + ); } Future invokeServiceMethodDaemonArg( @@ -853,15 +854,15 @@ abstract class InspectorObjectGroupBase if (disposed) return const []; return useDaemonApi ? parseDiagnosticsNodesDaemon( - invokeServiceMethodDaemonInspectorRef(methodName, instanceRef), - parent, - isProperty, - ) + invokeServiceMethodDaemonInspectorRef(methodName, instanceRef), + parent, + isProperty, + ) : parseDiagnosticsNodesObservatory( - invokeServiceMethodObservatoryInspectorRef(methodName, instanceRef), - parent, - isProperty, - ); + invokeServiceMethodObservatoryInspectorRef(methodName, instanceRef), + parent, + isProperty, + ); } /// Evaluate an expression where `object` references the `inspectorRef` or @@ -1061,19 +1062,19 @@ class ObjectGroup extends InspectorObjectGroupBase { } return useDaemonApi ? handleSetSelectionDaemon( - invokeServiceMethodDaemonInspectorRef( - WidgetInspectorServiceExtensions.setSelectionById.name, - selection, - ), - uiAlreadyUpdated, - ) + invokeServiceMethodDaemonInspectorRef( + WidgetInspectorServiceExtensions.setSelectionById.name, + selection, + ), + uiAlreadyUpdated, + ) : handleSetSelectionObservatory( - invokeServiceMethodObservatoryInspectorRef( - WidgetInspectorServiceExtensions.setSelectionById.name, - selection, - ), - uiAlreadyUpdated, - ); + invokeServiceMethodObservatoryInspectorRef( + WidgetInspectorServiceExtensions.setSelectionById.name, + selection, + ), + uiAlreadyUpdated, + ); } Future setSelection(GenericInstanceRef selection) async { diff --git a/packages/devtools_app/lib/src/shared/diagnostics/references.dart b/packages/devtools_app/lib/src/shared/diagnostics/references.dart index 9305d34f4c3..a353f7c83b2 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/references.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/references.dart @@ -101,43 +101,41 @@ Future addChildReferences(DartObjectNode variable) async { return; case RefNodeType.staticInRefs: - final children = - ref.heapSelection - .references(ref.refNodeType.direction!) - .where((s) => !s.className!.isNull) - .map( - (s) => DartObjectNode.references( - s.className!.className, - ObjectReferences( - refNodeType: RefNodeType.staticInRefs, - heapSelection: s, - isolateRef: ref.isolateRef, - value: null, - ), - isRerootable: true, - ), - ) - .toList(); + final children = ref.heapSelection + .references(ref.refNodeType.direction!) + .where((s) => !s.className!.isNull) + .map( + (s) => DartObjectNode.references( + s.className!.className, + ObjectReferences( + refNodeType: RefNodeType.staticInRefs, + heapSelection: s, + isolateRef: ref.isolateRef, + value: null, + ), + isRerootable: true, + ), + ) + .toList(); variable.addAllChildren(children); return; case RefNodeType.staticOutRefs: - final children = - ref.heapSelection - .references(ref.refNodeType.direction!) - .where((s) => !s.className!.isNull) - .map( - (s) => DartObjectNode.references( - '${s.className!.className}, ${prettyPrintRetainedSize(s.retainedSize)}', - ObjectReferences( - refNodeType: RefNodeType.staticOutRefs, - heapSelection: s, - isolateRef: ref.isolateRef, - value: null, - ), - isRerootable: true, - ), - ) - .toList(); + final children = ref.heapSelection + .references(ref.refNodeType.direction!) + .where((s) => !s.className!.isNull) + .map( + (s) => DartObjectNode.references( + '${s.className!.className}, ${prettyPrintRetainedSize(s.retainedSize)}', + ObjectReferences( + refNodeType: RefNodeType.staticOutRefs, + heapSelection: s, + isolateRef: ref.isolateRef, + value: null, + ), + isRerootable: true, + ), + ) + .toList(); variable.addAllChildren(children); return; case RefNodeType.liveRefRoot: diff --git a/packages/devtools_app/lib/src/shared/diagnostics/tree_builder.dart b/packages/devtools_app/lib/src/shared/diagnostics/tree_builder.dart index c68aec96c57..d4f02f17553 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/tree_builder.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/tree_builder.dart @@ -102,10 +102,10 @@ Future _addDiagnosticChildrenIfNeeded( void _setupGrouping(DartObjectNode variable) { final numChildrenInGrouping = variable.childCount >= pow(DartObjectNode.maxChildrenInGrouping, 2) - ? (roundToNearestPow10(variable.childCount) / - DartObjectNode.maxChildrenInGrouping) - .floor() - : DartObjectNode.maxChildrenInGrouping; + ? (roundToNearestPow10(variable.childCount) / + DartObjectNode.maxChildrenInGrouping) + .floor() + : DartObjectNode.maxChildrenInGrouping; var start = variable.offset; final end = start + variable.childCount; diff --git a/packages/devtools_app/lib/src/shared/editor/api_classes.dart b/packages/devtools_app/lib/src/shared/editor/api_classes.dart index 9ed04a2190a..612fc47f0ba 100644 --- a/packages/devtools_app/lib/src/shared/editor/api_classes.dart +++ b/packages/devtools_app/lib/src/shared/editor/api_classes.dart @@ -327,11 +327,10 @@ class ActiveLocationChangedEvent extends EditorEvent { textDocument: TextDocument.fromJson( map[Field.textDocument] as Map, ), - selections: - (map[Field.selections] as List) - .cast>() - .map(EditorSelection.fromJson) - .toList(), + selections: (map[Field.selections] as List) + .cast>() + .map(EditorSelection.fromJson) + .toList(), ); final List selections; @@ -479,17 +478,13 @@ class EditableArgumentsResult with Serializable { : this( name: map[Field.name] as String?, documentation: map[Field.documentation] as String?, - range: - (map[Field.range] as Map?) == null - ? null - : EditorRange.fromJson( - map[Field.range] as Map, - ), - args: - (map[Field.arguments] as List? ?? []) - .cast>() - .map(EditableArgument.fromJson) - .toList(), + range: (map[Field.range] as Map?) == null + ? null + : EditorRange.fromJson(map[Field.range] as Map), + args: (map[Field.arguments] as List? ?? []) + .cast>() + .map(EditableArgument.fromJson) + .toList(), ); final List args; @@ -693,11 +688,10 @@ class GetDevicesResult with Serializable { GetDevicesResult.fromJson(Map map) : this( - devices: - (map[Field.devices] as List) - .cast>() - .map(EditorDevice.fromJson) - .toList(), + devices: (map[Field.devices] as List) + .cast>() + .map(EditorDevice.fromJson) + .toList(), selectedDeviceId: map[Field.selectedDeviceId] as String?, ); @@ -717,11 +711,10 @@ class GetDebugSessionsResult with Serializable { GetDebugSessionsResult.fromJson(Map map) : this( - debugSessions: - (map[Field.debugSessions] as List) - .cast>() - .map(EditorDebugSession.fromJson) - .toList(), + debugSessions: (map[Field.debugSessions] as List) + .cast>() + .map(EditorDebugSession.fromJson) + .toList(), ); final List debugSessions; diff --git a/packages/devtools_app/lib/src/shared/editor/editor_client.dart b/packages/devtools_app/lib/src/shared/editor/editor_client.dart index b3ea9632764..b8ebc72264d 100644 --- a/packages/devtools_app/lib/src/shared/editor/editor_client.dart +++ b/packages/devtools_app/lib/src/shared/editor/editor_client.dart @@ -78,14 +78,13 @@ class EditorClient extends DisposableController return; } - final info = - isRegistered - ? ServiceRegistered( - service: service, - method: method, - capabilities: capabilities, - ) - : ServiceUnregistered(service: service, method: method); + final info = isRegistered + ? ServiceRegistered( + service: service, + method: method, + capabilities: capabilities, + ) + : ServiceUnregistered(service: service, method: method); _editorServiceChangedController.add(info); }), ); @@ -274,12 +273,9 @@ class EditorClient extends DisposableController }, ); final rawResult = response.result[Field.result]; - result = - rawResult != null - ? EditableArgumentsResult.fromJson( - rawResult as Map, - ) - : null; + result = rawResult != null + ? EditableArgumentsResult.fromJson(rawResult as Map) + : null; } on RpcException catch (e, st) { // We expect content modified errors if a user edits their code before the // request completes. Therefore it is safe to ignore. diff --git a/packages/devtools_app/lib/src/shared/environment_parameters/environment_parameters_external.dart b/packages/devtools_app/lib/src/shared/environment_parameters/environment_parameters_external.dart index 8bec9e34248..30cd68fb0f5 100644 --- a/packages/devtools_app/lib/src/shared/environment_parameters/environment_parameters_external.dart +++ b/packages/devtools_app/lib/src/shared/environment_parameters/environment_parameters_external.dart @@ -22,12 +22,11 @@ class ExternalDevToolsEnvironmentParameters GaLink issueTrackerLink({String? additionalInfo, String? issueTitle}) { return GaLink( display: _newDevToolsIssueUriDisplay, - url: - newDevToolsGitHubIssueUriLengthSafe( - additionalInfo: additionalInfo, - issueTitle: issueTitle, - environment: issueLinkDetails(), - ).toString(), + url: newDevToolsGitHubIssueUriLengthSafe( + additionalInfo: additionalInfo, + issueTitle: issueTitle, + environment: issueLinkDetails(), + ).toString(), gaScreenName: gac.devToolsMain, gaSelectedItemDescription: gac.feedbackLink, ); @@ -53,8 +52,8 @@ class ExternalDevToolsEnvironmentParameters @override InspectorServiceBase? inspectorServiceProvider() => serviceConnection.serviceManager.connectedApp!.isFlutterAppNow == true - ? InspectorService() - : null; + ? InspectorService() + : null; @override String get perfettoIndexLocation => diff --git a/packages/devtools_app/lib/src/shared/framework/app_error_handling.dart b/packages/devtools_app/lib/src/shared/framework/app_error_handling.dart index 418b78f7738..68ad3953e21 100644 --- a/packages/devtools_app/lib/src/shared/framework/app_error_handling.dart +++ b/packages/devtools_app/lib/src/shared/framework/app_error_handling.dart @@ -113,8 +113,9 @@ SingleMapping? _cachedJsSourceMapping; SingleMapping? _cachedWasmSourceMapping; Future _fetchSourceMapping() async { - final cachedSourceMapping = - kIsWasm ? _cachedWasmSourceMapping : _cachedJsSourceMapping; + final cachedSourceMapping = kIsWasm + ? _cachedWasmSourceMapping + : _cachedJsSourceMapping; return cachedSourceMapping ?? (await _initializeSourceMapping()); } @@ -141,10 +142,9 @@ Future _sourceMapStackTrace(StackTrace? stack) async { final mappedStackTrace = await _maybeMapStackTrace(originalStackTrace); // If mapping fails, revert back to the original stack trace: - final stackTrace = - mappedStackTrace.toString().isEmpty - ? originalStackTrace - : mappedStackTrace; + final stackTrace = mappedStackTrace.toString().isEmpty + ? originalStackTrace + : mappedStackTrace; return stack_trace.Trace.from(stackTrace); } diff --git a/packages/devtools_app/lib/src/shared/framework/screen.dart b/packages/devtools_app/lib/src/shared/framework/screen.dart index c13102ec25c..6defab658d6 100644 --- a/packages/devtools_app/lib/src/shared/framework/screen.dart +++ b/packages/devtools_app/lib/src/shared/framework/screen.dart @@ -391,13 +391,10 @@ abstract class Screen { DevToolsIcon( icon: icon, iconAsset: iconAsset, - size: - iconAsset != null - // Add 1.0 to adjust for margins on the screen icon assets. - ? scaleByFontFactor( - defaultIconSizeBeforeScaling + 1.0, - ) - : defaultIconSize, + size: iconAsset != null + // Add 1.0 to adjust for margins on the screen icon assets. + ? scaleByFontFactor(defaultIconSizeBeforeScaling + 1.0) + : defaultIconSize, ), if (title.isNotEmpty) Padding( @@ -487,10 +484,9 @@ abstract class Screen { _log.finest('for offline mode: returning ${screen.worksWithOfflineData}'); return ( show: screen.worksWithOfflineData, - disabledReason: - screen.worksWithOfflineData - ? null - : ScreenDisabledReason.offlineDataNotSupported, + disabledReason: screen.worksWithOfflineData + ? null + : ScreenDisabledReason.offlineDataNotSupported, ); } @@ -572,10 +568,9 @@ class BadgePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final paint = - Paint() - ..color = colorScheme.errorContainer - ..style = PaintingStyle.fill; + final paint = Paint() + ..color = colorScheme.errorContainer + ..style = PaintingStyle.fill; final countPainter = TextPainter( text: TextSpan( diff --git a/packages/devtools_app/lib/src/shared/framework/screen_controllers.dart b/packages/devtools_app/lib/src/shared/framework/screen_controllers.dart index e182f80a30d..427254c8bd5 100644 --- a/packages/devtools_app/lib/src/shared/framework/screen_controllers.dart +++ b/packages/devtools_app/lib/src/shared/framework/screen_controllers.dart @@ -56,10 +56,9 @@ class ScreenControllers { /// When DevTools is showing offline data, the offline screen controller will /// be returned. T lookup() { - final controllers = - offlineDataController.showingOfflineData.value - ? offlineControllers - : this.controllers; + final controllers = offlineDataController.showingOfflineData.value + ? offlineControllers + : this.controllers; assert(controllers.containsKey(T)); return controllers[T]!.controller as T; } @@ -94,10 +93,9 @@ class ScreenControllers { void Function(DevToolsScreenController screenController) callback, { bool includeOfflineControllers = false, }) { - final controllers = - includeOfflineControllers - ? [...this.controllers.values, ...offlineControllers.values] - : this.controllers.values; + final controllers = includeOfflineControllers + ? [...this.controllers.values, ...offlineControllers.values] + : this.controllers.values; for (final lazyController in controllers) { if (lazyController.initialized) { callback(lazyController.controller); @@ -115,10 +113,9 @@ class ScreenControllers { callback, { bool includeOfflineControllers = false, }) async { - final controllers = - includeOfflineControllers - ? [...this.controllers.values, ...offlineControllers.values] - : this.controllers.values; + final controllers = includeOfflineControllers + ? [...this.controllers.values, ...offlineControllers.values] + : this.controllers.values; Future helper( FutureOr Function(DevToolsScreenController) futureOr, diff --git a/packages/devtools_app/lib/src/shared/http/_http_exception.dart b/packages/devtools_app/lib/src/shared/http/_http_exception.dart index 8cde8848a5f..9dcb02941f8 100644 --- a/packages/devtools_app/lib/src/shared/http/_http_exception.dart +++ b/packages/devtools_app/lib/src/shared/http/_http_exception.dart @@ -11,10 +11,9 @@ class HttpException { @override String toString() { - final b = - StringBuffer() - ..write('HttpException: ') - ..write(message); + final b = StringBuffer() + ..write('HttpException: ') + ..write(message); if (uri != null) { b.write(', uri = $uri'); } diff --git a/packages/devtools_app/lib/src/shared/http/http_request_data.dart b/packages/devtools_app/lib/src/shared/http/http_request_data.dart index 1d45371e0a4..55f5c4148ad 100644 --- a/packages/devtools_app/lib/src/shared/http/http_request_data.dart +++ b/packages/devtools_app/lib/src/shared/http/http_request_data.dart @@ -56,15 +56,14 @@ class DartIOHttpRequestData extends NetworkRequest { modifiedRequestData.containsKey(HttpRequestDataKeys.requestBody.name) && modifiedRequestData.containsKey(HttpRequestDataKeys.responseBody.name); - final parsedRequest = - isFullRequest - ? HttpProfileRequest.parse(modifiedRequestData) - : HttpProfileRequestRef.parse(modifiedRequestData); + final parsedRequest = isFullRequest + ? HttpProfileRequest.parse(modifiedRequestData) + : HttpProfileRequestRef.parse(modifiedRequestData); - final responseBody = - responseContent?[HttpRequestDataKeys.text.name]?.toString(); - final requestBody = - requestPostData?[HttpRequestDataKeys.text.name]?.toString(); + final responseBody = responseContent?[HttpRequestDataKeys.text.name] + ?.toString(); + final requestBody = requestPostData?[HttpRequestDataKeys.text.name] + ?.toString(); return DartIOHttpRequestData( parsedRequest!, @@ -77,8 +76,8 @@ class DartIOHttpRequestData extends NetworkRequest { @override Map toJson() { return { - HttpRequestDataKeys.request.name: - (_request as HttpProfileRequest).toJson(), + HttpRequestDataKeys.request.name: (_request as HttpProfileRequest) + .toJson(), }; } @@ -253,8 +252,9 @@ class DartIOHttpRequestData extends NetworkRequest { /// All instant events logged to the timeline for this HTTP request. List get instantEvents { if (_instantEvents == null) { - _instantEvents = - _request.events.map((e) => DartIOHttpInstantEvent._(e)).toList(); + _instantEvents = _request.events + .map((e) => DartIOHttpInstantEvent._(e)) + .toList(); _recalculateInstantEventTimes(); } return _instantEvents!; @@ -267,10 +267,9 @@ class DartIOHttpRequestData extends NetworkRequest { requestCookies.isNotEmpty || responseCookies.isNotEmpty; /// A list of all cookies contained within the request headers. - List get requestCookies => - _hasError - ? [] - : DartIOHttpRequestData._parseCookies(_request.request?.cookies); + List get requestCookies => _hasError + ? [] + : DartIOHttpRequestData._parseCookies(_request.request?.cookies); /// A list of all cookies contained within the response headers. List get responseCookies => @@ -371,10 +370,9 @@ class DartIOHttpRequestData extends NetworkRequest { DateTime lastTime = _request.startTime; for (final instant in instantEvents) { final instantTime = instant.timestamp; - instant._timeRange = - TimeRange() - ..start = Duration(microseconds: lastTime.microsecondsSinceEpoch) - ..end = Duration(microseconds: instantTime.microsecondsSinceEpoch); + instant._timeRange = TimeRange() + ..start = Duration(microseconds: lastTime.microsecondsSinceEpoch) + ..end = Duration(microseconds: instantTime.microsecondsSinceEpoch); lastTime = instantTime; } } diff --git a/packages/devtools_app/lib/src/shared/managers/banner_messages.dart b/packages/devtools_app/lib/src/shared/managers/banner_messages.dart index 5d468e4e6db..c3fc64a5a86 100644 --- a/packages/devtools_app/lib/src/shared/managers/banner_messages.dart +++ b/packages/devtools_app/lib/src/shared/managers/banner_messages.dart @@ -256,8 +256,8 @@ class BannerMessage extends StatelessWidget { size: actionsIconSize, color: foregroundColor, ), - onPressed: - () => bannerMessages.removeMessage(this, dismiss: true), + onPressed: () => + bannerMessages.removeMessage(this, dismiss: true), ), ], ), @@ -333,24 +333,23 @@ class DebugModePerformanceMessage extends BannerWarning { DebugModePerformanceMessage({required super.screenId}) : super( key: Key('DebugModePerformanceMessage - $screenId'), - buildTextSpans: - (context) => [ - const TextSpan( - text: - 'You are running your app in debug mode. Debug mode performance ' - 'is not indicative of release performance, but you may use debug ' - 'mode to gain visibility into the work the system performs (e.g. ' - 'building widgets, calculating layouts, rasterizing scenes,' - ' etc.). For precise measurement of performance, relaunch your ' - 'application in ', - ), - _runInProfileModeTextSpan( - context, - screenId: screenId, - style: Theme.of(context).warningMessageLinkStyle, - ), - const TextSpan(text: '.'), - ], + buildTextSpans: (context) => [ + const TextSpan( + text: + 'You are running your app in debug mode. Debug mode performance ' + 'is not indicative of release performance, but you may use debug ' + 'mode to gain visibility into the work the system performs (e.g. ' + 'building widgets, calculating layouts, rasterizing scenes,' + ' etc.). For precise measurement of performance, relaunch your ' + 'application in ', + ), + _runInProfileModeTextSpan( + context, + screenId: screenId, + style: Theme.of(context).warningMessageLinkStyle, + ), + const TextSpan(text: '.'), + ], ); } @@ -415,28 +414,26 @@ class HighCpuSamplingRateMessage extends BannerWarning { HighCpuSamplingRateMessage({required super.screenId}) : super( key: generateKey(screenId), - buildTextSpans: - (context) => [ - const TextSpan( - text: ''' + buildTextSpans: (context) => [ + const TextSpan( + text: ''' You are opting in to a high CPU sampling rate. This may affect the performance of your application. Please read our ''', - ), - GaLinkTextSpan( - link: GaLink( - display: 'documentation', - url: _cpuSamplingRateDocsUrl, - gaScreenName: screenId, - gaSelectedItemDescription: - gac.CpuProfilerDocs.profileGranularityDocs.name, - ), - context: context, - style: Theme.of(context).warningMessageLinkStyle, - ), - const TextSpan( - text: - ' to understand the trade-offs associated with this setting.', - ), - ], + ), + GaLinkTextSpan( + link: GaLink( + display: 'documentation', + url: _cpuSamplingRateDocsUrl, + gaScreenName: screenId, + gaSelectedItemDescription: + gac.CpuProfilerDocs.profileGranularityDocs.name, + ), + context: context, + style: Theme.of(context).warningMessageLinkStyle, + ), + const TextSpan( + text: ' to understand the trade-offs associated with this setting.', + ), + ], ); static Key generateKey(String screenId) => @@ -447,37 +444,31 @@ class HttpLoggingEnabledMessage extends BannerWarning { HttpLoggingEnabledMessage({required super.screenId}) : super( key: _generateKey(screenId), - buildTextSpans: - (context) => [ - const TextSpan( - text: ''' + buildTextSpans: (context) => [ + const TextSpan( + text: ''' HTTP traffic is being logged for debugging purposes. This may result in increased memory usage for your app. If this is not intentional, consider ''', - ), - TextSpan( - text: 'disabling http logging', - style: Theme.of(context).warningMessageLinkStyle, - recognizer: - TapGestureRecognizer() - ..onTap = () async { - await http_service.toggleHttpRequestLogging(false).then( - (_) { - if (!http_service.httpLoggingEnabled) { - notificationService.push( - 'Http logging disabled.', - ); - bannerMessages.removeMessageByKey( - _generateKey(screenId), - screenId, - ); - } - }, - ); - }, - ), - const TextSpan( - text: ' before profiling the memory of your application.', - ), - ], + ), + TextSpan( + text: 'disabling http logging', + style: Theme.of(context).warningMessageLinkStyle, + recognizer: TapGestureRecognizer() + ..onTap = () async { + await http_service.toggleHttpRequestLogging(false).then((_) { + if (!http_service.httpLoggingEnabled) { + notificationService.push('Http logging disabled.'); + bannerMessages.removeMessageByKey( + _generateKey(screenId), + screenId, + ); + } + }); + }, + ), + const TextSpan( + text: ' before profiling the memory of your application.', + ), + ], ); static Key _generateKey(String screenId) => @@ -488,20 +479,19 @@ class DebugModeMemoryMessage extends BannerWarning { DebugModeMemoryMessage({required super.screenId}) : super( key: Key('DebugModeMemoryMessage - $screenId'), - buildTextSpans: - (context) => [ - const TextSpan( - text: ''' + buildTextSpans: (context) => [ + const TextSpan( + text: ''' You are running your app in debug mode. Absolute memory usage may be higher in a debug build than in a release build. For the most accurate absolute memory stats, relaunch your application in ''', - ), - _runInProfileModeTextSpan( - context, - screenId: screenId, - style: Theme.of(context).warningMessageLinkStyle, - ), - const TextSpan(text: '.'), - ], + ), + _runInProfileModeTextSpan( + context, + screenId: screenId, + style: Theme.of(context).warningMessageLinkStyle, + ), + const TextSpan(text: '.'), + ], ); } @@ -535,24 +525,23 @@ class WelcomeToNewInspectorMessage extends BannerInfo { WelcomeToNewInspectorMessage({required super.screenId}) : super( key: Key('WelcomeToNewInspectorMessage - $screenId'), - buildTextSpans: - (context) => [ - const TextSpan( - text: ''' + buildTextSpans: (context) => [ + const TextSpan( + text: ''' 👋 Welcome to the new Flutter inspector! To get started, check out the ''', - ), - GaLinkTextSpan( - link: GaLink( - display: 'documentation', - url: 'https://docs.flutter.dev/tools/devtools/inspector#new', - gaScreenName: screenId, - gaSelectedItemDescription: gac.inspectorV2Docs, - ), - context: context, - style: Theme.of(context).linkTextStyle, - ), - const TextSpan(text: '.'), - ], + ), + GaLinkTextSpan( + link: GaLink( + display: 'documentation', + url: 'https://docs.flutter.dev/tools/devtools/inspector#new', + gaScreenName: screenId, + gaSelectedItemDescription: gac.inspectorV2Docs, + ), + context: context, + style: Theme.of(context).linkTextStyle, + ), + const TextSpan(text: '.'), + ], ); } diff --git a/packages/devtools_app/lib/src/shared/managers/notifications.dart b/packages/devtools_app/lib/src/shared/managers/notifications.dart index 9046a64ef40..8c15cebf570 100644 --- a/packages/devtools_app/lib/src/shared/managers/notifications.dart +++ b/packages/devtools_app/lib/src/shared/managers/notifications.dart @@ -73,10 +73,9 @@ class NotificationService { if (reportExplanation != null) 'Explanation:\n$reportExplanation', if (stackTrace != null) 'Stack trace:\n$stackTrace', ]; - final additionalInfo = - additionalInfoParts.isNotEmpty - ? additionalInfoParts.join('\n\n') - : null; + final additionalInfo = additionalInfoParts.isNotEmpty + ? additionalInfoParts.join('\n\n') + : null; unawaited( launchUrlWithErrorHandling( devToolsEnvironmentParameters @@ -96,10 +95,9 @@ class NotificationService { isDismissible: isDismissible, actions: [if (isReportable) reportErrorAction], // Double the duration so that the user has time to report the error: - duration: - isReportable - ? NotificationMessage.defaultDuration * 2 - : NotificationMessage.defaultDuration, + duration: isReportable + ? NotificationMessage.defaultDuration * 2 + : NotificationMessage.defaultDuration, ), allowDuplicates: allowDuplicates, ); @@ -163,10 +161,9 @@ class NotificationAction extends StatelessWidget { final theme = Theme.of(context); return DevToolsButton( label: label, - color: - isPrimary - ? theme.colorScheme.onPrimary - : theme.colorScheme.onSecondaryContainer, + color: isPrimary + ? theme.colorScheme.onPrimary + : theme.colorScheme.onSecondaryContainer, elevated: isPrimary, outlined: !isPrimary, onPressed: onPressed, diff --git a/packages/devtools_app/lib/src/shared/managers/survey.dart b/packages/devtools_app/lib/src/shared/managers/survey.dart index d7554937e03..b275fa688f4 100644 --- a/packages/devtools_app/lib/src/shared/managers/survey.dart +++ b/packages/devtools_app/lib/src/shared/managers/survey.dart @@ -77,11 +77,10 @@ class SurveyService { ), NotificationAction( label: _takeSurveyLabel, - onPressed: - () => _takeSurveyPressed( - surveyUrl: _generateSurveyUrl(survey.url!), - message: message, - ), + onPressed: () => _takeSurveyPressed( + surveyUrl: _generateSurveyUrl(survey.url!), + message: message, + ), isPrimary: true, ), ]; @@ -173,18 +172,20 @@ class DevToolsSurvey { final endDateAsString = json[_endDateKey] as String?; final minVersionAsString = json[_minDevToolsVersionKey] as String?; - final startDate = - startDateAsString != null ? DateTime.parse(startDateAsString) : null; - final endDate = - endDateAsString != null ? DateTime.parse(endDateAsString) : null; + final startDate = startDateAsString != null + ? DateTime.parse(startDateAsString) + : null; + final endDate = endDateAsString != null + ? DateTime.parse(endDateAsString) + : null; final title = json[_titleKey] as String?; final surveyUrl = json[_urlKey] as String?; - final minDevToolsVersion = - minVersionAsString != null - ? SemanticVersion.parse(minVersionAsString) - : null; - final devEnvironments = - (json[_devEnvironmentsKey] as List?)?.cast().toList(); + final minDevToolsVersion = minVersionAsString != null + ? SemanticVersion.parse(minVersionAsString) + : null; + final devEnvironments = (json[_devEnvironmentsKey] as List?) + ?.cast() + .toList(); return DevToolsSurvey._( id, startDate, @@ -236,13 +237,12 @@ class DevToolsSurvey { } extension ShowSurveyExtension on DevToolsSurvey { - bool get meetsDateRequirement => - (startDate == null || endDate == null) - ? false - : Range( - startDate!.millisecondsSinceEpoch, - endDate!.millisecondsSinceEpoch, - ).contains(_currentClockTime().millisecondsSinceEpoch); + bool get meetsDateRequirement => (startDate == null || endDate == null) + ? false + : Range( + startDate!.millisecondsSinceEpoch, + endDate!.millisecondsSinceEpoch, + ).contains(_currentClockTime().millisecondsSinceEpoch); bool get meetsMinVersionRequirement => minDevToolsVersion == null || diff --git a/packages/devtools_app/lib/src/shared/memory/class_name.dart b/packages/devtools_app/lib/src/shared/memory/class_name.dart index f4233037f66..c1e9f7db2ce 100644 --- a/packages/devtools_app/lib/src/shared/memory/class_name.dart +++ b/packages/devtools_app/lib/src/shared/memory/class_name.dart @@ -168,8 +168,9 @@ class HeapClassName with Serializable { return false; } - late final shortName = - className == 'Context' && library == '' ? 'Closure Context' : className; + late final shortName = className == 'Context' && library == '' + ? 'Closure Context' + : className; ClassType? _cachedClassType; diff --git a/packages/devtools_app/lib/src/shared/memory/classes.dart b/packages/devtools_app/lib/src/shared/memory/classes.dart index a5b9778ddc0..c35e2914ac9 100644 --- a/packages/devtools_app/lib/src/shared/memory/classes.dart +++ b/packages/devtools_app/lib/src/shared/memory/classes.dart @@ -19,11 +19,10 @@ class ObjectSetStats { from ??= _empty; subtract ??= _empty; - final result = - ObjectSetStats() - ..instanceCount = from.instanceCount - subtract.instanceCount - ..shallowSize = from.shallowSize - subtract.shallowSize - ..retainedSize = from.retainedSize - subtract.retainedSize; + final result = ObjectSetStats() + ..instanceCount = from.instanceCount - subtract.instanceCount + ..shallowSize = from.shallowSize - subtract.shallowSize + ..retainedSize = from.retainedSize - subtract.retainedSize; if (result.isZero) return null; return result; @@ -205,14 +204,13 @@ class SingleClassData extends ClassData { required List? retainers, required List? retainedSizes, }) { - final path = - retainers == null - ? null - : PathFromRoot.forObject( - graph, - shortestRetainers: retainers, - index: index, - ); + final path = retainers == null + ? null + : PathFromRoot.forObject( + graph, + shortestRetainers: retainers, + index: index, + ); final excludeFromRetained = path != null && diff --git a/packages/devtools_app/lib/src/shared/memory/retainers.dart b/packages/devtools_app/lib/src/shared/memory/retainers.dart index f9a9ba72a55..e4110fd6055 100644 --- a/packages/devtools_app/lib/src/shared/memory/retainers.dart +++ b/packages/devtools_app/lib/src/shared/memory/retainers.dart @@ -13,20 +13,19 @@ typedef References = List Function(int index); /// Shallow size of the given object. typedef ShallowSize = int Function(int index); -typedef ShortestRetainersResult = - ({ - /// Retainer for each object in the graph. - /// - /// When a value at index i is 0, it means the object at index i - /// has no retainers. - /// Null is not used for no-retainer to save memory footprint. - List retainers, +typedef ShortestRetainersResult = ({ + /// Retainer for each object in the graph. + /// + /// When a value at index i is 0, it means the object at index i + /// has no retainers. + /// Null is not used for no-retainer to save memory footprint. + List retainers, - /// Retained size for each object in the graph. - /// - /// If an object is unreachable, its retained size is 0. - List? retainedSizes, - }); + /// Retained size for each object in the graph. + /// + /// If an object is unreachable, its retained size is 0. + List? retainedSizes, +}); /// Index of the sentinel object. const _sentinelIndex = 0; diff --git a/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart b/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart index 261af777c7b..440c2cc3d1b 100644 --- a/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart +++ b/packages/devtools_app/lib/src/shared/preferences/_inspector_preferences.dart @@ -283,8 +283,9 @@ class InspectorPreferencesController extends DisposableController // Set [_checkedFlutterPubRoot] to true to avoid an infinite loop on the // next call to [removePubRootDirectories]: _checkedFlutterPubRoot = true; - final flutterPubRootDirectories = - cachedDirectories.where(_isFlutterPubRoot).toList(); + final flutterPubRootDirectories = cachedDirectories + .where(_isFlutterPubRoot) + .toList(); await removePubRootDirectories(flutterPubRootDirectories); cachedDirectories.removeWhere(_isFlutterPubRoot); } @@ -299,9 +300,8 @@ class InspectorPreferencesController extends DisposableController /// directories are for the current project so we make a best guess based on /// the root library for the main isolate. Future _inferPubRootDirectory() async { - final fileUriString = - await serviceConnection.serviceManager - .mainIsolateRootLibraryUriAsString(); + final fileUriString = await serviceConnection.serviceManager + .mainIsolateRootLibraryUriAsString(); if (fileUriString == null) { return null; } @@ -324,10 +324,9 @@ class InspectorPreferencesController extends DisposableController pubRootDirectory ??= (parts..removeLast()).join('/'); // Make sure the root directory ends with /, otherwise we will patch with // other directories that start the same. - pubRootDirectory = - pubRootDirectory.endsWith('/') - ? pubRootDirectory - : '$pubRootDirectory/'; + pubRootDirectory = pubRootDirectory.endsWith('/') + ? pubRootDirectory + : '$pubRootDirectory/'; return pubRootDirectory; } @@ -383,10 +382,9 @@ class InspectorPreferencesController extends DisposableController Future _uncachePubRootDirectories( List pubRootDirectories, ) async { - final directoriesToCache = - (await readCachedPubRootDirectories()) - .where((dir) => !pubRootDirectories.contains(dir)) - .toList(); + final directoriesToCache = (await readCachedPubRootDirectories()) + .where((dir) => !pubRootDirectories.contains(dir)) + .toList(); await storage.setValue( _customPubRootStorageId(), jsonEncode(directoriesToCache), @@ -438,8 +436,8 @@ class InspectorPreferencesController extends DisposableController final localInspectorService = _inspectorService; if (localInspectorService is! InspectorService) return; - final freshPubRootDirectories = - await localInspectorService.getPubRootDirectories(); + final freshPubRootDirectories = await localInspectorService + .getPubRootDirectories(); if (freshPubRootDirectories != null) { final newSet = Set.of(freshPubRootDirectories); final oldSet = Set.of(_pubRootDirectories.value); diff --git a/packages/devtools_app/lib/src/shared/primitives/custom_pointer_scroll_view.dart b/packages/devtools_app/lib/src/shared/primitives/custom_pointer_scroll_view.dart index 634a98ff2bf..f1199350ec8 100644 --- a/packages/devtools_app/lib/src/shared/primitives/custom_pointer_scroll_view.dart +++ b/packages/devtools_app/lib/src/shared/primitives/custom_pointer_scroll_view.dart @@ -50,8 +50,9 @@ abstract class CustomPointerScrollView extends BoxScrollView { final List slivers = buildSlivers(context); final AxisDirection axisDirection = getDirection(context); - final ScrollController? scrollController = - _primary ? PrimaryScrollController.of(context) : controller; + final ScrollController? scrollController = _primary + ? PrimaryScrollController.of(context) + : controller; assert( scrollController != null, @@ -250,8 +251,8 @@ class CustomPointerScrollable extends StatefulWidget { /// Calling this method will create a dependency on the closest [Scrollable] /// in the [context], if there is one. static CustomPointerScrollableState? of(BuildContext context) { - final _ScrollableScope? widget = - context.dependOnInheritedWidgetOfExactType<_ScrollableScope>(); + final _ScrollableScope? widget = context + .dependOnInheritedWidgetOfExactType<_ScrollableScope>(); return widget?.scrollable; } @@ -429,22 +430,23 @@ class CustomPointerScrollableState extends State switch (widget.axis) { case Axis.vertical: _gestureRecognizers = { - VerticalDragGestureRecognizer: GestureRecognizerFactoryWithHandlers< - VerticalDragGestureRecognizer - >(() => VerticalDragGestureRecognizer(), ( - VerticalDragGestureRecognizer instance, - ) { - instance - ..onDown = _handleDragDown - ..onStart = _handleDragStart - ..onUpdate = _handleDragUpdate - ..onEnd = _handleDragEnd - ..onCancel = _handleDragCancel - ..minFlingDistance = _physics?.minFlingDistance - ..minFlingVelocity = _physics?.minFlingVelocity - ..maxFlingVelocity = _physics?.maxFlingVelocity - ..dragStartBehavior = widget.dragStartBehavior; - }), + VerticalDragGestureRecognizer: + GestureRecognizerFactoryWithHandlers< + VerticalDragGestureRecognizer + >(() => VerticalDragGestureRecognizer(), ( + VerticalDragGestureRecognizer instance, + ) { + instance + ..onDown = _handleDragDown + ..onStart = _handleDragStart + ..onUpdate = _handleDragUpdate + ..onEnd = _handleDragEnd + ..onCancel = _handleDragCancel + ..minFlingDistance = _physics?.minFlingDistance + ..minFlingVelocity = _physics?.minFlingVelocity + ..maxFlingVelocity = _physics?.maxFlingVelocity + ..dragStartBehavior = widget.dragStartBehavior; + }), }; break; case Axis.horizontal: @@ -558,10 +560,9 @@ class CustomPointerScrollableState extends State // Returns the offset that should result from applying [event] to the current // position, taking min/max scroll extent into account. double _targetScrollOffsetForPointerScroll(PointerScrollEvent event) { - double delta = - widget.axis == Axis.horizontal - ? event.scrollDelta.dx - : event.scrollDelta.dy; + double delta = widget.axis == Axis.horizontal + ? event.scrollDelta.dx + : event.scrollDelta.dy; if (axisDirectionIsReversed(widget.axisDirection)) { delta *= -1; diff --git a/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart b/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart index baac2c86683..c8aafc05600 100644 --- a/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart +++ b/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart @@ -20,8 +20,9 @@ class DiagnosticsTextStyles { ); static TextStyle warning(ColorScheme colorScheme) => TextStyle( - color: - colorScheme.isLight ? Colors.orange.shade900 : Colors.orange.shade400, + color: colorScheme.isLight + ? Colors.orange.shade900 + : Colors.orange.shade400, ); static TextStyle error(ColorScheme colorScheme) => diff --git a/packages/devtools_app/lib/src/shared/primitives/encoding.dart b/packages/devtools_app/lib/src/shared/primitives/encoding.dart index 4eda5174159..a787dd9a1e1 100644 --- a/packages/devtools_app/lib/src/shared/primitives/encoding.dart +++ b/packages/devtools_app/lib/src/shared/primitives/encoding.dart @@ -37,8 +37,9 @@ class HeapSnapshotGraphEncodeDecode extends EncodeDecode { if (value is HeapSnapshotGraph) return value; if (value is String) value = jsonDecode(value); value = value as List; - final chunks = - value.map((s) => ByteDataEncodeDecode.instance.decode(s)).toList(); + final chunks = value + .map((s) => ByteDataEncodeDecode.instance.decode(s)) + .toList(); return HeapSnapshotGraph.fromChunks(chunks); } } @@ -124,8 +125,8 @@ class ClassRefEncodeDecode extends EncodeDecode { Object? toEncodable(Object? value) { return switch (value) { null => null, - final HeapSnapshotGraph value => HeapSnapshotGraphEncodeDecode.instance - .toEncodable(value), + final HeapSnapshotGraph value => + HeapSnapshotGraphEncodeDecode.instance.toEncodable(value), final ByteData value => ByteDataEncodeDecode.instance.toEncodable(value), final DateTime value => DateTimeEncodeDecode.instance.toEncodable(value), final IsolateRef value => IsolateRefEncodeDecode.instance.toEncodable( diff --git a/packages/devtools_app/lib/src/shared/primitives/extent_delegate_list.dart b/packages/devtools_app/lib/src/shared/primitives/extent_delegate_list.dart index edbb9e9d0f6..2beaaf3a100 100644 --- a/packages/devtools_app/lib/src/shared/primitives/extent_delegate_list.dart +++ b/packages/devtools_app/lib/src/shared/primitives/extent_delegate_list.dart @@ -334,12 +334,9 @@ class RenderSliverExtentDelegateBoxAdaptor extends RenderSliverMultiBoxAdaptor { final firstIndex = _extentDelegate!.minChildIndexForScrollOffset( scrollOffset, ); - final targetLastIndex = - targetEndScrollOffset.isFinite - ? _extentDelegate!.maxChildIndexForScrollOffset( - targetEndScrollOffset, - ) - : null; + final targetLastIndex = targetEndScrollOffset.isFinite + ? _extentDelegate!.maxChildIndexForScrollOffset(targetEndScrollOffset) + : null; if (firstChild != null) { final leadingGarbage = _calculateLeadingGarbage(firstIndex); @@ -464,12 +461,11 @@ class RenderSliverExtentDelegateBoxAdaptor extends RenderSliverMultiBoxAdaptor { final targetEndScrollOffsetForPaint = constraints.scrollOffset + constraints.remainingPaintExtent; - final targetLastIndexForPaint = - targetEndScrollOffsetForPaint.isFinite - ? _extentDelegate!.maxChildIndexForScrollOffset( - targetEndScrollOffsetForPaint, - ) - : null; + final targetLastIndexForPaint = targetEndScrollOffsetForPaint.isFinite + ? _extentDelegate!.maxChildIndexForScrollOffset( + targetEndScrollOffsetForPaint, + ) + : null; assert(paintExtent <= estimatedMaxScrollOffset); geometry = SliverGeometry( scrollExtent: _extentDelegate!.layoutOffset(_extentDelegate!.length), diff --git a/packages/devtools_app/lib/src/shared/primitives/flutter_widgets/linked_scroll_controller.dart b/packages/devtools_app/lib/src/shared/primitives/flutter_widgets/linked_scroll_controller.dart index f493b9559dc..ad1412178b0 100644 --- a/packages/devtools_app/lib/src/shared/primitives/flutter_widgets/linked_scroll_controller.dart +++ b/packages/devtools_app/lib/src/shared/primitives/flutter_widgets/linked_scroll_controller.dart @@ -54,10 +54,9 @@ class LinkedScrollControllerGroup { /// Creates a new controller that is linked to any existing ones. ScrollController addAndGet() { - final initialScrollOffset = - _attachedControllers.isEmpty - ? 0.0 - : _attachedControllers.first.position.pixels; + final initialScrollOffset = _attachedControllers.isEmpty + ? 0.0 + : _attachedControllers.first.position.pixels; final controller = _LinkedScrollController( this, initialScrollOffset: initialScrollOffset, diff --git a/packages/devtools_app/lib/src/shared/primitives/trees.dart b/packages/devtools_app/lib/src/shared/primitives/trees.dart index d4cf8971a81..a86d9720849 100644 --- a/packages/devtools_app/lib/src/shared/primitives/trees.dart +++ b/packages/devtools_app/lib/src/shared/primitives/trees.dart @@ -314,8 +314,9 @@ abstract class TreeNode> { final matchingNode = depthFirstTraversal( root, returnCondition: matchingNodeCondition, - exploreChildrenCondition: - includeCollapsedNodes ? null : (T node) => node.isExpanded, + exploreChildrenCondition: includeCollapsedNodes + ? null + : (T node) => node.isExpanded, action: (T _) => index++, ); if (matchingNode != null) return index; diff --git a/packages/devtools_app/lib/src/shared/primitives/utils.dart b/packages/devtools_app/lib/src/shared/primitives/utils.dart index 4429db8ac88..ff286164395 100644 --- a/packages/devtools_app/lib/src/shared/primitives/utils.dart +++ b/packages/devtools_app/lib/src/shared/primitives/utils.dart @@ -216,8 +216,9 @@ String longestFittingSubstring( int i = 0; while (i < runes.length) { final rune = runes[i]; - final charWidth = - rune < 128 ? asciiMeasurements[rune] : slowMeasureFallback(rune); + final charWidth = rune < 128 + ? asciiMeasurements[rune] + : slowMeasureFallback(rune); if (currentWidth + charWidth > maxWidth) { break; } @@ -825,14 +826,13 @@ List textSpansFromAnsi(String input, TextStyle defaultStyle) { final styled = entry.bold || entry.fgColor != null || entry.bgColor != null; return TextSpan( text: entry.text, - style: - styled - ? TextStyle( - color: ansiToColor(entry.fgColor), - backgroundColor: ansiToColor(entry.bgColor), - fontWeight: entry.bold ? FontWeight.bold : FontWeight.normal, - ) - : defaultStyle, + style: styled + ? TextStyle( + color: ansiToColor(entry.fgColor), + backgroundColor: ansiToColor(entry.bgColor), + fontWeight: entry.bold ? FontWeight.bold : FontWeight.normal, + ) + : defaultStyle, ); }).toList(); } @@ -867,17 +867,17 @@ extension LogicalKeySetExtension on LogicalKeySet { String describeKeys({bool isMacOS = false}) { // Put the modifiers first. If it has a synonym, then it's something like // shiftLeft, altRight, etc. - final sortedKeys = - keys.toList()..sort((a, b) { - final aIsModifier = a.synonyms.isNotEmpty || _modifiers.contains(a); - final bIsModifier = b.synonyms.isNotEmpty || _modifiers.contains(b); - if (aIsModifier && !bIsModifier) { - return -1; - } else if (bIsModifier && !aIsModifier) { - return 1; - } - return a.keyLabel.compareTo(b.keyLabel); - }); + final sortedKeys = keys.toList() + ..sort((a, b) { + final aIsModifier = a.synonyms.isNotEmpty || _modifiers.contains(a); + final bIsModifier = b.synonyms.isNotEmpty || _modifiers.contains(b); + if (aIsModifier && !bIsModifier) { + return -1; + } else if (bIsModifier && !aIsModifier) { + return 1; + } + return a.keyLabel.compareTo(b.keyLabel); + }); return sortedKeys.map((key) { if (_modifiers.contains(key)) { diff --git a/packages/devtools_app/lib/src/shared/server/server.dart b/packages/devtools_app/lib/src/shared/server/server.dart index 900018594d1..260f757468e 100644 --- a/packages/devtools_app/lib/src/shared/server/server.dart +++ b/packages/devtools_app/lib/src/shared/server/server.dart @@ -117,8 +117,9 @@ Future notifyForVmServiceConnection({ DevToolsJsonFile _devToolsJsonFileFromResponse(Response resp, String filePath) { final data = json.decode(resp.body) as Map; final lastModified = data['lastModifiedTime']; - final lastModifiedTime = - lastModified != null ? DateTime.parse(lastModified) : DateTime.now(); + final lastModifiedTime = lastModified != null + ? DateTime.parse(lastModified) + : DateTime.now(); return DevToolsJsonFile( name: filePath, lastModifiedTime: lastModifiedTime, diff --git a/packages/devtools_app/lib/src/shared/server/server_api_client.dart b/packages/devtools_app/lib/src/shared/server/server_api_client.dart index edc271c8480..8406975ee00 100644 --- a/packages/devtools_app/lib/src/shared/server/server_api_client.dart +++ b/packages/devtools_app/lib/src/shared/server/server_api_client.dart @@ -41,10 +41,9 @@ class DevToolsServerConnection { /// /// - http://foo/devtools => http://foo/devtools/api @visibleForTesting - static Uri apiUriFor(Uri baseUri) => - baseUri.path.endsWith('devtools') - ? baseUri.resolve('devtools/api/') - : baseUri.resolve('api/'); + static Uri apiUriFor(Uri baseUri) => baseUri.path.endsWith('devtools') + ? baseUri.resolve('devtools/api/') + : baseUri.resolve('api/'); /// Connects to the legacy SSE API. /// diff --git a/packages/devtools_app/lib/src/shared/table/_flat_table.dart b/packages/devtools_app/lib/src/shared/table/_flat_table.dart index d5fc89bc3b8..c6fa4a85207 100644 --- a/packages/devtools_app/lib/src/shared/table/_flat_table.dart +++ b/packages/devtools_app/lib/src/shared/table/_flat_table.dart @@ -36,12 +36,11 @@ class SearchableFlatTable extends FlatTable { }) : super( searchMatchesNotifier: searchController.searchMatches, activeSearchMatchNotifier: searchController.activeSearchMatch, - onDataSorted: - () => WidgetsBinding.instance.addPostFrameCallback((_) { - // This needs to be in a post frame callback so that the search - // matches are not updated in the middle of a table build. - searchController.refreshSearchMatches(); - }), + onDataSorted: () => WidgetsBinding.instance.addPostFrameCallback((_) { + // This needs to be in a post frame callback so that the search + // matches are not updated in the middle of a table build. + searchController.refreshSearchMatches(); + }), ); } @@ -308,12 +307,9 @@ class FlatTableState extends State> with AutoDisposeMixin { ); if (widget.sizeColumnsToFit || tableController.columnWidths == null) { return LayoutBuilder( - builder: - (context, constraints) => buildTable( - tableController.computeColumnWidthsSizeToFit( - constraints.maxWidth, - ), - ), + builder: (context, constraints) => buildTable( + tableController.computeColumnWidthsSizeToFit(constraints.maxWidth), + ), ); } return buildTable(tableController.columnWidths!); diff --git a/packages/devtools_app/lib/src/shared/table/_table_column.dart b/packages/devtools_app/lib/src/shared/table/_table_column.dart index ddf612baa75..4506902859a 100644 --- a/packages/devtools_app/lib/src/shared/table/_table_column.dart +++ b/packages/devtools_app/lib/src/shared/table/_table_column.dart @@ -81,30 +81,28 @@ class _ColumnHeader extends StatelessWidget { const SizedBox(width: densePadding), ], Expanded( - child: - column.titleTooltip != null - ? DevToolsTooltip( - message: column.titleTooltip, - padding: const EdgeInsets.all(denseSpacing), - child: title, - ) - : title, + child: column.titleTooltip != null + ? DevToolsTooltip( + message: column.titleTooltip, + padding: const EdgeInsets.all(denseSpacing), + child: title, + ) + : title, ), ], ); return column.includeHeader ? InkWell( - canRequestFocus: false, - onTap: - column.supportsSorting - ? () => _handleSortChange( + canRequestFocus: false, + onTap: column.supportsSorting + ? () => _handleSortChange( column, secondarySortColumn: secondarySortColumn, ) - : null, - child: headerContent, - ) + : null, + child: headerContent, + ) : headerContent; } diff --git a/packages/devtools_app/lib/src/shared/table/_table_row.dart b/packages/devtools_app/lib/src/shared/table/_table_row.dart index 02dbfe3e998..100a7ddc8a4 100644 --- a/packages/devtools_app/lib/src/shared/table/_table_row.dart +++ b/packages/devtools_app/lib/src/shared/table/_table_row.dart @@ -275,22 +275,20 @@ class _TableRowState extends State> final row = tableRowFor(context, onPressed: onPressed); final box = SizedBox( - height: - widget._rowType == _TableRowType.data - ? defaultRowHeight - : defaultHeaderHeight + - (widget.tall ? scaleByFontFactor(densePadding) : 0.0), + height: widget._rowType == _TableRowType.data + ? defaultRowHeight + : defaultHeaderHeight + + (widget.tall ? scaleByFontFactor(densePadding) : 0.0), child: Material( color: _searchAwareBackgroundColor(), - child: - onPressed != null - ? InkWell( - canRequestFocus: false, - key: contentKey, - onTap: onPressed, - child: row, - ) - : row, + child: onPressed != null + ? InkWell( + canRequestFocus: false, + key: contentKey, + onTap: onPressed, + child: row, + ) + : row, ), ); return box; @@ -338,15 +336,14 @@ class _TableRowState extends State> if (widget.isSelected) { return colorScheme.selectedRowBackgroundColor; } - final searchAwareBackgroundColor = - isSearchMatch - ? Color.alphaBlend( - isActiveSearchMatch - ? activeSearchMatchColorOpaque - : searchMatchColorOpaque, - backgroundColor, - ) - : backgroundColor; + final searchAwareBackgroundColor = isSearchMatch + ? Color.alphaBlend( + isActiveSearchMatch + ? activeSearchMatchColorOpaque + : searchMatchColorOpaque, + backgroundColor, + ) + : backgroundColor; return searchAwareBackgroundColor; } @@ -481,25 +478,27 @@ class _TableRowState extends State> } if (column == widget.expandableColumn) { - final expandIndicator = - widget.isExpandable - ? ValueListenableBuilder( - valueListenable: expandController, - builder: (context, _, _) { - return RotationTransition( - turns: expandArrowAnimation, - child: Icon( - Icons.expand_more, - color: theme.colorScheme.onSurface, - size: defaultIconSize, - ), - ); - }, - ) - : SizedBox(width: defaultIconSize, height: defaultIconSize); + final expandIndicator = widget.isExpandable + ? ValueListenableBuilder( + valueListenable: expandController, + builder: (context, _, _) { + return RotationTransition( + turns: expandArrowAnimation, + child: Icon( + Icons.expand_more, + color: theme.colorScheme.onSurface, + size: defaultIconSize, + ), + ); + }, + ) + : SizedBox(width: defaultIconSize, height: defaultIconSize); content = Row( mainAxisSize: MainAxisSize.min, - children: [expandIndicator, Expanded(child: content)], + children: [ + expandIndicator, + Expanded(child: content), + ], ); } content = Padding( diff --git a/packages/devtools_app/lib/src/shared/table/_tree_table.dart b/packages/devtools_app/lib/src/shared/table/_tree_table.dart index 2420e80b435..4bc64ef0880 100644 --- a/packages/devtools_app/lib/src/shared/table/_tree_table.dart +++ b/packages/devtools_app/lib/src/shared/table/_tree_table.dart @@ -408,10 +408,9 @@ class TreeTableState> extends State> newSelectedNodeIndex = max(selectedNodeIndex! - 1, 0); break; case TreeTableScrollKind.parent: - newSelectedNodeIndex = - selectionValue.node!.parent != null - ? max(_data.indexOf(selectionValue.node!.parent!), 0) - : 0; + newSelectedNodeIndex = selectionValue.node!.parent != null + ? max(_data.indexOf(selectionValue.node!.parent!), 0) + : 0; break; } diff --git a/packages/devtools_app/lib/src/shared/table/column_widths.dart b/packages/devtools_app/lib/src/shared/table/column_widths.dart index c7cb2cdaede..3d9d7fe839e 100644 --- a/packages/devtools_app/lib/src/shared/table/column_widths.dart +++ b/packages/devtools_app/lib/src/shared/table/column_widths.dart @@ -58,15 +58,15 @@ extension FlatColumnWidthExtension on FlatTableController { maxWidth = max(0, maxWidth); double available = maxWidth; // Columns sorted by increasing minWidth. - final sortedColumns = - columns.toList()..sort((a, b) { - if (a.minWidthPx != null && b.minWidthPx != null) { - return a.minWidthPx!.compareTo(b.minWidthPx!); - } - if (a.minWidthPx != null) return -1; - if (b.minWidthPx != null) return 1; - return 0; - }); + final sortedColumns = columns.toList() + ..sort((a, b) { + if (a.minWidthPx != null && b.minWidthPx != null) { + return a.minWidthPx!.compareTo(b.minWidthPx!); + } + if (a.minWidthPx != null) return -1; + if (b.minWidthPx != null) return 1; + return 0; + }); for (final col in columns) { if (col.fixedWidthPx != null) { @@ -112,8 +112,9 @@ extension FlatColumnWidthExtension on FlatTableController { } } } - final unconstrainedWidth = - unconstrainedCount > 0 ? available / unconstrainedCount : available; + final unconstrainedWidth = unconstrainedCount > 0 + ? available / unconstrainedCount + : available; int unconstrainedFound = 0; final widths = []; for (final column in columns) { diff --git a/packages/devtools_app/lib/src/shared/table/table.dart b/packages/devtools_app/lib/src/shared/table/table.dart index 676fe64e106..bcf54fc7204 100644 --- a/packages/devtools_app/lib/src/shared/table/table.dart +++ b/packages/devtools_app/lib/src/shared/table/table.dart @@ -136,10 +136,9 @@ class DevToolsTableState extends State> _linkedHorizontalScrollControllerGroup = LinkedScrollControllerGroup(); - final initialScrollOffset = - widget.preserveVerticalScrollPosition - ? widget.tableController.tableUiState.scrollOffset - : 0.0; + final initialScrollOffset = widget.preserveVerticalScrollPosition + ? widget.tableController.tableUiState.scrollOffset + : 0.0; widget.tableController.initScrollController(initialScrollOffset); scrollController = widget.tableController.verticalScrollController!; @@ -197,10 +196,9 @@ class DevToolsTableState extends State> final nodeIndex = selection.nodeIndex; if (selection.scrollIntoView && node != null) { - final selectedDisplayRow = - nodeIndexCalculator != null - ? nodeIndexCalculator(node)! - : nodeIndex!; + final selectedDisplayRow = nodeIndexCalculator != null + ? nodeIndexCalculator(node)! + : nodeIndex!; final newPos = selectedDisplayRow * defaultRowHeight; @@ -460,9 +458,8 @@ class DevToolsTableState extends State> controller: pinnedScrollController, itemCount: pinnedData.length, itemExtent: widget.rowItemExtent, - itemBuilder: - (context, index) => - _buildItem(context, index, isPinned: true), + itemBuilder: (context, index) => + _buildItem(context, index, isPinned: true), ), ), ), @@ -477,15 +474,13 @@ class DevToolsTableState extends State> onTapDown: (a) => widget.focusNode?.requestFocus(), child: Focus( autofocus: true, - onKeyEvent: - (_, event) => - widget.handleKeyEvent != null - ? widget.handleKeyEvent!( - event, - scrollController, - constraints, - ) - : KeyEventResult.ignored, + onKeyEvent: (_, event) => widget.handleKeyEvent != null + ? widget.handleKeyEvent!( + event, + scrollController, + constraints, + ) + : KeyEventResult.ignored, focusNode: widget.focusNode, child: ListView.builder( controller: scrollController, diff --git a/packages/devtools_app/lib/src/shared/table/table_data.dart b/packages/devtools_app/lib/src/shared/table/table_data.dart index d3b7d966f0d..6f138be7323 100644 --- a/packages/devtools_app/lib/src/shared/table/table_data.dart +++ b/packages/devtools_app/lib/src/shared/table/table_data.dart @@ -237,10 +237,9 @@ abstract class TimeAndPercentageColumn extends ColumnData { } @override - double getValue(T dataObject) => - percentageOnly - ? percentAsDoubleProvider(dataObject) - : timeProvider!(dataObject).inMicroseconds.toDouble(); + double getValue(T dataObject) => percentageOnly + ? percentAsDoubleProvider(dataObject) + : timeProvider!(dataObject).inMicroseconds.toDouble(); @override String getDisplayValue(T dataObject) { @@ -319,10 +318,9 @@ abstract class SizeAndPercentageColumn extends ColumnData { } @override - double getValue(T dataObject) => - percentageOnly - ? percentAsDoubleProvider(dataObject) - : sizeProvider!(dataObject).toDouble(); + double getValue(T dataObject) => percentageOnly + ? percentAsDoubleProvider(dataObject) + : sizeProvider!(dataObject).toDouble(); @override String getDisplayValue(T dataObject) { diff --git a/packages/devtools_app/lib/src/shared/title.dart b/packages/devtools_app/lib/src/shared/title.dart index cb49f13ee1c..f40af0065d9 100644 --- a/packages/devtools_app/lib/src/shared/title.dart +++ b/packages/devtools_app/lib/src/shared/title.dart @@ -13,8 +13,8 @@ void generateDevToolsTitle() { } _devToolsTitle.value = serviceConnection.serviceManager.connectedApp!.isFlutterAppNow! - ? 'Flutter DevTools' - : 'Dart DevTools'; + ? 'Flutter DevTools' + : 'Dart DevTools'; } ValueListenable get devToolsTitle => _devToolsTitle; diff --git a/packages/devtools_app/lib/src/shared/ui/common_widgets.dart b/packages/devtools_app/lib/src/shared/ui/common_widgets.dart index 6e62539a07d..f043571983f 100644 --- a/packages/devtools_app/lib/src/shared/ui/common_widgets.dart +++ b/packages/devtools_app/lib/src/shared/ui/common_widgets.dart @@ -44,10 +44,9 @@ TextStyle semibold(TextStyle style) => TextStyle primaryColor(TextStyle style, BuildContext context) { final theme = Theme.of(context); return style.copyWith( - color: - (theme.brightness == Brightness.light) - ? theme.primaryColor - : theme.colorScheme.secondary, + color: (theme.brightness == Brightness.light) + ? theme.primaryColor + : theme.colorScheme.secondary, fontWeight: FontWeight.w400, ); } @@ -80,13 +79,12 @@ class GaDevToolsButton extends DevToolsButton { super.outlined, super.tooltipPadding, }) : super( - onPressed: - onPressed != null - ? () { - ga.select(gaScreen, gaSelection); - onPressed(); - } - : null, + onPressed: onPressed != null + ? () { + ga.select(gaScreen, gaSelection); + onPressed(); + } + : null, ); factory GaDevToolsButton.iconOnly({ @@ -974,8 +972,9 @@ class Breadcrumb extends StatelessWidget { textDirection: TextDirection.ltr, )..layout(); - final caretWidth = - isRoot ? Breadcrumb.caretWidth : Breadcrumb.caretWidth * 2; + final caretWidth = isRoot + ? Breadcrumb.caretWidth + : Breadcrumb.caretWidth * 2; final breadcrumbWidth = textPainter.width + caretWidth + densePadding * 2; return InkWell( @@ -1032,8 +1031,9 @@ class _BreadcrumbPainter extends CustomPainter { canvas.drawPath(path, paint); - final textXOffset = - isRoot ? densePadding : Breadcrumb.caretWidth + densePadding; + final textXOffset = isRoot + ? densePadding + : Breadcrumb.caretWidth + densePadding; textPainter.paint( canvas, Offset(textXOffset, (Breadcrumb.height - textPainter.height) / 2), @@ -1427,20 +1427,19 @@ class CopyToClipboardControl extends StatelessWidget { @override Widget build(BuildContext context) { - final onPressed = - dataProvider == null - ? null - : () { - if (gaScreen != null && gaItem != null) { - ga.select(gaScreen!, gaItem!); - } - unawaited( - copyToClipboard( - dataProvider!() ?? '', - successMessage: successMessage, - ), - ); - }; + final onPressed = dataProvider == null + ? null + : () { + if (gaScreen != null && gaItem != null) { + ga.select(gaScreen!, gaItem!); + } + unawaited( + copyToClipboard( + dataProvider!() ?? '', + successMessage: successMessage, + ), + ); + }; final size = this.size ?? defaultIconSize; return SizedBox( height: size, @@ -1834,8 +1833,9 @@ class _BlinkingIconState extends State { duration: const Duration(seconds: 1), firstChild: _icon(), secondChild: _icon(color: widget.color), - crossFadeState: - showFirst ? CrossFadeState.showFirst : CrossFadeState.showSecond, + crossFadeState: showFirst + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, ); } @@ -2144,30 +2144,27 @@ class ContextMenuButton extends StatelessWidget { Widget build(BuildContext context) { return MenuAnchor( menuChildren: menuChildren, - builder: ( - BuildContext context, - MenuController controller, - Widget? child, - ) { - return SizedBox( - width: buttonWidth, - child: ToolbarAction( - icon: icon, - size: iconSize, - color: color, - onPressed: () { - if (gaScreen != null && gaItem != null) { - ga.select(gaScreen!, gaItem!); - } - if (controller.isOpen) { - controller.close(); - } else { - controller.open(); - } - }, - ), - ); - }, + builder: + (BuildContext context, MenuController controller, Widget? child) { + return SizedBox( + width: buttonWidth, + child: ToolbarAction( + icon: icon, + size: iconSize, + color: color, + onPressed: () { + if (gaScreen != null && gaItem != null) { + ga.select(gaScreen!, gaItem!); + } + if (controller.isOpen) { + controller.close(); + } else { + controller.open(); + } + }, + ), + ); + }, ); } } @@ -2208,8 +2205,8 @@ class _PositiveIntegerSettingState extends State () => _textEditingController.text = widget.notifier.value.toString(), ); - _textEditingController = - TextEditingController()..text = widget.notifier.value.toString(); + _textEditingController = TextEditingController() + ..text = widget.notifier.value.toString(); } @override @@ -2317,11 +2314,11 @@ class DevToolsOverlay extends StatelessWidget { return fullScreen ? overlayContent : Center( - child: Padding( - padding: EdgeInsets.only(top: topOffset ?? 0.0), - child: RoundedOutlinedBorder(clip: true, child: overlayContent), - ), - ); + child: Padding( + padding: EdgeInsets.only(top: topOffset ?? 0.0), + child: RoundedOutlinedBorder(clip: true, child: overlayContent), + ), + ); } double _overlayWidth(Size parentSize) { diff --git a/packages/devtools_app/lib/src/shared/ui/dialogs.dart b/packages/devtools_app/lib/src/shared/ui/dialogs.dart index bf8aff856a2..d87c7ff18d2 100644 --- a/packages/devtools_app/lib/src/shared/ui/dialogs.dart +++ b/packages/devtools_app/lib/src/shared/ui/dialogs.dart @@ -27,24 +27,22 @@ class UnexpectedErrorDialog extends StatelessWidget { actions: [ DialogTextButton( child: const Text('Copy details'), - onPressed: - () => unawaited( - copyToClipboard( - additionalInfo, - successMessage: 'Error details copied to clipboard', - ), - ), + onPressed: () => unawaited( + copyToClipboard( + additionalInfo, + successMessage: 'Error details copied to clipboard', + ), + ), ), DialogTextButton( child: const Text('Create issue'), - onPressed: - () => unawaited( - launchUrlWithErrorHandling( - devToolsEnvironmentParameters - .issueTrackerLink(additionalInfo: additionalInfo) - .url, - ), - ), + onPressed: () => unawaited( + launchUrlWithErrorHandling( + devToolsEnvironmentParameters + .issueTrackerLink(additionalInfo: additionalInfo) + .url, + ), + ), ), const DialogCloseButton(), ], diff --git a/packages/devtools_app/lib/src/shared/ui/drop_down_button.dart b/packages/devtools_app/lib/src/shared/ui/drop_down_button.dart index a6a57e41369..1fcfd0bea65 100644 --- a/packages/devtools_app/lib/src/shared/ui/drop_down_button.dart +++ b/packages/devtools_app/lib/src/shared/ui/drop_down_button.dart @@ -74,8 +74,9 @@ class AnalyticsDropDownButton extends StatelessWidget { void _onChanged(T? newValue) { if (sendAnalytics && items != null) { - final gaId = - items?.firstWhereOrNull((element) => element.item == newValue)?.gaId; + final gaId = items + ?.firstWhereOrNull((element) => element.item == newValue) + ?.gaId; if (gaId != null) { ga.select(gaScreen, '$gaDropDownId $gaId'); } diff --git a/packages/devtools_app/lib/src/shared/ui/editable_list.dart b/packages/devtools_app/lib/src/shared/ui/editable_list.dart index aff345a1704..3608d46418a 100644 --- a/packages/devtools_app/lib/src/shared/ui/editable_list.dart +++ b/packages/devtools_app/lib/src/shared/ui/editable_list.dart @@ -179,19 +179,19 @@ class EditableListActionBar extends StatelessWidget { const SizedBox(width: densePadding), isRefreshing?.value ?? false ? SizedBox( - width: defaultTextFieldHeight, - height: defaultTextFieldHeight, - child: const Padding( - padding: EdgeInsets.all(densePadding), - child: CircularProgressIndicator(), - ), - ) + width: defaultTextFieldHeight, + height: defaultTextFieldHeight, + child: const Padding( + padding: EdgeInsets.all(densePadding), + child: CircularProgressIndicator(), + ), + ) : RefreshButton( - gaScreen: gaScreen, - gaSelection: gaRefreshSelection, - onPressed: onRefresh, - minScreenWidthForTextBeforeScaling: double.maxFinite, - ), + gaScreen: gaScreen, + gaSelection: gaRefreshSelection, + onPressed: onRefresh, + minScreenWidthForTextBeforeScaling: double.maxFinite, + ), ], ), ); diff --git a/packages/devtools_app/lib/src/shared/ui/file_import.dart b/packages/devtools_app/lib/src/shared/ui/file_import.dart index 761107aee7d..361461d6926 100644 --- a/packages/devtools_app/lib/src/shared/ui/file_import.dart +++ b/packages/devtools_app/lib/src/shared/ui/file_import.dart @@ -84,27 +84,26 @@ class OpenSaveButtonGroup extends StatelessWidget { ), child: saveFormats.length == 1 && - saveFormats.first == SaveFormat.devtools - ? _SimpleOpenSaveButton( - icon: Icons.file_download, - tooltip: 'Save this screen\'s data for offline viewing', - roundedLeftBorder: false, - roundedRightBorder: true, - onPressed: - onSave != null - ? () { - ga.select(screenId, gac.saveFile); - onSave!.call(SaveFormat.devtools); - } - : null, - ) - : _DropdownSaveButton( - screenId: screenId, - onSave: onSave, - saveFormats: saveFormats, - gaItemForSaveFormatSelection: - gaItemForSaveFormatSelection, - ), + saveFormats.first == SaveFormat.devtools + ? _SimpleOpenSaveButton( + icon: Icons.file_download, + tooltip: 'Save this screen\'s data for offline viewing', + roundedLeftBorder: false, + roundedRightBorder: true, + onPressed: onSave != null + ? () { + ga.select(screenId, gac.saveFile); + onSave!.call(SaveFormat.devtools); + } + : null, + ) + : _DropdownSaveButton( + screenId: screenId, + onSave: onSave, + saveFormats: saveFormats, + gaItemForSaveFormatSelection: + gaItemForSaveFormatSelection, + ), ), ], ), @@ -204,15 +203,14 @@ class __DropdownSaveButtonState extends State<_DropdownSaveButton> { ) .toList(); }, - items: - widget.saveFormats - .map( - (f) => DropdownMenuItem( - value: f, - child: Text(f.display), - ), - ) - .toList(), + items: widget.saveFormats + .map( + (f) => DropdownMenuItem( + value: f, + child: Text(f.display), + ), + ) + .toList(), ), ); } @@ -373,10 +371,9 @@ class _FileImportContainerState extends State { gaSelection: widget.gaSelectionAction!, label: widget.actionText!, elevated: true, - onPressed: - importedFile != null - ? () => widget.onAction!(importedFile!) - : null, + onPressed: importedFile != null + ? () => widget.onAction!(importedFile!) + : null, ), ], ), @@ -600,14 +597,13 @@ class _DualFileImportContainerState extends State { label: widget.actionText, icon: Icons.highlight, elevated: true, - onPressed: - firstImportedFile != null && secondImportedFile != null - ? () => widget.onAction( - firstImportedFile!, - secondImportedFile!, - (error) => notificationService.push(error), - ) - : null, + onPressed: firstImportedFile != null && secondImportedFile != null + ? () => widget.onAction( + firstImportedFile!, + secondImportedFile!, + (error) => notificationService.push(error), + ) + : null, ), ], ), diff --git a/packages/devtools_app/lib/src/shared/ui/filter.dart b/packages/devtools_app/lib/src/shared/ui/filter.dart index 47e4190dc9e..0cb29166a41 100644 --- a/packages/devtools_app/lib/src/shared/ui/filter.dart +++ b/packages/devtools_app/lib/src/shared/ui/filter.dart @@ -51,14 +51,13 @@ mixin FilterControllerMixin on DisposableController void setActiveFilter({String? query, SettingFilters? settingFilters}) { _activeFilter.value = Filter( - queryFilter: - query != null - ? QueryFilter.parse( - query, - args: queryFilterArgs, - useRegExp: useRegExp.value, - ) - : QueryFilter.empty(args: queryFilterArgs), + queryFilter: query != null + ? QueryFilter.parse( + query, + args: queryFilterArgs, + useRegExp: useRegExp.value, + ) + : QueryFilter.empty(args: queryFilterArgs), settingFilters: settingFilters ?? this.settingFilters, ); } @@ -127,8 +126,9 @@ mixin FilterControllerMixin on DisposableController final filter = _activeFilter.value; return FilterTag( query: filter.queryFilter.query, - settingFilterValues: - settingFilters.map((filter) => filter.valueAsJson).toList(), + settingFilterValues: settingFilters + .map((filter) => filter.valueAsJson) + .toList(), useRegExp: useRegExp.value, ).tag; } @@ -492,12 +492,11 @@ class QueryFilter { for (final arg in args.values.where((arg) => arg.matchesKey(part))) { arg ..isNegative = part.startsWith(QueryFilterArgument.negativePrefix) - ..values = - useRegExp - ? valueStrings - .map((v) => RegExp(v, caseSensitive: false)) - .toList() - : valueStrings; + ..values = useRegExp + ? valueStrings + .map((v) => RegExp(v, caseSensitive: false)) + .toList() + : valueStrings; } } else { substringExpressions.add( @@ -506,9 +505,7 @@ class QueryFilter { } } - final bool validArgumentFilter = args.values.any( - (a) => a.values.isNotEmpty, - ); + final validArgumentFilter = args.values.any((a) => a.values.isNotEmpty); if (!validArgumentFilter && substringExpressions.isEmpty) { return QueryFilter.empty(args: args); } @@ -530,13 +527,12 @@ class QueryFilter { final bool isEmpty; - String get query => - isEmpty - ? '' - : [ - ...substringExpressions.toStringList(), - for (final arg in filterArguments) arg.display, - ].join(' ').trim(); + String get query => isEmpty + ? '' + : [ + ...substringExpressions.toStringList(), + for (final arg in filterArguments) arg.display, + ].join(' ').trim(); } class QueryFilterArgument { @@ -590,10 +586,9 @@ class QueryFilterArgument { var matches = false; for (final value in values) { - matches = - substringMatch - ? dataValue.caseInsensitiveContains(value) - : dataValue.caseInsensitiveEquals(value); + matches = substringMatch + ? dataValue.caseInsensitiveContains(value) + : dataValue.caseInsensitiveEquals(value); if (matches) break; } return isNegative ? !matches : matches; @@ -663,37 +658,34 @@ class _StandaloneFilterFieldState extends State> autofocus: true, hintText: 'Filter', controller: queryTextFieldController, - prefixIcon: - widget.controller.settingFilters.isNotEmpty - ? Container( - height: inputDecorationElementHeight, - padding: const EdgeInsets.only( - left: densePadding, - right: denseSpacing, - ), - child: ValueListenableBuilder( - valueListenable: widget.controller.activeFilter, - builder: (context, _, _) { - return DevToolsFilterButton( - message: 'More filters', - onPressed: () { - unawaited( - showDialog( - context: context, - builder: - (context) => FilterDialog( - controller: widget.controller, - ), + prefixIcon: widget.controller.settingFilters.isNotEmpty + ? Container( + height: inputDecorationElementHeight, + padding: const EdgeInsets.only( + left: densePadding, + right: denseSpacing, + ), + child: ValueListenableBuilder( + valueListenable: widget.controller.activeFilter, + builder: (context, _, _) { + return DevToolsFilterButton( + message: 'More filters', + onPressed: () { + unawaited( + showDialog( + context: context, + builder: (context) => FilterDialog( + controller: widget.controller, ), - ); - }, - isFilterActive: - widget.controller.isFilterActive, - ); - }, - ), - ) - : null, + ), + ); + }, + isFilterActive: widget.controller.isFilterActive, + ); + }, + ), + ) + : null, additionalSuffixActions: [ if (widget.controller.queryFilterArgs.isNotEmpty) InputDecorationSuffixButton.help( @@ -819,8 +811,8 @@ class FilterTag { try { final useRegExp = parts.last == useRegExpTag; final query = parts[0].trim(); - final settingFilterValues = - (jsonDecode(parts[1]) as List).cast>(); + final settingFilterValues = (jsonDecode(parts[1]) as List) + .cast>(); return FilterTag( query: query, settingFilterValues: settingFilterValues, diff --git a/packages/devtools_app/lib/src/shared/ui/history_viewport.dart b/packages/devtools_app/lib/src/shared/ui/history_viewport.dart index 9497632f365..aad6cf45fde 100644 --- a/packages/devtools_app/lib/src/shared/ui/history_viewport.dart +++ b/packages/devtools_app/lib/src/shared/ui/history_viewport.dart @@ -62,26 +62,24 @@ class _HistoryViewportState extends State> { @override Widget build(BuildContext context) { - final titleIcon = - widget.titleIcon != null - ? Padding( - padding: const EdgeInsets.only(right: densePadding), - child: Icon( - widget.titleIcon, - size: defaultIconSize, - color: _iconColor, - ), - ) - : const SizedBox.shrink(); + final titleIcon = widget.titleIcon != null + ? Padding( + padding: const EdgeInsets.only(right: densePadding), + child: Icon( + widget.titleIcon, + size: defaultIconSize, + color: _iconColor, + ), + ) + : const SizedBox.shrink(); return ValueListenableBuilder( valueListenable: widget.history.current, builder: (context, T? current, _) { final theme = Theme.of(context); - final title = - widget.generateTitle == null - ? ' ' - : widget.generateTitle!(current); + final title = widget.generateTitle == null + ? ' ' + : widget.generateTitle!(current); final defaultTitleStyle = theme.textTheme.titleMedium!; final titleWidget = debuggerSectionTitle( theme, @@ -90,77 +88,74 @@ class _HistoryViewportState extends State> { if (widget.historyEnabled) ...[ ToolbarAction( icon: Icons.chevron_left, - onPressed: - widget.history.hasPrevious - ? () { - widget.history.moveBack(); - if (widget.onChange != null) { - widget.onChange!( - widget.history.current.value, - widget.history.peekNext(), - ); - } + onPressed: widget.history.hasPrevious + ? () { + widget.history.moveBack(); + if (widget.onChange != null) { + widget.onChange!( + widget.history.current.value, + widget.history.peekNext(), + ); } - : null, + } + : null, ), ToolbarAction( icon: Icons.chevron_right, - onPressed: - widget.history.hasNext - ? () { - final current = widget.history.current.value as T; - widget.history.moveForward(); - if (widget.onChange != null) { - widget.onChange!( - widget.history.current.value, - current, - ); - } + onPressed: widget.history.hasNext + ? () { + final current = widget.history.current.value as T; + widget.history.moveForward(); + if (widget.onChange != null) { + widget.onChange!( + widget.history.current.value, + current, + ); } - : null, + } + : null, ), const SizedBox(width: denseSpacing), const VerticalDivider(thickness: 1.0), const SizedBox(width: defaultSpacing), ], Expanded( - child: - widget.onTitleTap == null - ? Row( - children: [ - titleIcon, - Text(title, style: defaultTitleStyle), - ], - ) - : MouseRegion( - cursor: SystemMouseCursors.click, - onExit: (_) { - _updateTitleStyle(defaultTitleStyle); - }, - onEnter: (_) { - _updateTitleStyle( - defaultTitleStyle.copyWith( - color: theme.colorScheme.primary, - ), - ); - }, - child: GestureDetector( - onTap: widget.onTitleTap, - child: Row( - children: [ - titleIcon, - Expanded( - child: Text( - title, - style: - _titleStyle ?? - theme.textTheme.titleMedium, - ), - ), - ], + child: widget.onTitleTap == null + ? Row( + children: [ + titleIcon, + Text(title, style: defaultTitleStyle), + ], + ) + : MouseRegion( + cursor: SystemMouseCursors.click, + onExit: (_) { + _updateTitleStyle(defaultTitleStyle); + }, + onEnter: (_) { + _updateTitleStyle( + defaultTitleStyle.copyWith( + color: theme.colorScheme.primary, ), + ); + }, + child: GestureDetector( + onTap: widget.onTitleTap, + child: Row( + children: [ + titleIcon, + Expanded( + child: Text( + title, + style: + _titleStyle ?? + theme.textTheme.titleMedium, + ), + ), + ], ), ), + ), ), if (widget.controls != null) ...[ const SizedBox(width: denseSpacing), diff --git a/packages/devtools_app/lib/src/shared/ui/hover.dart b/packages/devtools_app/lib/src/shared/ui/hover.dart index ea94bab9a6b..b43e30929b8 100644 --- a/packages/devtools_app/lib/src/shared/ui/hover.dart +++ b/packages/devtools_app/lib/src/shared/ui/hover.dart @@ -424,10 +424,9 @@ class _HoverCardTooltipState extends State { HoverCard? spinnerHoverCard; final hoverCardDataFuture = asyncGenerateHoverCardData( event: event, - isHoverStale: - () => - spinnerHoverCard != null && - !_hoverCardController.isHoverCardStillActive(spinnerHoverCard), + isHoverStale: () => + spinnerHoverCard != null && + !_hoverCardController.isHoverCardStillActive(spinnerHoverCard), ); final hoverCardDataCompleter = _hoverCardDataCompleter(hoverCardDataFuture); // If we have set the async hover card to show up only after a timeout, diff --git a/packages/devtools_app/lib/src/shared/ui/search.dart b/packages/devtools_app/lib/src/shared/ui/search.dart index 2107561794c..fb1064e65cf 100644 --- a/packages/devtools_app/lib/src/shared/ui/search.dart +++ b/packages/devtools_app/lib/src/shared/ui/search.dart @@ -122,15 +122,16 @@ mixin SearchControllerMixin searchInProgress = true; // Start new search operation - final future = Future(() { - return matchesForSearch( - _searchNotifier.value, - searchPreviousMatches: searchPreviousMatches, - ); - }).then((matches) { - searchInProgress = false; - _updateMatches(matches); - }); + final future = + Future(() { + return matchesForSearch( + _searchNotifier.value, + searchPreviousMatches: searchPreviousMatches, + ); + }).then((matches) { + searchInProgress = false; + _updateMatches(matches); + }); _searchOperation = CancelableOperation.fromFuture(future); await _searchOperation!.value; searchInProgress = false; @@ -194,8 +195,8 @@ mixin SearchControllerMixin matchIndex.value = 1; // first item because [matchIndex] us 1-based } _activeSearchMatch.value?.isActiveSearchMatch = false; - _activeSearchMatch.value = - searchMatches.value[activeMatchIndex]..isActiveSearchMatch = true; + _activeSearchMatch.value = searchMatches.value[activeMatchIndex] + ..isActiveSearchMatch = true; onMatchChanged(activeMatchIndex); } @@ -205,11 +206,10 @@ mixin SearchControllerMixin /// If [matchesForSearch] is overridden in such a way that /// [currentDataToSearchThrough] is not used, then this getter does not need /// to be implemented. - Iterable get currentDataToSearchThrough => - throw UnimplementedError( - 'Implement this getter in order to use the default' - ' [matchesForSearch] behavior.', - ); + Iterable get currentDataToSearchThrough => throw UnimplementedError( + 'Implement this getter in order to use the default' + ' [matchesForSearch] behavior.', + ); /// Default search matching logic. /// @@ -254,8 +254,8 @@ mixin SearchControllerMixin @mustCallSuper @override void init() { - _searchTextFieldController = - SearchTextEditingController()..text = _searchNotifier.value; + _searchTextFieldController = SearchTextEditingController() + ..text = _searchNotifier.value; _searchFieldFocusNode = FocusNode(debugLabel: 'search-field'); } @@ -350,25 +350,23 @@ class AutoCompleteState extends State with AutoDisposeMixin { context, ).regularTextStyle.copyWith(fontWeight: FontWeight.bold); - final tileContents = - searchAutoComplete.value - .map( - (match) => _maybeHighlightMatchText( - match, - autoCompleteTextStyle, - autoCompleteHighlightedTextStyle, - ), - ) - .toList(); + final tileContents = searchAutoComplete.value + .map( + (match) => _maybeHighlightMatchText( + match, + autoCompleteTextStyle, + autoCompleteHighlightedTextStyle, + ), + ) + .toList(); // When there are no tiles present, we don't need to display the // auto complete list. if (tileContents.isEmpty) return const SizedBox.shrink(); - final tileEntryHeight = - tileContents.isEmpty - ? 0.0 - : calculateTextSpanHeight(tileContents.first) + denseSpacing; + final tileEntryHeight = tileContents.isEmpty + ? 0.0 + : calculateTextSpanHeight(tileContents.first) + denseSpacing; // Find the searchField and place overlay below bottom of TextField and // make overlay width of TextField. This is also we decide the height of @@ -382,17 +380,15 @@ class AutoCompleteState extends State with AutoDisposeMixin { final maxAreaForPopup = areaHeight - tileEntryHeight; // TODO(terry): Scrolling doesn't work so max popup height is also total // matches to use. - topMatchesLimit = - min( - defaultTopMatchesLimit, - (maxAreaForPopup / tileEntryHeight) - 1, // zero based. - ).truncate(); + topMatchesLimit = min( + defaultTopMatchesLimit, + (maxAreaForPopup / tileEntryHeight) - 1, // zero based. + ).truncate(); // Total tiles visible. - final totalTiles = - bottom - ? searchAutoComplete.value.length - : (maxAreaForPopup / tileEntryHeight).truncateToDouble(); + final totalTiles = bottom + ? searchAutoComplete.value.length + : (maxAreaForPopup / tileEntryHeight).truncateToDouble(); final autoCompleteTiles = []; final count = min(searchAutoComplete.value.length, totalTiles); @@ -413,17 +409,17 @@ class AutoCompleteState extends State with AutoDisposeMixin { // Compute the Y position of the popup (auto-complete list). Its bottom // will be positioned at the top of the text field. Add 1 includes // the TextField border. - final yCoord = - bottom ? 0.0 : -((count * tileEntryHeight) + box.size.height + 1); + final yCoord = bottom + ? 0.0 + : -((count * tileEntryHeight) + box.size.height + 1); final xCoord = controller.xPosition; return Positioned( key: searchAutoCompleteKey, - width: - isMaxWidth - ? box.size.width - : AutoCompleteSearchControllerMixin.minPopupWidth, + width: isMaxWidth + ? box.size.width + : AutoCompleteSearchControllerMixin.minPopupWidth, height: count * tileEntryHeight, child: CompositedTransformFollower( link: controller.autoCompleteLayerLink, @@ -450,16 +446,15 @@ class AutoCompleteState extends State with AutoDisposeMixin { TextStyle highlightedTextStyle, ) { return match.transformAutoCompleteMatch( - transformMatchedSegment: - (segment) => TextSpan(text: segment, style: highlightedTextStyle), - transformUnmatchedSegment: - (segment) => TextSpan(text: segment, style: regularTextStyle), - combineSegments: - (segments) => TextSpan( - text: segments.first.text, - style: segments.first.style, - children: segments.sublist(1), - ), + transformMatchedSegment: (segment) => + TextSpan(text: segment, style: highlightedTextStyle), + transformUnmatchedSegment: (segment) => + TextSpan(text: segment, style: regularTextStyle), + combineSegments: (segments) => TextSpan( + text: segments.first.text, + style: segments.first.style, + children: segments.sublist(1), + ), ); } } @@ -500,8 +495,9 @@ class AutoCompleteTile extends StatelessWidget { valueListenable: controller.currentHoveredIndex, builder: (context, currentHoveredIndex, _) { return Container( - color: - currentHoveredIndex == index ? highlightColor : defaultColor, + color: currentHoveredIndex == index + ? highlightColor + : defaultColor, padding: const EdgeInsets.symmetric(horizontal: denseSpacing), alignment: Alignment.centerLeft, child: Text.rich(textSpan, maxLines: 1), @@ -571,10 +567,9 @@ mixin AutoCompleteSearchControllerMixin on SearchControllerMixin { final _currentHoveredIndex = ValueNotifier(0); - String? get currentHoveredText => - searchAutoComplete.value.isNotEmpty - ? searchAutoComplete.value[currentHoveredIndex.value].text - : null; + String? get currentHoveredText => searchAutoComplete.value.isNotEmpty + ? searchAutoComplete.value[currentHoveredIndex.value].text + : null; /// Last X position of caret in search field, used for pop-up position. double xPosition = 0.0; @@ -922,10 +917,10 @@ class _SearchFieldState extends State with AutoDisposeMixin { return widget._maxLines != 1 ? searchField : SizedBox( - width: widget.searchFieldWidth, - height: widget.searchFieldHeight, - child: searchField, - ); + width: widget.searchFieldWidth, + height: widget.searchFieldHeight, + child: searchField, + ); } } @@ -1048,24 +1043,23 @@ class StatelessSearchField labelText: label, labelStyle: theme.subtleTextStyle, prefixIcon: Icon(Icons.search, size: defaultIconSize), - prefix: - prefix != null - ? Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - prefix!, - SizedBox( - height: inputDecorationElementHeight, - width: defaultIconSize, - child: Transform.rotate( - angle: degToRad(90), - child: PaddedDivider.vertical(), - ), + prefix: prefix != null + ? Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + prefix!, + SizedBox( + height: inputDecorationElementHeight, + width: defaultIconSize, + child: Transform.rotate( + angle: degToRad(90), + child: PaddedDivider.vertical(), ), - ], - ) - : null, + ), + ], + ) + : null, suffix: suffix ?? _SearchFieldSuffix( @@ -1168,8 +1162,8 @@ class _AutoCompleteSearchFieldState extends State with AutoDisposeMixin { HighlightAutoComplete get _highlightDropdown => widget.onHighlightDropdown != null - ? widget.onHighlightDropdown as HighlightAutoComplete - : _highlightDropdownItem; + ? widget.onHighlightDropdown as HighlightAutoComplete + : _highlightDropdownItem; @override void initState() { @@ -1346,11 +1340,11 @@ class _SearchFieldSuffix extends StatelessWidget { return supportsNavigation ? SearchNavigationControls(controller, onClose: onClose) : InputDecorationSuffixButton.close( - onPressed: () { - controller.searchTextFieldController.clear(); - onClose?.call(); - }, - ); + onPressed: () { + controller.searchTextFieldController.clear(); + onClose?.call(); + }, + ); } } @@ -1383,14 +1377,13 @@ class SearchNavigationControls extends StatelessWidget { child: SizedBox( width: scaleByFontFactor(smallProgressSize), height: scaleByFontFactor(smallProgressSize), - child: - isSearchInProgress - ? SmallCircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).regularTextStyle.color, - ), - ) - : const SizedBox(), + child: isSearchInProgress + ? SmallCircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + Theme.of(context).regularTextStyle.color, + ), + ) + : const SizedBox(), ), ), _matchesStatus(numMatches), @@ -1451,11 +1444,10 @@ mixin SearchableDataMixin { /// [SearchControllerMixin.matchesForSearch] is overridden in such a way that /// [matchesSearchToken] is not used, then this method does not need to be /// implemented. - bool matchesSearchToken(RegExp regExpSearch) => - throw UnimplementedError( - 'Implement this method in order to use the default' - ' [SearchControllerMixin.matchesForSearch] behavior.', - ); + bool matchesSearchToken(RegExp regExpSearch) => throw UnimplementedError( + 'Implement this method in order to use the default' + ' [SearchControllerMixin.matchesForSearch] behavior.', + ); } // This mixin is used to get around the type system where a type `T` needs to diff --git a/packages/devtools_app/lib/src/shared/ui/side_panel.dart b/packages/devtools_app/lib/src/shared/ui/side_panel.dart index 2d5be926636..236d1c384e5 100644 --- a/packages/devtools_app/lib/src/shared/ui/side_panel.dart +++ b/packages/devtools_app/lib/src/shared/ui/side_panel.dart @@ -180,13 +180,12 @@ class SidePanel extends AnimatedWidget { markdownData.isNullOrEmpty ? Text(textIfMarkdownDataEmpty ?? '') : Expanded( - child: Markdown( - data: markdownData!, - onTapLink: - (text, url, title) => - unawaited(launchUrlWithErrorHandling(url!)), + child: Markdown( + data: markdownData!, + onTapLink: (text, url, title) => + unawaited(launchUrlWithErrorHandling(url!)), + ), ), - ), ], ), ), diff --git a/packages/devtools_app/lib/src/shared/ui/tree_view.dart b/packages/devtools_app/lib/src/shared/ui/tree_view.dart index dc0e3dcfbcd..bd893306d65 100644 --- a/packages/devtools_app/lib/src/shared/ui/tree_view.dart +++ b/packages/devtools_app/lib/src/shared/ui/tree_view.dart @@ -87,8 +87,8 @@ class _TreeViewState> extends State> final T item = dataFlatList[index]; return _TreeViewItem( item, - buildDisplay: - (onPressed) => widget.dataDisplayProvider(item, onPressed), + buildDisplay: (onPressed) => + widget.dataDisplayProvider(item, onPressed), onItemSelected: _onItemSelected, onItemExpanded: _onItemExpanded, ); @@ -177,21 +177,23 @@ class _TreeViewItemState> extends State<_TreeViewItem> Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(left: nodeIndent(widget.data)), - color: - widget.data.isSelected - ? Theme.of(context).colorScheme.selectedRowBackgroundColor - : null, + color: widget.data.isSelected + ? Theme.of(context).colorScheme.selectedRowBackgroundColor + : null, child: Row( mainAxisSize: MainAxisSize.min, children: [ widget.data.isExpandable ? InkWell( - onTap: _onExpanded, - child: RotationTransition( - turns: expandArrowAnimation, - child: Icon(Icons.keyboard_arrow_down, size: defaultIconSize), - ), - ) + onTap: _onExpanded, + child: RotationTransition( + turns: expandArrowAnimation, + child: Icon( + Icons.keyboard_arrow_down, + size: defaultIconSize, + ), + ), + ) : SizedBox(width: defaultIconSize), Expanded(child: widget.buildDisplay(_onSelected)), ], diff --git a/packages/devtools_app/lib/src/shared/ui/utils.dart b/packages/devtools_app/lib/src/shared/ui/utils.dart index 3e0e127f1ec..d46894c7f92 100644 --- a/packages/devtools_app/lib/src/shared/ui/utils.dart +++ b/packages/devtools_app/lib/src/shared/ui/utils.dart @@ -173,10 +173,9 @@ class _OffsetScrollbarState extends State { widget.offsetController.position.viewportDimension; } } - final offset = - widget.axis == Axis.vertical - ? Offset(delta, 0.0) - : Offset(0.0, delta); + final offset = widget.axis == Axis.vertical + ? Offset(delta, 0.0) + : Offset(0.0, delta); return Transform.translate( offset: offset, child: Scrollbar( diff --git a/packages/devtools_app/lib/src/shared/ui/vm_flag_widgets.dart b/packages/devtools_app/lib/src/shared/ui/vm_flag_widgets.dart index 3cf01dc4256..fa5ca6b3b85 100644 --- a/packages/devtools_app/lib/src/shared/ui/vm_flag_widgets.dart +++ b/packages/devtools_app/lib/src/shared/ui/vm_flag_widgets.dart @@ -48,8 +48,9 @@ class CpuSamplingRateDropdown extends StatelessWidget { // dropdown list. We default to [CpuSamplingFrequency.medium] if the // flag value is not one of the three defaults in DevTools // (50, 250, 1000). - final safeValue = - CpuSamplingRateExtension.fromValue(flag.valueAsString ?? '').value; + final safeValue = CpuSamplingRateExtension.fromValue( + flag.valueAsString ?? '', + ).value; // Set the vm flag value to the [safeValue] if we get to this state. if (safeValue != flag.valueAsString) { unawaited(_onSamplingFrequencyChanged(safeValue)); @@ -175,20 +176,18 @@ class _VMFlagsDialogState extends State with AutoDisposeMixin { } void _updateFromController() { - flags = - (serviceConnection.vmFlagManager.flags.value?.flags ?? []) - .map((flag) => _DialogFlag(flag)) - .toList(); + flags = (serviceConnection.vmFlagManager.flags.value?.flags ?? []) + .map((flag) => _DialogFlag(flag)) + .toList(); _refilter(); } void _refilter() { final filter = filterController.text.trim().toLowerCase(); - filteredFlags = - filter.isEmpty - ? flags - : flags.where((flag) => flag.filterText.contains(filter)).toList(); + filteredFlags = filter.isEmpty + ? flags + : flags.where((flag) => flag.filterText.contains(filter)).toList(); } @override @@ -286,8 +285,8 @@ class _DialogFlag { _DialogFlag(this.flag) : filterText = '${flag.name?.toLowerCase()}\n' - '${flag.comment?.toLowerCase()}\n' - '${flag.valueAsString?.toLowerCase()}'; + '${flag.comment?.toLowerCase()}\n' + '${flag.valueAsString?.toLowerCase()}'; final Flag flag; final String filterText; diff --git a/packages/devtools_app/lib/src/shared/utils/utils.dart b/packages/devtools_app/lib/src/shared/utils/utils.dart index f41bf23af67..4d05451b999 100644 --- a/packages/devtools_app/lib/src/shared/utils/utils.dart +++ b/packages/devtools_app/lib/src/shared/utils/utils.dart @@ -361,7 +361,7 @@ void safeUnawaited( Future future, { void Function(Object?, StackTrace)? onError, }) { - onError ??= - (e, st) => reportError('Error in unawaited Future: $e', stack: st); + onError ??= (e, st) => + reportError('Error in unawaited Future: $e', stack: st); unawaited(future.catchError(onError)); } diff --git a/packages/devtools_app/lib/src/shared/utils/vm_utils.dart b/packages/devtools_app/lib/src/shared/utils/vm_utils.dart index 72320b8246a..91da0f0baa0 100644 --- a/packages/devtools_app/lib/src/shared/utils/vm_utils.dart +++ b/packages/devtools_app/lib/src/shared/utils/vm_utils.dart @@ -37,14 +37,16 @@ Future findInstance( return null; } - final result = (await serviceConnection.serviceManager.service!.getInstances( - isolateId, - classId, - preferences.memory.refLimit.value, - )).instances?.firstWhereOrNull( - (instance) => - (instance is InstanceRef) && (instance.identityHashCode == hashCode), - ); + final result = + (await serviceConnection.serviceManager.service!.getInstances( + isolateId, + classId, + preferences.memory.refLimit.value, + )).instances?.firstWhereOrNull( + (instance) => + (instance is InstanceRef) && + (instance.identityHashCode == hashCode), + ); if (result is InstanceRef) return result; return null; diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_controller.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_controller.dart index 45ac9e49884..fb5c6aa0c6b 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_controller.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_controller.dart @@ -15,14 +15,13 @@ import '../../../shared/ui/filter.dart'; import '../../../shared/utils/utils.dart'; import 'property_editor_types.dart'; -typedef EditableWidgetData = - ({ - List properties, - String? name, - String? documentation, - String? fileUri, - EditorRange? range, - }); +typedef EditableWidgetData = ({ + List properties, + String? name, + String? documentation, + String? fileUri, + EditorRange? range, +}); typedef EditArgumentFunction = Future Function({ @@ -176,22 +175,22 @@ class PropertyEditorController extends DisposableController final range = widgetRange; return range == null ? Object.hash( - property.name, - property.type, - property.value, // Include the property value. - property.displayValue, - widgetName, - fileUri, - ) + property.name, + property.type, + property.value, // Include the property value. + property.displayValue, + widgetName, + fileUri, + ) : Object.hash( - property.name, - property.type, - property.displayValue, - fileUri, - widgetName, - range.start.line, // Include the start position of the property. - range.start.character, - ); + property.name, + property.type, + property.displayValue, + fileUri, + widgetName, + range.start.line, // Include the start position of the property. + range.start.character, + ); } Future _updateWithEditableArgs({ @@ -205,13 +204,12 @@ class PropertyEditorController extends DisposableController textDocument: textDocument, position: cursorPosition, ); - final properties = - (result?.args ?? []) - .map(argToProperty) - .nonNulls - // Filter out any deprecated properties that aren't set. - .where((property) => !property.isDeprecated || property.hasArgument) - .toList(); + final properties = (result?.args ?? []) + .map(argToProperty) + .nonNulls + // Filter out any deprecated properties that aren't set. + .where((property) => !property.isDeprecated || property.hasArgument) + .toList(); final name = result?.name; final range = result?.range; @@ -257,8 +255,10 @@ class PropertyEditorController extends DisposableController setActiveFilter(); if (editableArgsResult != null) { _editableWidgetData.value = ( - properties: - editableArgsResult.args.map(argToProperty).nonNulls.toList(), + properties: editableArgsResult.args + .map(argToProperty) + .nonNulls + .toList(), name: editableArgsResult.name, documentation: editableArgsResult.documentation, fileUri: document?.uriAsString, diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_inputs.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_inputs.dart index 59ad8b0252e..4c1b68eafd5 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_inputs.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_inputs.dart @@ -130,8 +130,8 @@ class _DropdownInputState extends State<_DropdownInput> padding: denseSpacing, ), isExpanded: true, - selectedItemBuilder: - (context) => _dropdownItems(withDefaultLabels: false), + selectedItemBuilder: (context) => + _dropdownItems(withDefaultLabels: false), items: _dropdownItems(withDefaultLabels: true), onChanged: (newValue) async { if (newValue != widget.property.valueDisplay) { @@ -283,9 +283,9 @@ class _TextInputState extends State<_TextInput> // set the empty selection at the end of the string. final newSelection = (newValue.length < previousSelection.end || - newValue.length < previousSelection.start) - ? TextSelection.collapsed(offset: newValue.length) - : previousSelection; + newValue.length < previousSelection.start) + ? TextSelection.collapsed(offset: newValue.length) + : previousSelection; // Set the new value in the controller with the new selection. _controller.value = TextEditingValue( text: newValue, @@ -315,10 +315,9 @@ mixin _PropertyInputMixin on State { ), ); final editToNull = property.isNullable && property.isNully(valueAsString); - final value = - editToNull - ? null - : property.convertFromInputString(valueAsString) as U?; + final value = editToNull + ? null + : property.convertFromInputString(valueAsString) as U?; final response = await editPropertyCallback(name: argName, value: value); _handleServerResponse(response, property: property); } diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_messages.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_messages.dart index 8039bf0b878..e3cf4530149 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_messages.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_messages.dart @@ -55,8 +55,9 @@ class HowToUseMessage extends StatelessWidget { ); TextSpan highlight(TextSpan original) => _highlight( original, - highlighterColor: - theme.isDarkTheme ? _darkHighlighterColor : _lightHighlighterColor, + highlighterColor: theme.isDarkTheme + ? _darkHighlighterColor + : _lightHighlighterColor, ); return Text.rich( @@ -110,7 +111,10 @@ class HowToUseMessage extends StatelessWidget { String text, { required TextStyle style, required Color color, - }) => TextSpan(text: text, style: style.copyWith(color: color)); + }) => TextSpan( + text: text, + style: style.copyWith(color: color), + ); TextSpan _highlight(TextSpan original, {required Color highlighterColor}) => TextSpan( diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_panel.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_panel.dart index 368e6a4160a..fafac06fba0 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_panel.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_panel.dart @@ -61,11 +61,8 @@ class _PropertyEditorPanelState extends State { alignment: Alignment.topCenter, child: FutureBuilder( future: _editor, - builder: - (context, snapshot) => switch (( - snapshot.connectionState, - snapshot.data, - )) { + builder: (context, snapshot) => + switch ((snapshot.connectionState, snapshot.data)) { (ConnectionState.done, final editor?) => _PropertyEditorConnectedPanel( editor, diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_types.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_types.dart index a5c72d5d000..21a4af54dc9 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_types.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_types.dart @@ -33,13 +33,16 @@ class EditableBool extends EditableProperty with FiniteValuesProperty { @override Object? convertFromInputString(String? valueAsString) => valueAsString == 'true' || valueAsString == 'false' - ? valueAsString == 'true' - : valueAsString; // The boolean value might be an expression. + ? valueAsString == 'true' + : valueAsString; // The boolean value might be an expression. @override Set get propertyOptions { - final shouldIncludeValueDisplay = - !['true', 'false', 'null'].contains(valueDisplay); + final shouldIncludeValueDisplay = ![ + 'true', + 'false', + 'null', + ].contains(valueDisplay); return { (text: 'true', isDefault: defaultValue == true), diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_view.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_view.dart index f4b73157ce9..810d55e16f3 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_view.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/property_editor_view.dart @@ -50,10 +50,9 @@ class PropertyEditorView extends StatelessWidget { List _propertyEditorContents(EditableWidgetData? editableWidgetData) { if (editableWidgetData == null) { - final introSentence = - controller.waitingForFirstEvent - ? const WelcomeMessage() - : const NoWidgetAtLocationMessage(); + final introSentence = controller.waitingForFirstEvent + ? const WelcomeMessage() + : const NoWidgetAtLocationMessage(); return [introSentence, const HowToUseMessage()]; } @@ -297,20 +296,19 @@ class _InfoTooltip extends StatelessWidget { ), ]; - final defaultValueSpans = - property.hasDefault - ? [ - TextSpan(text: '\n\nDefault value: ', style: boldFontStyle), - TextSpan( - text: property.defaultValue.toString(), - style: fixedFontStyle, - ), - ] - : [ - TextSpan(text: '\n\nDefault value:\n', style: boldFontStyle), - TextSpan(text: property.name, style: fixedFontStyle), - TextSpan(text: ' has no default value.', style: regularFontStyle), - ]; + final defaultValueSpans = property.hasDefault + ? [ + TextSpan(text: '\n\nDefault value: ', style: boldFontStyle), + TextSpan( + text: property.defaultValue.toString(), + style: fixedFontStyle, + ), + ] + : [ + TextSpan(text: '\n\nDefault value:\n', style: boldFontStyle), + TextSpan(text: property.name, style: fixedFontStyle), + TextSpan(text: ' has no default value.', style: regularFontStyle), + ]; final spans = [...propertyNameSpans, ...defaultValueSpans]; diff --git a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/utils/utils.dart b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/utils/utils.dart index 79707c8ece6..c8877868dee 100644 --- a/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/utils/utils.dart +++ b/packages/devtools_app/lib/src/standalone_ui/ide_shared/property_editor/utils/utils.dart @@ -104,10 +104,9 @@ class DartDocConverter { int templateIndex; if (startTemplateIndex != -1 && endTemplateIndex != -1) { - templateIndex = - (startTemplateIndex < endTemplateIndex) - ? startTemplateIndex - : endTemplateIndex; + templateIndex = (startTemplateIndex < endTemplateIndex) + ? startTemplateIndex + : endTemplateIndex; } else if (startTemplateIndex != -1) { templateIndex = startTemplateIndex; } else if (endTemplateIndex != -1) { @@ -126,8 +125,8 @@ class DartDocConverter { } final closingChars = input.substring(closingIndex).startsWith('$closingCurlyBrace$newLine') - ? '$closingCurlyBrace$newLine' - : closingCurlyBrace; + ? '$closingCurlyBrace$newLine' + : closingCurlyBrace; currentIndex = closingIndex + closingChars.length; } diff --git a/packages/devtools_app/lib/src/standalone_ui/vs_code/debug_sessions.dart b/packages/devtools_app/lib/src/standalone_ui/vs_code/debug_sessions.dart index 00c53662ead..46799af2115 100644 --- a/packages/devtools_app/lib/src/standalone_ui/vs_code/debug_sessions.dart +++ b/packages/devtools_app/lib/src/standalone_ui/vs_code/debug_sessions.dart @@ -61,33 +61,30 @@ class DebugSessions extends StatelessWidget { final isDebug = mode == 'debug'; final isFlutter = session.debuggerType?.contains('Flutter') ?? false; - final label = - session.flutterMode != null - ? '${session.name} (${session.flutterMode})' - : session.name; + final label = session.flutterMode != null + ? '${session.name} (${session.flutterMode})' + : session.name; return TableRow( children: [ Text(label, style: Theme.of(context).regularTextStyle), IconButton( - onPressed: - editor.supportsHotReload && (isDebug || !isFlutter) - ? () { - ga.select(editor.gaId, gac.hotReload); - unawaited(editor.hotReload(session.id)); - } - : null, + onPressed: editor.supportsHotReload && (isDebug || !isFlutter) + ? () { + ga.select(editor.gaId, gac.hotReload); + unawaited(editor.hotReload(session.id)); + } + : null, tooltip: 'Hot Reload', icon: Icon(hotReloadIcon, size: actionsIconSize), ), IconButton( - onPressed: - editor.supportsHotRestart && (isDebug || !isFlutter) - ? () { - ga.select(editor.gaId, gac.hotRestart); - unawaited(editor.hotRestart(session.id)); - } - : null, + onPressed: editor.supportsHotRestart && (isDebug || !isFlutter) + ? () { + ga.select(editor.gaId, gac.hotRestart); + unawaited(editor.hotRestart(session.id)); + } + : null, tooltip: 'Hot Restart', icon: Icon(hotRestartIcon, size: actionsIconSize), ), diff --git a/packages/devtools_app/lib/src/standalone_ui/vs_code/devices.dart b/packages/devtools_app/lib/src/standalone_ui/vs_code/devices.dart index 0ab30df1ea4..6c1a3ea73f4 100644 --- a/packages/devtools_app/lib/src/standalone_ui/vs_code/devices.dart +++ b/packages/devtools_app/lib/src/standalone_ui/vs_code/devices.dart @@ -22,12 +22,11 @@ class Devices extends StatelessWidget { for (final MapEntry(key: id, value: device) in devices.entries) if (device.supported) id: device, }, - unsupportedDevicePlatformTypes = - devices.values - .where((device) => !device.supported) - .map((device) => device.platformType) - .nonNulls - .toSet(); + unsupportedDevicePlatformTypes = devices.values + .where((device) => !device.supported) + .map((device) => device.platformType) + .nonNulls + .toSet(); final EditorClient editor; final Map supportedDevices; @@ -67,10 +66,9 @@ class Devices extends StatelessWidget { required bool isSelected, }) { final backgroundColor = isSelected ? theme.colorScheme.secondary : null; - final foregroundColor = - isSelected - ? theme.colorScheme.onSecondary - : theme.colorScheme.onSurface; + final foregroundColor = isSelected + ? theme.colorScheme.onSecondary + : theme.colorScheme.onSurface; return TableRow( decoration: BoxDecoration(color: backgroundColor), diff --git a/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/devtools_view.dart b/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/devtools_view.dart index e5ada2f64fa..87a8fd58469 100644 --- a/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/devtools_view.dart +++ b/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/devtools_view.dart @@ -96,13 +96,12 @@ class SidebarDevToolsScreens extends StatelessWidget { ), Table( defaultVerticalAlignment: TableCellVerticalAlignment.middle, - columnWidths: - singleColumn - ? null - : const { - 0: FlexColumnWidth(), - 1: FlexColumnWidth(), - }, + columnWidths: singleColumn + ? null + : const { + 0: FlexColumnWidth(), + 1: FlexColumnWidth(), + }, children: generateRows(singleColumn), ), ], @@ -110,8 +109,9 @@ class SidebarDevToolsScreens extends StatelessWidget { } List generateRows(bool singleColumn) { - final devtoolsScreens = - ScreenMetaData.values.where(includeInSidebar).toList(); + final devtoolsScreens = ScreenMetaData.values + .where(includeInSidebar) + .toList(); if (singleColumn) { return devtoolsScreens .map( @@ -121,13 +121,12 @@ class SidebarDevToolsScreens extends StatelessWidget { editor: editor, singleColumn: singleColumn, hasDebugSessions: debugSessions.isNotEmpty, - onPressed: - (data) => openDevToolsScreen( - screenId: data.screenId, - requiresDebugSession: data.requiresDebugSession, - prefersDebugSession: data.prefersDebugSession, - editor: editor, - ), + onPressed: (data) => openDevToolsScreen( + screenId: data.screenId, + requiresDebugSession: data.requiresDebugSession, + prefersDebugSession: data.prefersDebugSession, + editor: editor, + ), ), ) .toList(); @@ -144,13 +143,12 @@ class SidebarDevToolsScreens extends StatelessWidget { editor: editor, singleColumn: singleColumn, hasDebugSessions: debugSessions.isNotEmpty, - onPressed: - (data) => openDevToolsScreen( - screenId: data.screenId, - requiresDebugSession: data.requiresDebugSession, - prefersDebugSession: data.prefersDebugSession, - editor: editor, - ), + onPressed: (data) => openDevToolsScreen( + screenId: data.screenId, + requiresDebugSession: data.requiresDebugSession, + prefersDebugSession: data.prefersDebugSession, + editor: editor, + ), ), ); } diff --git a/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/shared.dart b/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/shared.dart index 1117ab3eebb..10ec203df28 100644 --- a/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/shared.dart +++ b/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/shared.dart @@ -11,15 +11,14 @@ import '../../../shared/analytics/analytics.dart' as ga; import '../../../shared/analytics/constants.dart' as gac; import '../../../shared/editor/editor_client.dart'; -typedef DevToolsButtonData = - ({ - String label, - IconData? icon, - String? iconAsset, - String screenId, - bool requiresDebugSession, - bool prefersDebugSession, - }); +typedef DevToolsButtonData = ({ + String label, + IconData? icon, + String? iconAsset, + String screenId, + bool requiresDebugSession, + bool prefersDebugSession, +}); TableRow createDevToolsScreenRow({ required DevToolsButtonData dataLeft, @@ -33,15 +32,14 @@ TableRow createDevToolsScreenRow({ !singleColumn || dataRight == null, 'dataRight must be null is singleColumn is true', ); - final cellRight = - dataRight != null - ? _DevToolsScreenButton( - data: dataRight, - editor: editor, - hasDebugSessions: hasDebugSessions, - onPressed: onPressed, - ) - : const SizedBox(); + final cellRight = dataRight != null + ? _DevToolsScreenButton( + data: dataRight, + editor: editor, + hasDebugSessions: hasDebugSessions, + onPressed: onPressed, + ) + : const SizedBox(); return TableRow( children: [ _DevToolsScreenButton( @@ -78,8 +76,9 @@ class _DevToolsScreenButton extends StatelessWidget { return SizedBox( width: double.infinity, child: maybeWrapWithTooltip( - tooltip: - disableButton ? 'This tool requires an active debug session' : null, + tooltip: disableButton + ? 'This tool requires an active debug session' + : null, child: TextButton.icon( style: TextButton.styleFrom( alignment: Alignment.centerLeft, @@ -93,8 +92,9 @@ class _DevToolsScreenButton extends StatelessWidget { ), label: Text( data.label, - style: - disableButton ? theme.subtleTextStyle : theme.regularTextStyle, + style: disableButton + ? theme.subtleTextStyle + : theme.regularTextStyle, ), onPressed: disableButton ? null : () => onPressed(data), ), diff --git a/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/sidebar_extensions_controller.dart b/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/sidebar_extensions_controller.dart index a2878384575..1dc6e7e63dd 100644 --- a/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/sidebar_extensions_controller.dart +++ b/packages/devtools_app/lib/src/standalone_ui/vs_code/devtools/sidebar_extensions_controller.dart @@ -163,16 +163,15 @@ class SidebarDevToolsExtensionsController extends DisposableController // watch event from the IDE or analysis server to signal when any // package_config.json file in the workspace changes. Future _detectExtensions(Uri? projectRootUri) async { - final extensionService = - projectRootUri == null - ? - // A null [projectRootUri] indicates that this is an extensions lookup - // for the entire workspace, not a debug session with a fixed root URI. - ExtensionService(ignoreServiceConnection: true) - : ExtensionService( - fixedAppRoot: projectRootUri, - ignoreServiceConnection: true, - ); + final extensionService = projectRootUri == null + ? + // A null [projectRootUri] indicates that this is an extensions lookup + // for the entire workspace, not a debug session with a fixed root URI. + ExtensionService(ignoreServiceConnection: true) + : ExtensionService( + fixedAppRoot: projectRootUri, + ignoreServiceConnection: true, + ); assert( !_extensionServiceByRootUri.containsKey(projectRootUri), 'The initialization for the ExtensionService for root uri ' @@ -210,13 +209,12 @@ class SidebarDevToolsExtensionsController extends DisposableController extensionType: 'all', ); - final deduped = - allExtensions - .where( - (ext) => - !_ignoredExtensionsByHashCode.contains(identityHashCode(ext)), - ) - .toList(); + final deduped = allExtensions + .where( + (ext) => + !_ignoredExtensionsByHashCode.contains(identityHashCode(ext)), + ) + .toList(); _uniqueExtensions.value = deduped..sort(); } diff --git a/packages/devtools_app/lib/src/standalone_ui/vs_code/flutter_panel.dart b/packages/devtools_app/lib/src/standalone_ui/vs_code/flutter_panel.dart index 1b535fac0f4..abfba5e72b3 100644 --- a/packages/devtools_app/lib/src/standalone_ui/vs_code/flutter_panel.dart +++ b/packages/devtools_app/lib/src/standalone_ui/vs_code/flutter_panel.dart @@ -51,11 +51,8 @@ class _EditorSidebarPanelState extends State { Expanded( child: FutureBuilder( future: _editor, - builder: - (context, snapshot) => switch (( - snapshot.connectionState, - snapshot.data, - )) { + builder: (context, snapshot) => + switch ((snapshot.connectionState, snapshot.data)) { (ConnectionState.done, final editor?) => _EditorConnectedPanel(editor), _ => const CenteredCircularProgressIndicator(), diff --git a/packages/devtools_app/test/extensions/extension_settings_test.dart b/packages/devtools_app/test/extensions/extension_settings_test.dart index 41c46b8a6fb..9c5ac53e4dd 100644 --- a/packages/devtools_app/test/extensions/extension_settings_test.dart +++ b/packages/devtools_app/test/extensions/extension_settings_test.dart @@ -133,46 +133,38 @@ void main() { ExtensionEnabledState.none, ); - final barSetting = - tester - .widgetList(find.byType(ExtensionSetting)) - .where( - (setting) => - setting.extension.name.caseInsensitiveEquals('bar'), - ) - .first; - final bazSetting = - tester - .widgetList(find.byType(ExtensionSetting)) - .where( - (setting) => - setting.extension.name.caseInsensitiveEquals('baz'), - ) - .first; - final fooSetting = - tester - .widgetList(find.byType(ExtensionSetting)) - .where( - (setting) => - setting.extension.name.caseInsensitiveEquals('foo'), - ) - .first; - final providerSetting = - tester - .widgetList(find.byType(ExtensionSetting)) - .where( - (setting) => - setting.extension.name.caseInsensitiveEquals('provider'), - ) - .first; - final someToolSetting = - tester - .widgetList(find.byType(ExtensionSetting)) - .where( - (setting) => - setting.extension.name.caseInsensitiveEquals('some_tool'), - ) - .first; + final barSetting = tester + .widgetList(find.byType(ExtensionSetting)) + .where( + (setting) => setting.extension.name.caseInsensitiveEquals('bar'), + ) + .first; + final bazSetting = tester + .widgetList(find.byType(ExtensionSetting)) + .where( + (setting) => setting.extension.name.caseInsensitiveEquals('baz'), + ) + .first; + final fooSetting = tester + .widgetList(find.byType(ExtensionSetting)) + .where( + (setting) => setting.extension.name.caseInsensitiveEquals('foo'), + ) + .first; + final providerSetting = tester + .widgetList(find.byType(ExtensionSetting)) + .where( + (setting) => + setting.extension.name.caseInsensitiveEquals('provider'), + ) + .first; + final someToolSetting = tester + .widgetList(find.byType(ExtensionSetting)) + .where( + (setting) => + setting.extension.name.caseInsensitiveEquals('some_tool'), + ) + .first; // Disable the 'bar' extension. await tester.tap( diff --git a/packages/devtools_app/test/framework/observer/memory_observer_test.dart b/packages/devtools_app/test/framework/observer/memory_observer_test.dart index 0679976c6e5..2572d3be6ae 100644 --- a/packages/devtools_app/test/framework/observer/memory_observer_test.dart +++ b/packages/devtools_app/test/framework/observer/memory_observer_test.dart @@ -64,8 +64,11 @@ void main() { test( 'does not add banner message when memory limit is not reached', () async { - memoryUsageBytes = - convertBytes(1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + memoryUsageBytes = convertBytes( + 1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); observer.init(); await measurementComplete.future; @@ -75,15 +78,19 @@ void main() { // used instead of `gac.devToolsMain`. expect(DevToolsRouterDelegate.currentPage, isNull); - final messages = - bannerMessages.messagesForScreen(universalScreenId).value; + final messages = bannerMessages + .messagesForScreen(universalScreenId) + .value; expect(messages, isEmpty); }, ); test('adds banner message when memory limit is reached', () async { - memoryUsageBytes = - convertBytes(3.1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + memoryUsageBytes = convertBytes( + 3.1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); observer.init(); await measurementComplete.future; @@ -93,8 +100,9 @@ void main() { // used instead of `gac.devToolsMain`. expect(DevToolsRouterDelegate.currentPage, isNull); - final messages = - bannerMessages.messagesForScreen(universalScreenId).value; + final messages = bannerMessages + .messagesForScreen(universalScreenId) + .value; expect(messages, isNotEmpty); }); @@ -124,8 +132,11 @@ void main() { screenControllers.lookup(); DevToolsRouterDelegate.currentPage = screenController1.screenId; - memoryUsageBytes = - convertBytes(3.1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + memoryUsageBytes = convertBytes( + 3.1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); var result = await MemoryObserver.reduceMemory( debugMeasureUsageInBytes: testMeasureMemoryUsage, ); @@ -135,8 +146,11 @@ void main() { expect(screenController2.releaseMemoryCallCount, 1); expect(screenController2.partialReleaseMemoryCallCount, 0); - memoryUsageBytes = - convertBytes(1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + memoryUsageBytes = convertBytes( + 1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); result = await MemoryObserver.reduceMemory( debugMeasureUsageInBytes: testMeasureMemoryUsage, ); @@ -151,8 +165,11 @@ void main() { test('skips uninitialized screen controllers', () async { DevToolsRouterDelegate.currentPage = screenController1.screenId; - memoryUsageBytes = - convertBytes(3.1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + memoryUsageBytes = convertBytes( + 3.1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); var result = await MemoryObserver.reduceMemory( debugMeasureUsageInBytes: testMeasureMemoryUsage, ); @@ -165,8 +182,11 @@ void main() { // Lookup to force initialization. screenControllers.lookup(); - memoryUsageBytes = - convertBytes(3.1, from: ByteUnit.gb, to: ByteUnit.byte).round(); + memoryUsageBytes = convertBytes( + 3.1, + from: ByteUnit.gb, + to: ByteUnit.byte, + ).round(); result = await MemoryObserver.reduceMemory( debugMeasureUsageInBytes: testMeasureMemoryUsage, ); diff --git a/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_controller_test.dart b/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_controller_test.dart index d64a744463e..1331d3ab404 100644 --- a/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_controller_test.dart +++ b/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_controller_test.dart @@ -105,10 +105,9 @@ void main() { extentMicros: 100, processId: 'test', ); - final originalData = - controller.cpuProfileStore.lookupProfile( - label: CpuProfilerController.userTagNone, - )!; + final originalData = controller.cpuProfileStore.lookupProfile( + label: CpuProfilerController.userTagNone, + )!; expect( originalData.functionProfile.stackFrames.values.length, equals(17), @@ -118,12 +117,15 @@ void main() { expect(filteredData.stackFrames.values.length, equals(12)); // The native frame filter is applied by default. - final originalNativeFrames = - originalData.functionProfile.stackFrames.values - .where((sf) => sf.isNative) - .toList(); - final filteredNativeFrames = - filteredData.stackFrames.values.where((sf) => sf.isNative).toList(); + final originalNativeFrames = originalData + .functionProfile + .stackFrames + .values + .where((sf) => sf.isNative) + .toList(); + final filteredNativeFrames = filteredData.stackFrames.values + .where((sf) => sf.isNative) + .toList(); expect(originalNativeFrames.length, equals(5)); expect(filteredNativeFrames, isEmpty); }); @@ -135,10 +137,9 @@ void main() { extentMicros: 100, processId: 'test', ); - final originalData = - controller.cpuProfileStore.lookupProfile( - label: CpuProfilerController.userTagNone, - )!; + final originalData = controller.cpuProfileStore.lookupProfile( + label: CpuProfilerController.userTagNone, + )!; expect( originalData.functionProfile.stackFrames.values.length, equals(17), @@ -190,10 +191,9 @@ void main() { extentMicros: 100, processId: 'test', ); - final originalData = - controller.cpuProfileStore.lookupProfile( - label: CpuProfilerController.userTagNone, - )!; + final originalData = controller.cpuProfileStore.lookupProfile( + label: CpuProfilerController.userTagNone, + )!; expect( originalData.functionProfile.stackFrames.values.length, equals(17), diff --git a/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_test.dart b/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_test.dart index 7ddef68faba..c3ef60e50b5 100644 --- a/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_test.dart +++ b/packages/devtools_app/test/screens/cpu_profiler/cpu_profiler_test.dart @@ -659,10 +659,9 @@ void main() { sampleCount: 100, samplePeriod: 100, stackDepth: 128, - time: - TimeRange() - ..start = const Duration() - ..end = const Duration(microseconds: 10000), + time: TimeRange() + ..start = const Duration() + ..end = const Duration(microseconds: 10000), ); await tester.pumpWidget(wrap(CpuProfileStats(metadata: metadata))); await tester.pumpAndSettle(); @@ -699,10 +698,9 @@ void main() { sampleCount: 100, samplePeriod: 0, stackDepth: 128, - time: - TimeRange() - ..start = const Duration() - ..end = const Duration(microseconds: 10000), + time: TimeRange() + ..start = const Duration() + ..end = const Duration(microseconds: 10000), ); await tester.pumpWidget(wrap(CpuProfileStats(metadata: metadata))); await tester.pumpAndSettle(); diff --git a/packages/devtools_app/test/screens/cpu_profiler/method_table/method_table_model_test.dart b/packages/devtools_app/test/screens/cpu_profiler/method_table/method_table_model_test.dart index 5913253f311..ebe54bde1fc 100644 --- a/packages/devtools_app/test/screens/cpu_profiler/method_table/method_table_model_test.dart +++ b/packages/devtools_app/test/screens/cpu_profiler/method_table/method_table_model_test.dart @@ -18,10 +18,9 @@ void main() { profileMetaData: ProfileMetaData( sampleCount: 10, samplePeriod: 250, - time: - TimeRange() - ..start = Duration.zero - ..end = const Duration(seconds: 1), + time: TimeRange() + ..start = Duration.zero + ..end = const Duration(seconds: 1), ), stackFrameIds: {'1'}, ); @@ -34,10 +33,9 @@ void main() { profileMetaData: ProfileMetaData( sampleCount: 10, samplePeriod: 250, - time: - TimeRange() - ..start = Duration.zero - ..end = const Duration(seconds: 1), + time: TimeRange() + ..start = Duration.zero + ..end = const Duration(seconds: 1), ), stackFrameIds: {'2'}, ); @@ -50,10 +48,9 @@ void main() { profileMetaData: ProfileMetaData( sampleCount: 10, samplePeriod: 250, - time: - TimeRange() - ..start = Duration.zero - ..end = const Duration(seconds: 1), + time: TimeRange() + ..start = Duration.zero + ..end = const Duration(seconds: 1), ), stackFrameIds: {'3'}, ); @@ -66,10 +63,9 @@ void main() { profileMetaData: ProfileMetaData( sampleCount: 10, samplePeriod: 250, - time: - TimeRange() - ..start = Duration.zero - ..end = const Duration(seconds: 1), + time: TimeRange() + ..start = Duration.zero + ..end = const Duration(seconds: 1), ), stackFrameIds: {'4'}, ); diff --git a/packages/devtools_app/test/screens/debugger/debugger_screen_call_stack_test.dart b/packages/devtools_app/test/screens/debugger/debugger_screen_call_stack_test.dart index cbe4abe8038..d7379bb9756 100644 --- a/packages/devtools_app/test/screens/debugger/debugger_screen_call_stack_test.dart +++ b/packages/devtools_app/test/screens/debugger/debugger_screen_call_stack_test.dart @@ -145,8 +145,8 @@ void main() { ), ]; - final stackFramesWithLocation = - stackFrames.map((frame) { + final stackFramesWithLocation = stackFrames + .map((frame) { return StackFrameAndSourcePosition( frame, position: SourcePosition( @@ -154,7 +154,8 @@ void main() { column: 10, ), ); - }).toList(); + }) + .toList(); when( debuggerController.stackFramesWithLocation, diff --git a/packages/devtools_app/test/screens/debugger/eval_field_test.dart b/packages/devtools_app/test/screens/debugger/eval_field_test.dart index f2c5280333a..959cb92a901 100644 --- a/packages/devtools_app/test/screens/debugger/eval_field_test.dart +++ b/packages/devtools_app/test/screens/debugger/eval_field_test.dart @@ -155,9 +155,8 @@ void main() { final objects = await _setupEvalFieldObjects(tester); await tester.enterText(objects.textField, 'someValue.'); - objects - .searchTextEditingController - .selection = const TextSelection.collapsed(offset: 0); + objects.searchTextEditingController.selection = + const TextSelection.collapsed(offset: 0); await tester.pumpAndSettle(); expect(objects.searchTextEditingController.text, 'someValue.'); diff --git a/packages/devtools_app/test/screens/debugger/file_search_test.dart b/packages/devtools_app/test/screens/debugger/file_search_test.dart index 68839a4feef..7693fde1d81 100644 --- a/packages/devtools_app/test/screens/debugger/file_search_test.dart +++ b/packages/devtools_app/test/screens/debugger/file_search_test.dart @@ -388,10 +388,10 @@ List getAutoCompleteMatch( return matches .map( (match) => match.transformAutoCompleteMatch( - transformMatchedSegment: - (segment) => preserveCases ? segment : segment.toUpperCase(), - transformUnmatchedSegment: - (segment) => preserveCases ? segment : segment.toLowerCase(), + transformMatchedSegment: (segment) => + preserveCases ? segment : segment.toUpperCase(), + transformUnmatchedSegment: (segment) => + preserveCases ? segment : segment.toLowerCase(), combineSegments: (segments) => segments.join(), ), ) diff --git a/packages/devtools_app/test/screens/debugger/span_parser_test.dart b/packages/devtools_app/test/screens/debugger/span_parser_test.dart index b2201a663bd..42f64641373 100644 --- a/packages/devtools_app/test/screens/debugger/span_parser_test.dart +++ b/packages/devtools_app/test/screens/debugger/span_parser_test.dart @@ -32,14 +32,12 @@ void main() { final grammarFile = File(path.join('assets', 'dart_syntax.json')).absolute; late Grammar grammar; - final testDataDirectory = - Directory( - path.join('test', 'test_infra', 'test_data', 'syntax_highlighting'), - ).absolute; - final goldenDirectory = - Directory( - path.join('test', 'test_infra', 'goldens', 'syntax_highlighting'), - ).absolute; + final testDataDirectory = Directory( + path.join('test', 'test_infra', 'test_data', 'syntax_highlighting'), + ).absolute; + final goldenDirectory = Directory( + path.join('test', 'test_infra', 'goldens', 'syntax_highlighting'), + ).absolute; setUpAll(() async { expect(grammarFile.existsSync(), true); diff --git a/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart b/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart index e9d339d6b19..b124c1ab9c3 100644 --- a/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart +++ b/packages/devtools_app/test/screens/deep_link_validation/deep_links_screen_test.dart @@ -107,8 +107,9 @@ void main() { expect(find.byType(ProjectRootTextField), findsOneWidget); // Verify the project roots dropdown contains paths in the correct format. - final firstDropdownItemFinder = - find.byType(DropdownMenuItem).first; + final firstDropdownItemFinder = find + .byType(DropdownMenuItem) + .first; expect(firstDropdownItemFinder, findsWidgets); final firstDropdownItem = tester.widget>( firstDropdownItemFinder, diff --git a/packages/devtools_app/test/screens/inspector/diagnostics_test.dart b/packages/devtools_app/test/screens/inspector/diagnostics_test.dart index 9400f2ead69..1e1bb3e2457 100644 --- a/packages/devtools_app/test/screens/inspector/diagnostics_test.dart +++ b/packages/devtools_app/test/screens/inspector/diagnostics_test.dart @@ -201,15 +201,14 @@ void main() { final diagnosticsNodeFind = find.byType(DiagnosticsNodeDescription); // The icon is part of the clickable width, so we include it. - final measuredIconWidth = - tester - .getSize( - find.descendant( - of: diagnosticsNodeFind, - matching: find.byType(AssetImageIcon), - ), - ) - .width; + final measuredIconWidth = tester + .getSize( + find.descendant( + of: diagnosticsNodeFind, + matching: find.byType(AssetImageIcon), + ), + ) + .width; // There is only one rich text widget, containing the description. final richTextWidget = diff --git a/packages/devtools_app/test/screens/inspector/inspector_tree_test.dart b/packages/devtools_app/test/screens/inspector/inspector_tree_test.dart index 9d099ec2ae0..159e87c6241 100644 --- a/packages/devtools_app/test/screens/inspector/inspector_tree_test.dart +++ b/packages/devtools_app/test/screens/inspector/inspector_tree_test.dart @@ -53,8 +53,9 @@ void main() { bool isSummaryTree = false, }) async { final debuggerController = DebuggerController(); - final summaryTreeController = - isSummaryTree ? null : InspectorTreeController(); + final summaryTreeController = isSummaryTree + ? null + : InspectorTreeController(); await tester.pumpWidget( wrapWithControllers( debugger: debuggerController, @@ -73,12 +74,11 @@ void main() { testWidgets('Row with negative index regression test', ( WidgetTester tester, ) async { - final treeController = - InspectorTreeController() - ..config = InspectorTreeConfig( - onNodeAdded: (_, _) {}, - onClientActiveChange: (_) {}, - ); + final treeController = InspectorTreeController() + ..config = InspectorTreeConfig( + onNodeAdded: (_, _) {}, + onClientActiveChange: (_) {}, + ); await pumpInspectorTree(tester, treeController: treeController); expect(treeController.getRow(const Offset(0, -100.0)), isNull); @@ -87,8 +87,8 @@ void main() { expect(treeController.getRow(const Offset(0, 0.0)), isNull); expect(treeController.getRowOffset(0), equals(0)); - treeController.root = - InspectorTreeNode()..appendChild(InspectorTreeNode()); + treeController.root = InspectorTreeNode() + ..appendChild(InspectorTreeNode()); await pumpInspectorTree(tester, treeController: treeController); @@ -119,7 +119,12 @@ void main() { testWidgets('Shows preview from Text.rich', (WidgetTester tester) async { final diagnosticNode = await widgetToInspectorTreeDiagnosticsNode( widget: const Text.rich( - TextSpan(children: [TextSpan(text: 'Rich '), TextSpan(text: 'text')]), + TextSpan( + children: [ + TextSpan(text: 'Rich '), + TextSpan(text: 'text'), + ], + ), ), tester: tester, ); diff --git a/packages/devtools_app/test/screens/inspector/layout_explorer/inspector_data_models_test.dart b/packages/devtools_app/test/screens/inspector/layout_explorer/inspector_data_models_test.dart index 213eb84054f..a8e0cd0d86a 100644 --- a/packages/devtools_app/test/screens/inspector/layout_explorer/inspector_data_models_test.dart +++ b/packages/devtools_app/test/screens/inspector/layout_explorer/inspector_data_models_test.dart @@ -224,12 +224,12 @@ void main() { required MainAxisAlignment mainAxisAlignment, }) => Row( textDirection: flipMainAxis ? TextDirection.rtl : TextDirection.ltr, - mainAxisAlignment: - flipMainAxis ? mainAxisAlignment.reversed : mainAxisAlignment, - children: - flipMainAxis - ? childrenWidgets.reversed.toList() - : childrenWidgets, + mainAxisAlignment: flipMainAxis + ? mainAxisAlignment.reversed + : mainAxisAlignment, + children: flipMainAxis + ? childrenWidgets.reversed.toList() + : childrenWidgets, ); for (final mainAxisAlignment in MainAxisAlignment.values) { final originalWidgetRenderProperties = childrenRenderProperties( diff --git a/packages/devtools_app/test/screens/inspector/utils/inspector_tree.dart b/packages/devtools_app/test/screens/inspector/utils/inspector_tree.dart index b9492d42c56..88963611a34 100644 --- a/packages/devtools_app/test/screens/inspector/utils/inspector_tree.dart +++ b/packages/devtools_app/test/screens/inspector/utils/inspector_tree.dart @@ -12,15 +12,14 @@ import 'package:flutter_test/flutter_test.dart'; InspectorTreeController inspectorTreeControllerFromNode( RemoteDiagnosticsNode node, ) { - final controller = - InspectorTreeController() - ..config = InspectorTreeConfig( - onNodeAdded: (_, _) {}, - onClientActiveChange: (_) {}, - ); - - controller.root = - InspectorTreeNode()..appendChild(InspectorTreeNode()..diagnostic = node); + final controller = InspectorTreeController() + ..config = InspectorTreeConfig( + onNodeAdded: (_, _) {}, + onClientActiveChange: (_) {}, + ); + + controller.root = InspectorTreeNode() + ..appendChild(InspectorTreeNode()..diagnostic = node); return controller; } diff --git a/packages/devtools_app/test/screens/inspector_v2/diagnostics_test.dart b/packages/devtools_app/test/screens/inspector_v2/diagnostics_test.dart index 7da2b9a18bb..97f24b660f7 100644 --- a/packages/devtools_app/test/screens/inspector_v2/diagnostics_test.dart +++ b/packages/devtools_app/test/screens/inspector_v2/diagnostics_test.dart @@ -203,15 +203,14 @@ void main() { final diagnosticsNodeFind = find.byType(DiagnosticsNodeDescription); // The icon is part of the clickable width, so we include it. - final measuredIconWidth = - tester - .getSize( - find.descendant( - of: diagnosticsNodeFind, - matching: find.byType(AssetImageIcon), - ), - ) - .width; + final measuredIconWidth = tester + .getSize( + find.descendant( + of: diagnosticsNodeFind, + matching: find.byType(AssetImageIcon), + ), + ) + .width; // There is only one rich text widget, containing the description. final richTextWidget = diff --git a/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart b/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart index 879ba23ee19..8d69f8614a9 100644 --- a/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart +++ b/packages/devtools_app/test/screens/inspector_v2/inspector_integration_test.dart @@ -301,8 +301,9 @@ void main() { final diagnostics = state.controller.inspectorTree.rowsInTree.value.map( (row) => row!.node.diagnostic, ); - final textDiagnostic = - diagnostics.firstWhere((d) => d?.description == 'Text')!; + final textDiagnostic = diagnostics.firstWhere( + (d) => d?.description == 'Text', + )!; expect(textDiagnostic.isCreatedByLocalProject, isTrue); // Toggle implementation widgets off. diff --git a/packages/devtools_app/test/screens/inspector_v2/inspector_screen_test.dart b/packages/devtools_app/test/screens/inspector_v2/inspector_screen_test.dart index fb6b7743cdb..303e1cfe8f6 100644 --- a/packages/devtools_app/test/screens/inspector_v2/inspector_screen_test.dart +++ b/packages/devtools_app/test/screens/inspector_v2/inspector_screen_test.dart @@ -316,10 +316,9 @@ void main() { 'should render StoryOfYourFlexWidget', windowSize, (WidgetTester tester) async { - final controller = - TestInspectorV2Controller() - ..setSelectedNode(treeNode) - ..setSelectedDiagnostic(diagnostic); + final controller = TestInspectorV2Controller() + ..setSelectedNode(treeNode) + ..setSelectedDiagnostic(diagnostic); await tester.pumpWidget( MaterialApp( home: Scaffold(body: WidgetDetails(controller: controller)), diff --git a/packages/devtools_app/test/screens/inspector_v2/inspector_tree_test.dart b/packages/devtools_app/test/screens/inspector_v2/inspector_tree_test.dart index 0b01565c5e6..f134241186b 100644 --- a/packages/devtools_app/test/screens/inspector_v2/inspector_tree_test.dart +++ b/packages/devtools_app/test/screens/inspector_v2/inspector_tree_test.dart @@ -74,12 +74,11 @@ void main() { testWidgets('Row with negative index regression test', ( WidgetTester tester, ) async { - final treeController = - InspectorTreeController() - ..config = InspectorTreeConfig( - onNodeAdded: (_, _) {}, - onClientActiveChange: (_) {}, - ); + final treeController = InspectorTreeController() + ..config = InspectorTreeConfig( + onNodeAdded: (_, _) {}, + onClientActiveChange: (_) {}, + ); await pumpInspectorTree(tester, treeController: treeController); expect(treeController.rowForOffset(const Offset(0, -100.0)), isNull); @@ -88,8 +87,8 @@ void main() { expect(treeController.rowForOffset(const Offset(0, 0.0)), isNull); expect(treeController.rowOffset(0), equals(0)); - treeController.root = - InspectorTreeNode()..appendChild(InspectorTreeNode()); + treeController.root = InspectorTreeNode() + ..appendChild(InspectorTreeNode()); await pumpInspectorTree(tester, treeController: treeController); @@ -120,7 +119,12 @@ void main() { testWidgets('Shows preview from Text.rich', (WidgetTester tester) async { final diagnosticNode = await widgetToInspectorTreeDiagnosticsNode( widget: const Text.rich( - TextSpan(children: [TextSpan(text: 'Rich '), TextSpan(text: 'text')]), + TextSpan( + children: [ + TextSpan(text: 'Rich '), + TextSpan(text: 'text'), + ], + ), ), tester: tester, ); diff --git a/packages/devtools_app/test/screens/inspector_v2/layout_explorer/inspector_data_models_test.dart b/packages/devtools_app/test/screens/inspector_v2/layout_explorer/inspector_data_models_test.dart index f08c1a1ea36..6c8302d73df 100644 --- a/packages/devtools_app/test/screens/inspector_v2/layout_explorer/inspector_data_models_test.dart +++ b/packages/devtools_app/test/screens/inspector_v2/layout_explorer/inspector_data_models_test.dart @@ -224,12 +224,12 @@ void main() { required MainAxisAlignment mainAxisAlignment, }) => Row( textDirection: flipMainAxis ? TextDirection.rtl : TextDirection.ltr, - mainAxisAlignment: - flipMainAxis ? mainAxisAlignment.reversed : mainAxisAlignment, - children: - flipMainAxis - ? childrenWidgets.reversed.toList() - : childrenWidgets, + mainAxisAlignment: flipMainAxis + ? mainAxisAlignment.reversed + : mainAxisAlignment, + children: flipMainAxis + ? childrenWidgets.reversed.toList() + : childrenWidgets, ); for (final mainAxisAlignment in MainAxisAlignment.values) { final originalWidgetRenderProperties = childrenRenderProperties( diff --git a/packages/devtools_app/test/screens/inspector_v2/utils/inspector_tree.dart b/packages/devtools_app/test/screens/inspector_v2/utils/inspector_tree.dart index 0a30a4b982c..d2aac2767d3 100644 --- a/packages/devtools_app/test/screens/inspector_v2/utils/inspector_tree.dart +++ b/packages/devtools_app/test/screens/inspector_v2/utils/inspector_tree.dart @@ -15,15 +15,14 @@ import 'package:flutter_test/flutter_test.dart'; InspectorTreeController inspectorTreeControllerFromNode( RemoteDiagnosticsNode node, ) { - final controller = - InspectorTreeController() - ..config = InspectorTreeConfig( - onNodeAdded: (_, _) {}, - onClientActiveChange: (_) {}, - ); - - controller.root = - InspectorTreeNode()..appendChild(InspectorTreeNode()..diagnostic = node); + final controller = InspectorTreeController() + ..config = InspectorTreeConfig( + onNodeAdded: (_, _) {}, + onClientActiveChange: (_) {}, + ); + + controller.root = InspectorTreeNode() + ..appendChild(InspectorTreeNode()..diagnostic = node); return controller; } diff --git a/packages/devtools_app/test/screens/logging/logging_screen_data_test.dart b/packages/devtools_app/test/screens/logging/logging_screen_data_test.dart index 0b675e5d8ab..968ef191e1c 100644 --- a/packages/devtools_app/test/screens/logging/logging_screen_data_test.dart +++ b/packages/devtools_app/test/screens/logging/logging_screen_data_test.dart @@ -295,13 +295,10 @@ LogData _generate(int i) { break; } - final detailsComputer = - computedDetails == null - ? null - : () => Future.delayed( - const Duration(seconds: 1), - () => computedDetails!, - ); + final detailsComputer = computedDetails == null + ? null + : () => + Future.delayed(const Duration(seconds: 1), () => computedDetails!); return LogData(kind, details, i, detailsComputer: detailsComputer); } diff --git a/packages/devtools_app/test/screens/logging/metadata_test.dart b/packages/devtools_app/test/screens/logging/metadata_test.dart index 55b9f82d374..7844d0a40d4 100644 --- a/packages/devtools_app/test/screens/logging/metadata_test.dart +++ b/packages/devtools_app/test/screens/logging/metadata_test.dart @@ -92,15 +92,14 @@ void main() { wrapSimple( Column( key: testKey, - children: - testLogs.map((log) { - return Flexible( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: MetadataChips(data: log), - ), - ); - }).toList(), + children: testLogs.map((log) { + return Flexible( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: MetadataChips(data: log), + ), + ); + }).toList(), ), ), ); diff --git a/packages/devtools_app/test/screens/memory/diff/controller/diff_pane_controller_test.dart b/packages/devtools_app/test/screens/memory/diff/controller/diff_pane_controller_test.dart index c571a4dc499..8531dde587a 100644 --- a/packages/devtools_app/test/screens/memory/diff/controller/diff_pane_controller_test.dart +++ b/packages/devtools_app/test/screens/memory/diff/controller/diff_pane_controller_test.dart @@ -46,8 +46,8 @@ void main() { final controller = scene.controller.diff; - final snapshots = - controller.core.snapshots.value.whereType(); + final snapshots = controller.core.snapshots.value + .whereType(); expect(snapshots.length, 2); snapshots.first.diffWith.value = snapshots.last; @@ -59,8 +59,8 @@ void main() { ); final fromJson = DiffPaneController.fromJson(json); - final snapshotsFromJson = - fromJson.core.snapshots.value.whereType(); + final snapshotsFromJson = fromJson.core.snapshots.value + .whereType(); expect(snapshotsFromJson.length, 2); expect( diff --git a/packages/devtools_app/test/screens/memory/diff/controller/heap_diff_test.dart b/packages/devtools_app/test/screens/memory/diff/controller/heap_diff_test.dart index 1ee2cbdc5cd..e8e0bec4090 100644 --- a/packages/devtools_app/test/screens/memory/diff/controller/heap_diff_test.dart +++ b/packages/devtools_app/test/screens/memory/diff/controller/heap_diff_test.dart @@ -56,13 +56,12 @@ void main() { created2, ], graphAfter); - final diff = - DiffClassData.compare( - before: classBefore, - dataBefore: await testHeapData(graphBefore), - after: classAfter, - dataAfter: await testHeapData(graphAfter), - )!; + final diff = DiffClassData.compare( + before: classBefore, + dataBefore: await testHeapData(graphBefore), + after: classAfter, + dataAfter: await testHeapData(graphAfter), + )!; expect(diff.className, className); expect(diff.diff.created.instanceCount, 2); @@ -82,13 +81,12 @@ void main() { final classBefore = testClassData(className, [deleted], graphBefore); - final diff = - DiffClassData.compare( - before: classBefore, - dataBefore: await testHeapData(graphBefore), - after: null, - dataAfter: await testHeapData(), - )!; + final diff = DiffClassData.compare( + before: classBefore, + dataBefore: await testHeapData(graphBefore), + after: null, + dataAfter: await testHeapData(), + )!; expect(diff.className, className); expect(diff.diff.created.instanceCount, 0); diff --git a/packages/devtools_app/test/screens/memory/diff/widgets/class_filter_test.dart b/packages/devtools_app/test/screens/memory/diff/widgets/class_filter_test.dart index 2cd45424b06..72d18a519d3 100644 --- a/packages/devtools_app/test/screens/memory/diff/widgets/class_filter_test.dart +++ b/packages/devtools_app/test/screens/memory/diff/widgets/class_filter_test.dart @@ -59,10 +59,9 @@ void main() { hasLength(2), ); - final diffWith = - test.isDiff - ? scene.diffController.core.snapshots.value[1] as SnapshotDataItem - : null; + final diffWith = test.isDiff + ? scene.diffController.core.snapshots.value[1] as SnapshotDataItem + : null; scene.diffController.setDiffing( scene.diffController.derived.selectedItem.value as SnapshotDataItem, diff --git a/packages/devtools_app/test/screens/memory/framework/memory_controller_test.dart b/packages/devtools_app/test/screens/memory/framework/memory_controller_test.dart index 081b0b010ff..3ae0e033662 100644 --- a/packages/devtools_app/test/screens/memory/framework/memory_controller_test.dart +++ b/packages/devtools_app/test/screens/memory/framework/memory_controller_test.dart @@ -63,10 +63,9 @@ void main() { late final CpuSamples allocationTracingProfile; setUpAll(() { - final rawProfile = - File( - 'test/test_infra/test_data/memory/allocation_tracing/allocation_trace.json', - ).readAsStringSync(); + final rawProfile = File( + 'test/test_infra/test_data/memory/allocation_tracing/allocation_trace.json', + ).readAsStringSync(); allocationTracingProfile = CpuSamples.parse(jsonDecode(rawProfile))!; }); diff --git a/packages/devtools_app/test/screens/memory/shared/heap/heap_analyzer_test.dart b/packages/devtools_app/test/screens/memory/shared/heap/heap_analyzer_test.dart index d37cefb2eb9..45e96c3aa81 100644 --- a/packages/devtools_app/test/screens/memory/shared/heap/heap_analyzer_test.dart +++ b/packages/devtools_app/test/screens/memory/shared/heap/heap_analyzer_test.dart @@ -39,23 +39,23 @@ final _sizeTests = [ ), _SizeTest( name: 'Two objects heap', - heap: - FakeHeapSnapshotGraph()..setObjects({ - 1: [2], - 2: [], - }), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2], + 2: [], + }), rootRetainedSize: 2, unreachableSize: 0, ), _SizeTest( name: 'Four objects heap', - heap: - FakeHeapSnapshotGraph()..setObjects({ - 1: [2, 3, 4], - 2: [], - 3: [], - 4: [], - }), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2, 3, 4], + 2: [], + 3: [], + 4: [], + }), rootRetainedSize: 4, unreachableSize: 0, ), @@ -69,20 +69,20 @@ final _sizeTests = [ ), _SizeTest( name: 'Many unreachable objects heap', - heap: - FakeHeapSnapshotGraph()..setObjects({ - // Reachable: - 1: [2, 3, 4], - 2: [], - 3: [], - 4: [], + heap: FakeHeapSnapshotGraph() + ..setObjects({ + // Reachable: + 1: [2, 3, 4], + 2: [], + 3: [], + 4: [], - // Unreachable: - 5: [6, 7, 8], - 6: [], - 7: [], - 8: [], - }), + // Unreachable: + 5: [6, 7, 8], + 6: [], + 7: [], + 8: [], + }), rootRetainedSize: 4, unreachableSize: 4, ), @@ -95,15 +95,14 @@ final _sizeTests = [ // 2w 3 // | // 4 - heap: - FakeHeapSnapshotGraph() - ..setObjects({ - 1: [2, 3], - }) - ..addObjects({ - 2: [4], - }, weak: true) - ..addObjects({3: [], 4: []}), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2, 3], + }) + ..addObjects({ + 2: [4], + }, weak: true) + ..addObjects({3: [], 4: []}), rootRetainedSize: 3, unreachableSize: 1, ), @@ -114,16 +113,15 @@ final _sizeTests = [ // 2w 3w // | \ // 4 5 - heap: - FakeHeapSnapshotGraph() - ..setObjects({ - 1: [2, 3], - }) - ..addObjects({ - 2: [4], - 3: [5], - }, weak: true) - ..addObjects({4: [], 5: []}), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2, 3], + }) + ..addObjects({ + 2: [4], + 3: [5], + }, weak: true) + ..addObjects({4: [], 5: []}), rootRetainedSize: 3, unreachableSize: 2, ), @@ -133,13 +131,13 @@ final _sizeTests = [ name: 'Diamond', // |\ // \| - heap: - FakeHeapSnapshotGraph()..setObjects({ - 1: [2, 3], - 2: [4], - 3: [4], - 4: [], - }), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2, 3], + 2: [4], + 3: [4], + 4: [], + }), rootRetainedSize: 4, unreachableSize: 0, ), @@ -148,14 +146,14 @@ final _sizeTests = [ // \ // |\ // \| - heap: - FakeHeapSnapshotGraph()..setObjects({ - 1: [2], - 2: [3, 4], - 3: [5], - 4: [5], - 5: [], - }), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2], + 2: [3, 4], + 3: [5], + 4: [5], + 5: [], + }), rootRetainedSize: 5, unreachableSize: 0, ), @@ -164,19 +162,18 @@ final _sizeTests = [ // \ // |\ // \| - heap: - FakeHeapSnapshotGraph() - ..setObjects({ - 1: [2], - 2: [3, 4], - }) - ..addObjects({ - 3: [5], - }, weak: true) - ..addObjects({ - 4: [5], - 5: [], - }), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2], + 2: [3, 4], + }) + ..addObjects({ + 3: [5], + }, weak: true) + ..addObjects({ + 4: [5], + 5: [], + }), rootRetainedSize: 5, unreachableSize: 0, ), @@ -185,17 +182,16 @@ final _sizeTests = [ // \ // |\ // \| - heap: - FakeHeapSnapshotGraph() - ..setObjects({ - 1: [2], - 2: [3, 4], - }) - ..addObjects({ - 3: [5], - 4: [5], - }, weak: true) - ..addObjects({5: []}), + heap: FakeHeapSnapshotGraph() + ..setObjects({ + 1: [2], + 2: [3, 4], + }) + ..addObjects({ + 3: [5], + 4: [5], + }, weak: true) + ..addObjects({5: []}), rootRetainedSize: 4, unreachableSize: 1, ), diff --git a/packages/devtools_app/test/screens/memory/shared/heap/heap_test.dart b/packages/devtools_app/test/screens/memory/shared/heap/heap_test.dart index 7bc221c1e2c..9e6527be19c 100644 --- a/packages/devtools_app/test/screens/memory/shared/heap/heap_test.dart +++ b/packages/devtools_app/test/screens/memory/shared/heap/heap_test.dart @@ -28,59 +28,59 @@ final _classB = HeapClassName.fromPath(className: 'B', library: 'l'); final _classSizeTests = <_ClassSizeTest>[ _ClassSizeTest( name: 'separate', - heap: - FakeHeapSnapshotGraph()..setObjects( - { - 1: [2, 3, 4], - 2: [], - 3: [], - 4: [], - }, - classes: {1: _root, 2: _classA, 3: _classA, 4: _classA}, - ), + heap: FakeHeapSnapshotGraph() + ..setObjects( + { + 1: [2, 3, 4], + 2: [], + 3: [], + 4: [], + }, + classes: {1: _root, 2: _classA, 3: _classA, 4: _classA}, + ), expectedClassARetainedSize: 3, ), _ClassSizeTest( name: 'linked', - heap: - FakeHeapSnapshotGraph()..setObjects( - { - 1: [2], - 2: [3], - 3: [4], - 4: [], - }, - classes: {1: _root, 2: _classA, 3: _classA, 4: _classA}, - ), + heap: FakeHeapSnapshotGraph() + ..setObjects( + { + 1: [2], + 2: [3], + 3: [4], + 4: [], + }, + classes: {1: _root, 2: _classA, 3: _classA, 4: _classA}, + ), expectedClassARetainedSize: 3, ), _ClassSizeTest( name: 'full graph', - heap: - FakeHeapSnapshotGraph()..setObjects( - { - 1: [2], - 2: [3, 4], - 3: [2, 4], - 4: [2, 3], - }, - classes: {1: _root, 2: _classA, 3: _classA, 4: _classA}, - ), + heap: FakeHeapSnapshotGraph() + ..setObjects( + { + 1: [2], + 2: [3, 4], + 3: [2, 4], + 4: [2, 3], + }, + classes: {1: _root, 2: _classA, 3: _classA, 4: _classA}, + ), expectedClassARetainedSize: 3, ), _ClassSizeTest( name: 'with global B', - heap: - FakeHeapSnapshotGraph()..setObjects( - { - 1: [2], - 2: [3, 5], - 3: [4, 5], - 4: [2, 3], - 5: [], - }, - classes: {1: _root, 2: _classA, 3: _classA, 4: _classA, 5: _classB}, - ), + heap: FakeHeapSnapshotGraph() + ..setObjects( + { + 1: [2], + 2: [3, 5], + 3: [4, 5], + 4: [2, 3], + 5: [], + }, + classes: {1: _root, 2: _classA, 3: _classA, 4: _classA, 5: _classB}, + ), expectedClassARetainedSize: 4, ), ]; diff --git a/packages/devtools_app/test/screens/memory/tracing/tracing_view_test.dart b/packages/devtools_app/test/screens/memory/tracing/tracing_view_test.dart index 0c8ddf9e17d..3d850ab2645 100644 --- a/packages/devtools_app/test/screens/memory/tracing/tracing_view_test.dart +++ b/packages/devtools_app/test/screens/memory/tracing/tracing_view_test.dart @@ -65,10 +65,9 @@ void main() { } setUpAll(() { - final rawProfile = - File( - 'test/test_infra/test_data/memory/allocation_tracing/allocation_trace.json', - ).readAsStringSync(); + final rawProfile = File( + 'test/test_infra/test_data/memory/allocation_tracing/allocation_trace.json', + ).readAsStringSync(); allocationTracingProfile = CpuSamples.parse(jsonDecode(rawProfile))!; }); @@ -395,10 +394,9 @@ void main() { await tester.tap(checkboxes.first); await tester.pumpAndSettle(); - final tracedClassList = - state.filteredClassList.value - .where((e) => e.traceAllocations) - .toList(); + final tracedClassList = state.filteredClassList.value + .where((e) => e.traceAllocations) + .toList(); expect(tracedClassList.length, 1); expect(tracedClassList.first.clazz, classList.classes!.first); @@ -413,10 +411,9 @@ void main() { await clearFilter(tester, controller); // Check tracing state wasn't corrupted - final updatedTracedClassList = - state.filteredClassList.value - .where((e) => e.traceAllocations) - .toList(); + final updatedTracedClassList = state.filteredClassList.value + .where((e) => e.traceAllocations) + .toList(); expect(updatedTracedClassList, containsAll(tracedClassList)); expect(updatedTracedClassList.first.traceAllocations, true); }); diff --git a/packages/devtools_app/test/screens/network/network_controller_test.dart b/packages/devtools_app/test/screens/network/network_controller_test.dart index 256df4407ea..a66bffae707 100644 --- a/packages/devtools_app/test/screens/network/network_controller_test.dart +++ b/packages/devtools_app/test/screens/network/network_controller_test.dart @@ -300,26 +300,31 @@ void main() { }; final request1Pending = HttpProfileRequest.parse(httpBaseObject)!; - final request1Done = - HttpProfileRequest.parse({ - ...httpBaseObject, - 'endTime': endTime, - 'response': { - 'startTime': startTime, - 'endTime': endTime, - 'redirects': [], - 'statusCode': 200, - }, - })!; - final request2Pending = - HttpProfileRequest.parse({...httpBaseObject, 'id': '102'})!; + final request1Done = HttpProfileRequest.parse({ + ...httpBaseObject, + 'endTime': endTime, + 'response': { + 'startTime': startTime, + 'endTime': endTime, + 'redirects': [], + 'statusCode': 200, + }, + })!; + final request2Pending = HttpProfileRequest.parse({ + ...httpBaseObject, + 'id': '102', + })!; final socketStats1Pending = SocketStatistic.parse({...socketStatObject})!; - final socketStats1Done = - SocketStatistic.parse({...socketStatObject, 'endTime': endTime})!; - - final socketStats2Pending = - SocketStatistic.parse({...socketStatObject, 'id': '22'})!; + final socketStats1Done = SocketStatistic.parse({ + ...socketStatObject, + 'endTime': endTime, + })!; + + final socketStats2Pending = SocketStatistic.parse({ + ...socketStatObject, + 'id': '22', + })!; test( 'adding multiple socket and http requests notifies listeners only once', diff --git a/packages/devtools_app/test/screens/network/network_profiler_test.dart b/packages/devtools_app/test/screens/network/network_profiler_test.dart index c3f640c081a..15253ee4cf9 100644 --- a/packages/devtools_app/test/screens/network/network_profiler_test.dart +++ b/packages/devtools_app/test/screens/network/network_profiler_test.dart @@ -314,8 +314,8 @@ void main() { ) .first, ); - final selectableTextWidget = - textElement.findAncestorWidgetOfExactType()!; + final selectableTextWidget = textElement + .findAncestorWidgetOfExactType()!; await tester.tap(find.byWidget(selectableTextWidget)); await tester.pumpAndSettle(); diff --git a/packages/devtools_app/test/screens/performance/timeline_events/timeline_event_processor_test.dart b/packages/devtools_app/test/screens/performance/timeline_events/timeline_event_processor_test.dart index 42951ceb30e..5189e08ddad 100644 --- a/packages/devtools_app/test/screens/performance/timeline_events/timeline_event_processor_test.dart +++ b/packages/devtools_app/test/screens/performance/timeline_events/timeline_event_processor_test.dart @@ -52,18 +52,16 @@ void main() { when( mockPerformanceController.timelineEventsController, ).thenReturn(timelineEventsController); - processor = - timelineEventsController.perfettoController.processor - ..primeTrackIds(ui: testUiTrackId, raster: testRasterTrackId); - - trackEvents = - allTrackEventPackets - .map( - (packetJson) => PerfettoTrackEvent.fromPacket( - TracePacket.fromJson(jsonEncode(packetJson)), - ), - ) - .toList(); + processor = timelineEventsController.perfettoController.processor + ..primeTrackIds(ui: testUiTrackId, raster: testRasterTrackId); + + trackEvents = allTrackEventPackets + .map( + (packetJson) => PerfettoTrackEvent.fromPacket( + TracePacket.fromJson(jsonEncode(packetJson)), + ), + ) + .toList(); }); test('slice events form timeline event tree', () { diff --git a/packages/devtools_app/test/shared/analytics/analytics_test.dart b/packages/devtools_app/test/shared/analytics/analytics_test.dart index 475b1cc1683..4504b0f3172 100644 --- a/packages/devtools_app/test/shared/analytics/analytics_test.dart +++ b/packages/devtools_app/test/shared/analytics/analytics_test.dart @@ -11,8 +11,9 @@ import 'package:test/test.dart'; void main() { group('createStackTraceForAnalytics for stack trace', () { - final fileUriBase = - Platform.isWindows ? 'file:///c:/b/s/w' : 'file:///b/s/w'; + final fileUriBase = Platform.isWindows + ? 'file:///c:/b/s/w' + : 'file:///b/s/w'; test( 'with DevTools stack frames near the top', () { diff --git a/packages/devtools_app/test/shared/ansi_output_test.dart b/packages/devtools_app/test/shared/ansi_output_test.dart index ab8d24753c4..e0de53d7af3 100644 --- a/packages/devtools_app/test/shared/ansi_output_test.dart +++ b/packages/devtools_app/test/shared/ansi_output_test.dart @@ -142,13 +142,12 @@ void main() { break; } - final detailsComputer = - computedDetails == null - ? null - : () => Future.delayed( - const Duration(seconds: 1), - () => computedDetails!, - ); + final detailsComputer = computedDetails == null + ? null + : () => Future.delayed( + const Duration(seconds: 1), + () => computedDetails!, + ); return LogData(kind, details, i, detailsComputer: detailsComputer); } diff --git a/packages/devtools_app/test/shared/charts/flame_chart_test.dart b/packages/devtools_app/test/shared/charts/flame_chart_test.dart index b9354bc63e5..01fbe08e25a 100644 --- a/packages/devtools_app/test/shared/charts/flame_chart_test.dart +++ b/packages/devtools_app/test/shared/charts/flame_chart_test.dart @@ -715,18 +715,17 @@ void main() { node ??= testNode; await tester.pumpWidget( Builder( - builder: - (context) => Directionality( - textDirection: TextDirection.ltr, - child: node!.buildWidget( - selected: selected, - searchMatch: false, - activeSearchMatch: false, - hovered: hovered, - zoom: zoom, - theme: Theme.of(context), - ), - ), + builder: (context) => Directionality( + textDirection: TextDirection.ltr, + child: node!.buildWidget( + selected: selected, + searchMatch: false, + activeSearchMatch: false, + hovered: hovered, + zoom: zoom, + theme: Theme.of(context), + ), + ), ), ); } diff --git a/packages/devtools_app/test/shared/charts/treemap_test.dart b/packages/devtools_app/test/shared/charts/treemap_test.dart index 7946de69a29..65805f87548 100644 --- a/packages/devtools_app/test/shared/charts/treemap_test.dart +++ b/packages/devtools_app/test/shared/charts/treemap_test.dart @@ -64,10 +64,11 @@ void main() { final grandchild2 = TreemapNode(name: 'package:grandchild2'); final greatGrandchild1 = TreemapNode(name: 'package:greatGrandchild1'); final greatGrandchild2 = TreemapNode(name: 'package:greatGrandchild2'); - final testRoot = TreemapNode(name: 'libapp.so (Dart AOT)')..addAllChildren([ - child1..addChild(grandchild1..addChild(greatGrandchild1)), - child2..addChild(grandchild2..addChild(greatGrandchild2)), - ]); + final testRoot = TreemapNode(name: 'libapp.so (Dart AOT)') + ..addAllChildren([ + child1..addChild(grandchild1..addChild(greatGrandchild1)), + child2..addChild(grandchild2..addChild(greatGrandchild2)), + ]); final nodeWithDuplicatePackageNameGrandchild = TreemapNode( name: 'grandchild', diff --git a/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart b/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart index 43aee756de2..e761817975f 100644 --- a/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart +++ b/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart @@ -88,8 +88,8 @@ void main() { const testPubRootDirectory = '/alpha/bravo/charlie'; // Empty the pubroot directories. - final initialPubRootDirectories = - await inspectorServiceLocal.getPubRootDirectories(); + final initialPubRootDirectories = await inspectorServiceLocal + .getPubRootDirectories(); await inspectorServiceLocal.removePubRootDirectories( initialPubRootDirectories!, ); @@ -128,9 +128,8 @@ void main() { await inspectorServiceLocal.isWidgetCreationTracked(), isTrue, ); - final rootLibrary = - await serviceConnection.serviceManager - .mainIsolateRootLibraryUriAsString(); + final rootLibrary = await serviceConnection.serviceManager + .mainIsolateRootLibraryUriAsString(); await inspectorServiceLocal.addPubRootDirectories([rootLibrary!]); final rootDirectories = await inspectorServiceLocal.getPubRootDirectories() ?? @@ -205,8 +204,8 @@ void main() { // These tests are moot if widget creation is not tracked. expect(await inspectorServiceLocal.isWidgetCreationTracked(), isTrue); await inspectorServiceLocal.addPubRootDirectories([]); - final originalRootDirectories = - await inspectorServiceLocal.getPubRootDirectories(); + final originalRootDirectories = await inspectorServiceLocal + .getPubRootDirectories(); try { await inspectorServiceLocal.addPubRootDirectories([ '/usr/me/clients/google3/foo/bar/baz/lib/src/bla', @@ -266,11 +265,10 @@ void main() { test('isSummaryTree = true', () async { await env.setupEnvironment(); final group = inspectorService!.createObjectGroup('test-group'); - final root = - (await group.getRoot( - FlutterTreeType.widget, - isSummaryTree: true, - ))!; + final root = (await group.getRoot( + FlutterTreeType.widget, + isSummaryTree: true, + ))!; // Tree only contains widgets from local app. expect( treeToDebugString(root), @@ -327,18 +325,19 @@ void main() { // First get a node in the summary tree: final group = inspectorService!.createObjectGroup('test-group'); - final root = - (await group.getRoot( - FlutterTreeType.widget, - isSummaryTree: true, - ))!; - RemoteDiagnosticsNode nodeInSummaryTree = - findNodeMatching(root, 'MaterialApp')!; + final root = (await group.getRoot( + FlutterTreeType.widget, + isSummaryTree: true, + ))!; + RemoteDiagnosticsNode nodeInSummaryTree = findNodeMatching( + root, + 'MaterialApp', + )!; expect(nodeInSummaryTree, isNotNull); // Then get the details tree for the node in the summary tree: - RemoteDiagnosticsNode nodeInDetailsTree = - (await group.getDetailsSubtree(nodeInSummaryTree))!; + RemoteDiagnosticsNode nodeInDetailsTree = (await group + .getDetailsSubtree(nodeInSummaryTree))!; // When flutter rolls, this string may sometimes change due to // implementation details. @@ -354,8 +353,9 @@ void main() { equalsIgnoringHashCodes('Text\n'), ); - nodeInDetailsTree = - (await group.getDetailsSubtree(nodeInSummaryTree))!; + nodeInDetailsTree = (await group.getDetailsSubtree( + nodeInSummaryTree, + ))!; expect( treeToDebugString(nodeInDetailsTree), @@ -370,8 +370,10 @@ void main() { ); await group.setSelectionInspector(nodeInDetailsTree.valueRef, true); - final selection = - (await group.getSelection(null, FlutterTreeType.widget))!; + final selection = (await group.getSelection( + null, + FlutterTreeType.widget, + ))!; expect(selection, isNotNull); expect(selection.valueRef, equals(nodeInDetailsTree.valueRef)); expect( diff --git a/packages/devtools_app/test/shared/eval_integration_test.dart b/packages/devtools_app/test/shared/eval_integration_test.dart index ebd96fc8de3..36be55665f8 100644 --- a/packages/devtools_app/test/shared/eval_integration_test.dart +++ b/packages/devtools_app/test/shared/eval_integration_test.dart @@ -59,8 +59,10 @@ void main() { final instance = (await eval.asyncEval('42', isAlive: isAlive))!; expect(instance.valueAsString, '42'); - final instance2 = - (await eval.asyncEval('Future.value(42)', isAlive: isAlive))!; + final instance2 = (await eval.asyncEval( + 'Future.value(42)', + isAlive: isAlive, + ))!; expect(instance2.classRef!.name, '_Future'); }, timeout: const Timeout.factor(2), @@ -84,12 +86,11 @@ void main() { isolate: mainIsolate, ); - final instance = - (await eval.asyncEval( - // The delay asserts that there is no issue with garbage collection - 'await Future.delayed(const Duration(milliseconds: 500), () => 42)', - isAlive: isAlive, - ))!; + final instance = (await eval.asyncEval( + // The delay asserts that there is no issue with garbage collection + 'await Future.delayed(const Duration(milliseconds: 500), () => 42)', + isAlive: isAlive, + ))!; expect(instance.valueAsString, '42'); }, @@ -116,10 +117,9 @@ void main() { isAlive: isAlive, ) .then( - (_) => - throw Exception( - 'The FutureFailedException was not thrown as expected.', - ), + (_) => throw Exception( + 'The FutureFailedException was not thrown as expected.', + ), onError: (Object? err) => err, ); diff --git a/packages/devtools_app/test/shared/framework/screens_test.dart b/packages/devtools_app/test/shared/framework/screens_test.dart index f980c351e34..14bf1d36f9e 100644 --- a/packages/devtools_app/test/shared/framework/screens_test.dart +++ b/packages/devtools_app/test/shared/framework/screens_test.dart @@ -21,8 +21,9 @@ void main() { group('ScreenMetaData', () { test('values matches order of screens', () { final enumOrder = ScreenMetaData.values.map((s) => s.id).toList(); - final screenOrder = - defaultScreens().map((screen) => screen.screen.screenId).toList(); + final screenOrder = defaultScreens() + .map((screen) => screen.screen.screenId) + .toList(); // Remove any items that don't exist in both - we can't verify // the order of those. @@ -43,14 +44,12 @@ void main() { setUp(() { screen1 = SimpleScreen(const Placeholder()); screen2 = SimpleScreen(const Placeholder()); - extensionScreen1 = - DevToolsScreen( - ExtensionScreen(StubDevToolsExtensions.someToolExtension), - ).screen; - extensionScreen2 = - DevToolsScreen( - ExtensionScreen(StubDevToolsExtensions.barExtension), - ).screen; + extensionScreen1 = DevToolsScreen( + ExtensionScreen(StubDevToolsExtensions.someToolExtension), + ).screen; + extensionScreen2 = DevToolsScreen( + ExtensionScreen(StubDevToolsExtensions.barExtension), + ).screen; screens = [screen1, screen2, extensionScreen1, extensionScreen2]; }); diff --git a/packages/devtools_app/test/shared/framework/visible_screens_test.dart b/packages/devtools_app/test/shared/framework/visible_screens_test.dart index 01e6fda04f8..08fa495760d 100644 --- a/packages/devtools_app/test/shared/framework/visible_screens_test.dart +++ b/packages/devtools_app/test/shared/framework/visible_screens_test.dart @@ -270,9 +270,8 @@ void main() { }); } -List get visibleScreenTypes => - defaultScreens() - .map((s) => s.screen) - .where((s) => shouldShowScreen(s).show) - .map((s) => s.runtimeType) - .toList(); +List get visibleScreenTypes => defaultScreens() + .map((s) => s.screen) + .where((s) => shouldShowScreen(s).show) + .map((s) => s.runtimeType) + .toList(); diff --git a/packages/devtools_app/test/shared/import_export_test.dart b/packages/devtools_app/test/shared/import_export_test.dart index 61e31771a41..409531bfd3a 100644 --- a/packages/devtools_app/test/shared/import_export_test.dart +++ b/packages/devtools_app/test/shared/import_export_test.dart @@ -26,15 +26,14 @@ void main() { ExportController.generateFileName(time: t, type: ExportFileType.json), ); - final sortedByFileName = - dates - .map( - (t) => ExportController.generateFileName( - time: t, - type: ExportFileType.json, - ), - ) - .sorted(); + final sortedByFileName = dates + .map( + (t) => ExportController.generateFileName( + time: t, + type: ExportFileType.json, + ), + ) + .sorted(); expect(sortedByTime, sortedByFileName); }); diff --git a/packages/devtools_app/test/shared/memory/retaining_path_test.dart b/packages/devtools_app/test/shared/memory/retaining_path_test.dart index 8ccafbd86f0..13794071b79 100644 --- a/packages/devtools_app/test/shared/memory/retaining_path_test.dart +++ b/packages/devtools_app/test/shared/memory/retaining_path_test.dart @@ -33,16 +33,16 @@ void main() { final classB = HeapClassName.fromPath(className: 'B', library: 'l'); final classC = HeapClassName.fromPath(className: 'C', library: 'l'); - final graph = - FakeHeapSnapshotGraph()..setObjects( - { - 1: [2], - 2: [3], - 3: [4], - 4: [], - }, - classes: {1: root, 2: classA, 3: classB, 4: classC}, - ); + final graph = FakeHeapSnapshotGraph() + ..setObjects( + { + 1: [2], + 2: [3], + 3: [4], + 4: [], + }, + classes: {1: root, 2: classA, 3: classB, 4: classC}, + ); const shortestRetainers = [0, 0, 1, 2, 3]; PathFromRoot objectPath(int index) => PathFromRoot.forObject( diff --git a/packages/devtools_app/test/shared/preferences/preferences_controller_test.dart b/packages/devtools_app/test/shared/preferences/preferences_controller_test.dart index de1078317b8..84c19eb95a7 100644 --- a/packages/devtools_app/test/shared/preferences/preferences_controller_test.dart +++ b/packages/devtools_app/test/shared/preferences/preferences_controller_test.dart @@ -206,8 +206,8 @@ void main() { 'custom pub root directories are cached across multiple connections', () async { var directories = controller.pubRootDirectories.value; - var cachedDirectories = - await controller.readCachedPubRootDirectories(); + var cachedDirectories = await controller + .readCachedPubRootDirectories(); expect(directories, containsAll(customPubRootDirectories)); expect(cachedDirectories, containsAll(customPubRootDirectories)); @@ -228,8 +228,8 @@ void main() { 'test_dir/fake_app/custom_dir3', ], shouldCache: true); - final cachedDirectories = - await controller.readCachedPubRootDirectories(); + final cachedDirectories = await controller + .readCachedPubRootDirectories(); expect( cachedDirectories, @@ -246,8 +246,8 @@ void main() { () async { const notRemoved = 'test_dir/fake_app/custom_dir1'; const removed = 'test_dir/fake_app/custom_dir2'; - var cachedDirectories = - await controller.readCachedPubRootDirectories(); + var cachedDirectories = await controller + .readCachedPubRootDirectories(); expect(cachedDirectories, containsAll([notRemoved, removed])); @@ -266,8 +266,8 @@ void main() { }); test('does not save inferred directory to local cache', () async { - final cachedDirectories = - await controller.readCachedPubRootDirectories(); + final cachedDirectories = await controller + .readCachedPubRootDirectories(); expect(cachedDirectories, isNot(contains('test_dir/fake_app/'))); }); @@ -278,8 +278,8 @@ void main() { await controller.addPubRootDirectories([ 'test_dir/fake_app/do_not_cache_dir', ]); - final cachedDirectories = - await controller.readCachedPubRootDirectories(); + final cachedDirectories = await controller + .readCachedPubRootDirectories(); expect( cachedDirectories, diff --git a/packages/devtools_app/test/shared/primitives/trees_test.dart b/packages/devtools_app/test/shared/primitives/trees_test.dart index 898b1c56270..35046f75d34 100644 --- a/packages/devtools_app/test/shared/primitives/trees_test.dart +++ b/packages/devtools_app/test/shared/primitives/trees_test.dart @@ -327,17 +327,17 @@ void main() { treeNodeI = TraversalTestTreeNode('I'); treeNodeJ = TraversalTestTreeNode('J'); - tree = - treeNodeA..addAllChildren([ - treeNodeB..addAllChildren([ - treeNodeE..addAllChildren([treeNodeH]), - treeNodeF, - ]), - treeNodeC, - treeNodeD..addAllChildren([ - treeNodeG..addAllChildren([treeNodeI, treeNodeJ]), - ]), - ]); + tree = treeNodeA + ..addAllChildren([ + treeNodeB..addAllChildren([ + treeNodeE..addAllChildren([treeNodeH]), + treeNodeF, + ]), + treeNodeC, + treeNodeD..addAllChildren([ + treeNodeG..addAllChildren([treeNodeI, treeNodeJ]), + ]), + ]); }); group('BFS', () { @@ -361,11 +361,10 @@ void main() { }); test('finds the correct node', () { - final node = - breadthFirstTraversal( - tree, - returnCondition: (node) => node.id == 'H', - )!; + final node = breadthFirstTraversal( + tree, + returnCondition: (node) => node.id == 'H', + )!; expect(node.id, equals('H')); }); }); @@ -391,11 +390,10 @@ void main() { }); test('finds the correct node', () { - final node = - depthFirstTraversal( - tree, - returnCondition: (node) => node.id == 'H', - )!; + final node = depthFirstTraversal( + tree, + returnCondition: (node) => node.id == 'H', + )!; expect(node.id, equals('H')); }); @@ -436,15 +434,15 @@ final treeNode9 = TestTreeNode(9, tag: 'test-tag'); final treeNode10 = TestTreeNode(10); final treeNode11 = TestTreeNode(11); final treeNode12 = TestTreeNode(12); -final testTreeNode = - treeNode0..addAllChildren([ - treeNode1, - treeNode2..addAllChildren([treeNode10, treeNode11, treeNode12]), - treeNode3..addAllChildren([ - treeNode4, - treeNode5..addAllChildren([treeNode6, treeNode7, treeNode8, treeNode9]), - ]), - ]); +final testTreeNode = treeNode0 + ..addAllChildren([ + treeNode1, + treeNode2..addAllChildren([treeNode10, treeNode11, treeNode12]), + treeNode3..addAllChildren([ + treeNode4, + treeNode5..addAllChildren([treeNode6, treeNode7, treeNode8, treeNode9]), + ]), + ]); class TestTreeNode extends TreeNode { TestTreeNode(this.id, {this.tag}); diff --git a/packages/devtools_app/test/shared/primitives/utils_test.dart b/packages/devtools_app/test/shared/primitives/utils_test.dart index 3cdbdb2a772..267b22f7c3f 100644 --- a/packages/devtools_app/test/shared/primitives/utils_test.dart +++ b/packages/devtools_app/test/shared/primitives/utils_test.dart @@ -269,30 +269,24 @@ void main() { }); test('overlaps', () { - final t = - TimeRange() - ..start = const Duration(milliseconds: 100) - ..end = const Duration(milliseconds: 200); - final overlapBeginning = - TimeRange() - ..start = const Duration(milliseconds: 50) - ..end = const Duration(milliseconds: 150); - final overlapMiddle = - TimeRange() - ..start = const Duration(milliseconds: 125) - ..end = const Duration(milliseconds: 175); - final overlapEnd = - TimeRange() - ..start = const Duration(milliseconds: 150) - ..end = const Duration(milliseconds: 250); - final overlapAll = - TimeRange() - ..start = const Duration(milliseconds: 50) - ..end = const Duration(milliseconds: 250); - final noOverlap = - TimeRange() - ..start = const Duration(milliseconds: 300) - ..end = const Duration(milliseconds: 400); + final t = TimeRange() + ..start = const Duration(milliseconds: 100) + ..end = const Duration(milliseconds: 200); + final overlapBeginning = TimeRange() + ..start = const Duration(milliseconds: 50) + ..end = const Duration(milliseconds: 150); + final overlapMiddle = TimeRange() + ..start = const Duration(milliseconds: 125) + ..end = const Duration(milliseconds: 175); + final overlapEnd = TimeRange() + ..start = const Duration(milliseconds: 150) + ..end = const Duration(milliseconds: 250); + final overlapAll = TimeRange() + ..start = const Duration(milliseconds: 50) + ..end = const Duration(milliseconds: 250); + final noOverlap = TimeRange() + ..start = const Duration(milliseconds: 300) + ..end = const Duration(milliseconds: 400); expect(t.overlaps(t), isTrue); expect(t.overlaps(overlapBeginning), isTrue); @@ -303,30 +297,24 @@ void main() { }); test('containsRange', () { - final t = - TimeRange() - ..start = const Duration(milliseconds: 100) - ..end = const Duration(milliseconds: 200); - final containsStart = - TimeRange() - ..start = const Duration(milliseconds: 50) - ..end = const Duration(milliseconds: 150); - final containsStartAndEnd = - TimeRange() - ..start = const Duration(milliseconds: 125) - ..end = const Duration(milliseconds: 175); - final containsEnd = - TimeRange() - ..start = const Duration(milliseconds: 150) - ..end = const Duration(milliseconds: 250); - final invertedContains = - TimeRange() - ..start = const Duration(milliseconds: 50) - ..end = const Duration(milliseconds: 250); - final containsNeither = - TimeRange() - ..start = const Duration(milliseconds: 300) - ..end = const Duration(milliseconds: 400); + final t = TimeRange() + ..start = const Duration(milliseconds: 100) + ..end = const Duration(milliseconds: 200); + final containsStart = TimeRange() + ..start = const Duration(milliseconds: 50) + ..end = const Duration(milliseconds: 150); + final containsStartAndEnd = TimeRange() + ..start = const Duration(milliseconds: 125) + ..end = const Duration(milliseconds: 175); + final containsEnd = TimeRange() + ..start = const Duration(milliseconds: 150) + ..end = const Duration(milliseconds: 250); + final invertedContains = TimeRange() + ..start = const Duration(milliseconds: 50) + ..end = const Duration(milliseconds: 250); + final containsNeither = TimeRange() + ..start = const Duration(milliseconds: 300) + ..end = const Duration(milliseconds: 400); expect(t.containsRange(containsStart), isFalse); expect(t.containsRange(containsStartAndEnd), isTrue); @@ -377,10 +365,9 @@ void main() { group('offset', () { test('from well formed time range', () { - final t = - TimeRange() - ..start = const Duration(milliseconds: 100) - ..end = const Duration(milliseconds: 200); + final t = TimeRange() + ..start = const Duration(milliseconds: 100) + ..end = const Duration(milliseconds: 200); final offset = TimeRange.offset( original: t, offset: const Duration(milliseconds: 300), diff --git a/packages/devtools_app/test/shared/table/table_test.dart b/packages/devtools_app/test/shared/table/table_test.dart index 3998b5973f0..62ba9c32d95 100644 --- a/packages/devtools_app/test/shared/table/table_test.dart +++ b/packages/devtools_app/test/shared/table/table_test.dart @@ -1152,27 +1152,25 @@ void main() { setUp(() { treeColumn = _NameColumn(); _NumberColumn(); - tree1 = - TestData('Foo', 0) + tree1 = TestData('Foo', 0) + ..children.addAll([ + TestData('Bar', 1) ..children.addAll([ - TestData('Bar', 1) - ..children.addAll([ - TestData('Baz', 2), - TestData('Qux', 3), - TestData('Snap', 4), - TestData('Crackle', 5), - TestData('Pop', 5), - ]), - TestData('Baz', 7), - TestData('Qux', 6), - ]) - ..expandCascading(); - tree2 = - TestData('Foo_2', 0) - ..children.add( - TestData('Bar_2', 1)..children.add(TestData('Snap_2', 2)), - ) - ..expandCascading(); + TestData('Baz', 2), + TestData('Qux', 3), + TestData('Snap', 4), + TestData('Crackle', 5), + TestData('Pop', 5), + ]), + TestData('Baz', 7), + TestData('Qux', 6), + ]) + ..expandCascading(); + tree2 = TestData('Foo_2', 0) + ..children.add( + TestData('Bar_2', 1)..children.add(TestData('Snap_2', 2)), + ) + ..expandCascading(); }); testWidgets('displays with simple content', (WidgetTester tester) async { @@ -1574,18 +1572,17 @@ void main() { testWidgets('properly colors rows with alternating colors', ( WidgetTester tester, ) async { - final data = - TestData('Foo', 0) + final data = TestData('Foo', 0) + ..children.addAll([ + TestData('Bar', 1) ..children.addAll([ - TestData('Bar', 1) - ..children.addAll([ - TestData('Baz', 2), - TestData('Qux', 3), - TestData('Snap', 4), - ]), - TestData('Crackle', 5), - ]) - ..expandCascading(); + TestData('Baz', 2), + TestData('Qux', 3), + TestData('Snap', 4), + ]), + TestData('Crackle', 5), + ]) + ..expandCascading(); final table = TreeTable( columns: [_NumberColumn(), treeColumn], dataRoots: [data], diff --git a/packages/devtools_app/test/shared/ui/filter_test.dart b/packages/devtools_app/test/shared/ui/filter_test.dart index b5de27beee1..6d5ac0417b4 100644 --- a/packages/devtools_app/test/shared/ui/filter_test.dart +++ b/packages/devtools_app/test/shared/ui/filter_test.dart @@ -397,9 +397,8 @@ class _TestController extends DisposableController SettingFilter<_TestDataClass, int>( id: 'min-rating-level', name: 'Hide items below the minimum rating level', - includeCallback: - (_TestDataClass element, int currentFilterValue) => - element.rating >= currentFilterValue, + includeCallback: (_TestDataClass element, int currentFilterValue) => + element.rating >= currentFilterValue, enabledCallback: (int filterValue) => filterValue > 1, possibleValues: [1, 2, 3, 4, 5], defaultValue: 2, diff --git a/packages/devtools_app/test/shared/ui/hover_test.dart b/packages/devtools_app/test/shared/ui/hover_test.dart index 06483ddc6e3..b5181d5de37 100644 --- a/packages/devtools_app/test/shared/ui/hover_test.dart +++ b/packages/devtools_app/test/shared/ui/hover_test.dart @@ -8,15 +8,24 @@ import 'package:flutter_test/flutter_test.dart'; const _textSpan = TextSpan( children: [ - TextSpan(text: 'hello', style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan( + text: 'hello', + style: TextStyle(fontWeight: FontWeight.bold), + ), TextSpan(text: ' '), TextSpan(text: 'world'), TextSpan(text: ' '), - TextSpan(text: 'foo', style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan( + text: 'foo', + style: TextStyle(fontWeight: FontWeight.bold), + ), TextSpan(text: '.'), TextSpan(text: 'bar'), TextSpan(text: '.'), - TextSpan(text: 'baz', style: TextStyle(fontWeight: FontWeight.w100)), + TextSpan( + text: 'baz', + style: TextStyle(fontWeight: FontWeight.w100), + ), TextSpan(text: ' '), TextSpan(text: 'blah'), ], diff --git a/packages/devtools_app/test/shared/ui/ui_utils_test.dart b/packages/devtools_app/test/shared/ui/ui_utils_test.dart index 59cab3b5089..16982a068e1 100644 --- a/packages/devtools_app/test/shared/ui/ui_utils_test.dart +++ b/packages/devtools_app/test/shared/ui/ui_utils_test.dart @@ -105,9 +105,18 @@ void main() { text: 'parent', style: TextStyle(color: Colors.red), children: [ - TextSpan(text: 'foo', style: TextStyle(color: Colors.blue)), - TextSpan(text: 'bar', style: TextStyle(color: Colors.green)), - TextSpan(text: 'baz', style: TextStyle(color: Colors.yellow)), + TextSpan( + text: 'foo', + style: TextStyle(color: Colors.blue), + ), + TextSpan( + text: 'bar', + style: TextStyle(color: Colors.green), + ), + TextSpan( + text: 'baz', + style: TextStyle(color: Colors.yellow), + ), ], ); expect( diff --git a/packages/devtools_app/test/shared/ui/vm_flag_widgets_test.dart b/packages/devtools_app/test/shared/ui/vm_flag_widgets_test.dart index 94d72448b73..e35bd05d7f1 100644 --- a/packages/devtools_app/test/shared/ui/vm_flag_widgets_test.dart +++ b/packages/devtools_app/test/shared/ui/vm_flag_widgets_test.dart @@ -34,8 +34,9 @@ void main() { await fakeServiceConnection.serviceManager.flagsInitialized.future; dropdown = CpuSamplingRateDropdown( screenId: ProfilerScreen.id, - profilePeriodFlagNotifier: - fakeServiceConnection.vmFlagManager.flag(profilePeriod)!, + profilePeriodFlagNotifier: fakeServiceConnection.vmFlagManager.flag( + profilePeriod, + )!, ); }); @@ -85,8 +86,9 @@ void main() { ); expect(dropdownButton.value, equals(CpuSamplingRate.medium.value)); - var profilePeriodFlag = - (await getProfileGranularityFlag(fakeServiceConnection))!; + var profilePeriodFlag = (await getProfileGranularityFlag( + fakeServiceConnection, + ))!; expect( profilePeriodFlag.valueAsString, equals(CpuSamplingRate.medium.value), @@ -102,8 +104,9 @@ void main() { ); expect(dropdownButton.value, equals(CpuSamplingRate.high.value)); - profilePeriodFlag = - (await getProfileGranularityFlag(fakeServiceConnection))!; + profilePeriodFlag = (await getProfileGranularityFlag( + fakeServiceConnection, + ))!; expect(profilePeriodFlag.name, equals(profilePeriod)); expect( profilePeriodFlag.valueAsString, @@ -125,8 +128,9 @@ void main() { ); expect(dropdownButton.value, equals(CpuSamplingRate.low.value)); - profilePeriodFlag = - (await getProfileGranularityFlag(fakeServiceConnection))!; + profilePeriodFlag = (await getProfileGranularityFlag( + fakeServiceConnection, + ))!; expect(profilePeriodFlag.name, equals(profilePeriod)); expect( profilePeriodFlag.valueAsString, diff --git a/packages/devtools_app/test/standalone_ui/vs_code/devtools_test.dart b/packages/devtools_app/test/standalone_ui/vs_code/devtools_test.dart index d1fcbd38429..eb549f8d601 100644 --- a/packages/devtools_app/test/standalone_ui/vs_code/devtools_test.dart +++ b/packages/devtools_app/test/standalone_ui/vs_code/devtools_test.dart @@ -74,17 +74,16 @@ void main() { group('$DevToolsSidebarOptions', () { for (final hasDebugSessions in [true, false]) { - final debugSessions = - hasDebugSessions - ? { - 'test session': generateDebugSession( - debuggerType: 'Flutter', - deviceId: 'macos', - flutterMode: 'debug', - projectRootPath: testDtdProjectRoot, - ), - } - : {}; + final debugSessions = hasDebugSessions + ? { + 'test session': generateDebugSession( + debuggerType: 'Flutter', + deviceId: 'macos', + flutterMode: 'debug', + projectRootPath: testDtdProjectRoot, + ), + } + : {}; testWidgetsWithWindowSize( 'pumps DevTools screens ${hasDebugSessions ? 'with' : 'without'} debug ' diff --git a/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart b/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart index 48dd5da9214..29c00d88ce1 100644 --- a/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart +++ b/packages/devtools_app/test/test_infra/fixtures/networking_app/bin/main.dart @@ -147,11 +147,10 @@ class _HttpClient { void packageHttpPostStreamed() async { print('Sending streamed package:http POST...'); - final request = - http.StreamedRequest('POST', _uri) - ..contentLength = 20 - ..sink.add([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) - ..sink.add([21, 22, 23, 24, 25, 26, 27, 28, 29, 30]); + final request = http.StreamedRequest('POST', _uri) + ..contentLength = 20 + ..sink.add([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) + ..sink.add([21, 22, 23, 24, 25, 26, 27, 28, 29, 30]); unawaited(request.sink.close()); final response = await request.send(); diff --git a/packages/devtools_app/test/test_infra/flutter_test_driver.dart b/packages/devtools_app/test/test_infra/flutter_test_driver.dart index 8d1c602c4a9..99eda70e734 100644 --- a/packages/devtools_app/test/test_infra/flutter_test_driver.dart +++ b/packages/devtools_app/test/test_infra/flutter_test_driver.dart @@ -56,8 +56,9 @@ abstract class FlutterTestDriver { String _debugPrint(String msg) { const maxLength = 500; - final truncatedMsg = - msg.length > maxLength ? '${msg.substring(0, maxLength)}...' : msg; + final truncatedMsg = msg.length > maxLength + ? '${msg.substring(0, maxLength)}...' + : msg; _allMessages.add(truncatedMsg); if (_printDebugOutputToStdOut) { print('$_logPrefix$truncatedMsg'); @@ -223,10 +224,9 @@ abstract class FlutterTestDriver { return _timeoutWithMessages>( () => response.future, timeout: timeout, - message: - event != null - ? 'Did not receive expected $event event.' - : 'Did not receive response to request "$id".', + message: event != null + ? 'Did not receive expected $event event.' + : 'Did not receive response to request "$id".', ).whenComplete(() => sub.cancel()); } diff --git a/packages/devtools_app/test/test_infra/goldens/memory/load_offline_data_profile_tab.png b/packages/devtools_app/test/test_infra/goldens/memory/load_offline_data_profile_tab.png index f3ff3691f1da8dccd449309c52e5c02f1f2bb994..97595ba6d0fb26ed19fb67e5a80079b4642c499b 100644 GIT binary patch literal 28761 zcmeFZXIN8d*EXCPXNFN!K&n&)1(YsQq&kW)0t$#yLm80Xq?gbvAU%VHUKFHBlirIO zdWrN-l+Z(np@o`!SA?K*fA@1d<$Zs=Kc0OYif*#6vaVImb*{A&s(D-G#4*-m5D4VN z%|DgyKp?*tK_ExwfBy~K5qM1G20wmsy`ypsQqax50RHof>$RJAe+QTE@ApF>kTZ~* zN`Kt-N?MwLc|kqBMYcVadGwz-oc9paXQeWE(I09~okV*^^E$`W<)%QRMa`#gZa*k| z(RBsJEa;1lHpq0o?4DfS)qcV`#p2AjvL+_Q}M zT&vHvwM_ z>eOyD>Tk7aq(;=>Mpy&3VwP@1LgPlJQaR+G8Hn{QB?t=qBVABE1vTct$SDAr3D zuea+W!VA5$M&0*k3pA0A9eI|Ll2VCD$#-s>3P&%#6u3R=(M#K*%SE(gm-FKHhhZ0| zB&fosxQO_I&3ue82lZ^jD}IdMCJ$GnZlSM*pnh>BKjyt&72!GIhB^9!*NB=)k_Y4d z1aT{25{4^PNO{`1)Bt0s-?{+YBu0KCmM>+TQA44s146B?=~TZJyh&2n#;4`22T|3t zi`Z9pLa5Jwxh0hs?&QBZ)>B7_FU{Q_uknRW=g2du+Ar>SbgCR(evJoL!_sE7o@5=y z&w0$ji3=|(BI~g$s<7PyKVSV!aq}?>ZqX5w;;L_2iSui?lH!#nF-Tfw>-LE>s_|%v z<@Avzu4za{Rr-yUiy(#?i0evrb%Z)x=;GpH$@0%Pu?ve)@PJ)yJPJiL=`Hwqe-+w; zf0mqA^xaj#hXxSurtLXZ<2}t6EMhrH+pW8%n;5eW`E>J7d@O zRR(ttkLD~zKa(^8U#y)jI8$IxJ%fWO)+F=x4%Z%(;@{GWmoGDn*h~Jgvb5ql3#EPe z@@44i4gm*$Oht3PJ2o~}B_JSR%J;P>L%jM5(JDc)Z;UjopK~d`GtQ_bev-<_$f##1 zc2|-Ev-4Sfs4$x!UR_=NTo{ID6ba*y^=PKyBK6$VSQ2+8v{W>w*6lfDjn|vEL?Ms_ z&jwiEyAB^1%p7-`UCjKFoFv~UrcF;#vSoYS>P-uAyn0lxzV<@>?x&B=6HfIqc!Pae zTy;*eEq{}nD_g%aPoU3t#=gzf*v_k|uD+<#Fgv>0=|^Z;#|$bJl#~c;a7nZ1)_ZMb zhu0C;3&Rz+(-m2q#}tWZ6*RSpmnp*G=}C^T+=A_Or673KQt^5GCR&z$j#(H=t07+| zOBM-Xd{x7FeL#SIPI32(toiCJ{9Jd#vU_1973Xk@wBjHN7e7g~LaP^|)p3sv9k=$Z zZAPM{12PHkXJSn_;qn{9arvnJQbA7N2b-?8U6=p?g}rzOD+$Dk6KWgoH4~O=w!PK^ zPjMM@z=h-%RNEpPoM2-Cky)w!J_rXA5l5n9ldQesoYnSqILW$@&wOu~9W#`wEx%Fd zy`DRTQ*^VcU3@75fBW_=0`t?pfaZAH?AxdlW152#2jP|26b<`GuF~BH2nP|rHb#7E zmuy-M%xQYV&HaY^2bv=ywGWJ;&P_8}6diFvph(Gzy0BMI>}_9o zs>jX!_U*-Va1zB>Y;rVmDAn~Z)7@#d#q_%L)d+%}6DDN0Hdt)o7xdZGLiompc)-$u zSF&=-vr?O#VN1)e`$$XuBCTZWOu&N&q8kdU_MQ2;93{r0gU3NUBVUc1Y?zT}=BY<4 z$7E%AP^KZjshF!Mg&*fp8o5K3O_-t9fX&w@7Dsjz9dAuC>cymp9mYXn` z71VoXMSL_XFHdk5Dk=*k+X9qVYZaU%i31oEkK?K@pOCp)TPcUMJ^xud=4)=kxT?cD%m+6#eP-N2?Lq zW@ST|3KZA|mUVwX(TsD+LZ=<{X6}xT%9w4fSVZTh8nVF^eAY_8+{-NpO(pH-lvH!S zs@%ZBgjtz|B0w|}pCtS$634u=A@4cbDT~@toJz*+a?O3BZSHPtyxM=B<->vR37c~( zIZyVx(7KhEbEW=HPEMW4hRh>Xu9&n;OG{ruPfNGWAEv(cHKg~O>m~sU`q&*zp_jfd zW(?*0gi*D(!FQdlXu7va>z>4lO~L+(1B=9BO3tIar(t5SjlAsKWcrbi5GmsZNzP%S z=GxjC!(Myfl=oUsOPY_5JG6ZIS&1<^=7bc&h~QhCU1yr-?y(%oRVv5X;Ef%y(cM4G zzza5lmTD)t6xdC+S3VXkdm3}m(ZyeTtr-$x?cjHjb33-M#gMq!b))9eD=!}(AM_sA z=FVn^=Y&tUodap=x|n%$#Ac*!T^j#{Y2MyC%9o$`l@K5zTxsetdhg)m+AnU{x6Q(R z1$7FI8L62&;UQkcKLzRNA|t8M&zhK9<`f85wF-XcFQ~z7-QWGfWzXMkP-wK5ShT95 z7|NkIuK!})RM2l~5{Zx~^ndvi)Bdo3>Wf*aE$=Kbn=SOJ!D-$hLa&1{bqk?%s%r?% zDB{FZbg>$93&08~9vu46L2-pfI@OEK4h}@Mxi`jdj}8$f zIQRTr$7}zpYdOC^lloOFal@5lm3n6KVK{emVKiiZ?hxZSS;W3d9@lRtCA|G@dt9tj zh;O|DuynK8&eL-n$&in309KW6L|NNmA~rUn_yq*QK|GD`zvbXzb#>Simqpn z7>@jDOeU?OLdp`E!ie#oThD@GO0Nsz!)XR(Wo!Ja9>7!p5Xs&|F{=NyI%mQnFJA|c z4(;mffQkZ&mbtq_<=(xS$_+37kXe8-)p_YPqsBgUal2f(r?)-j9 z-$wVqpPgd0DL=>Uf2IFY;n~^l{P610D_KTX{b!j>ml%%)wcfvEGZg4NS46YFRCe=_ z1GfqZ?6>F>-oFd}4%Vam^Uvh72g(D1+_C!MrQ6E_Lw?)miTvo)i- z40$BK?KQ92c&oImEI#l&+WB@Ho+3)#vWE}9jkU6}lAWKw{$Am^j=sKr|G>ZvZ*Olm zH#Y=ulcO&`M|ioDQz~%r=D&XZdbq?&qrbl&k*8nMTW|zzHkhZcrL9d5+gJ((zb(aF zHKQC#;LRLOekEO9-MhNFEuHb=0Fk3@!79ii1*l4kp8*UII^9b-eNiUz{^QkWH|g{w zo$AG9WMq^l3X7bzO3Rm3|F(-5930eg1>)-&7xWr(B`|`yoWFj4pPiF)v*z|q01%_w?)Mgm&9G1ui8uNE z`}fjbUrnc1x6rW;D5B|QDJgh0ZnVtKY^;1IJjTw}HY_G4=9he)goKzIY8_E&Mudpd z;-^j&tq}+7L{4BYFfw(}evP#p!L;YMk4ZTb35ub$9StdIouBa2n|F2=d4xs=t{@=8jQ ziIE`xYjH)&GnZH)Z`X7`SxxN{!nb;Ig@=TAZ*5n);hXRv-%#c#H+7?;;gnHeC^c_E z=(m^Dv#c!8ojkg@?Tn;(+beq?NdVLA9(S3OIb!H~-=;$cggUs!f0(ZzPwN|TWSz5{?$b9_O=E~e7rUuRN9`4Vjhiedi(n5`!a8l zjiEHR@rkC64im7Yp0P1DU@103Hz&lAa%^0ipGl#p8hm6=znlK3d*+K+sJFMEp^weD zJ94n{KEBC$y`7QI!E@=r>P+t}EG&@Ih*G=8CwG7n$;->z4E<^3Ntmqk#8{#C0?OJT zYN`M!P6-9<&U!hbT=8XvdzhPJ6eIqyqlO$DFxY5ZI{{HeY)YGCh^Pt6d^67~nG0 zYJOAa*Y*pUS;z|DtVtQ=aDrjDQZB8|h$u41dJ?Vs%VGqp+z@AD_I3y@?;k%s<#~}I znEUxn|DThA>CWSDTqWzsS`Fdt9ja4vJlwNg9jR^%NsEhb_4X3%(Bgy%uAxH1Lx&p& zJr?vxJE*a+)w1N92}UP4`L2!?&AKjT?xqAZliWwg&e0-*Pp(7O_I1EnKL0X)d}VS1Yy7 zq${g$I*hlU2}~&_dMbGmj1N_$|D7|s3s|zet#GPSNQRn-fWh)3YReX&7>U{Dz_>B> zyDKxH1r=#&+>SNa!Mie<-m=0_X~iC&7xk$MJ*-Z({k3>sMU3^~+t#Kf21nP?#byKz@X=VVQ7MMXtxm-PO0J`|}y8mA=yTAT-Jo{}<| z{gzcBX(jh0hYUMN<2Yj-sXlN1#ZQ6&g&(Y_x9D|a zr?HthNpYKKY(<0k#fukDS)7(_@W9{bnW&SRMK*kW5nt##qlO+0HCe=BBLVU~G?^sp zoeiq=sw(gP@k4(I>j^i0;dS*5gG|)ZQpcy6nVHr$HaGk6gNCFJv>m^EWoy8PZSKxB zu#kqvi2T@#yJ0xFmAW{2m`?vdcc}fS1x4P?y#V1cGaHri*ApWH)M}3LN&9X-@LlMj zX{kne`zbx)Imm$^kmsnyp}a5}->)P@afTXjvD9JpM2Ctx9-ti@H%tikxj515Ekj10 zPLYO=#sRx_WTA?NecV$q8+vGjUwfFv!)@l@wX1ixgg-M@H_Pb6t2bWqWE9f7LB-}2 z2CMLwBoi0PAO-?wRJx3!k4`SnXB zW;wseZ6O2CR_N1obF4V0>}N>e(LBtby0v?30Zd~lyC2@sKzX>2X@wx=@mrfX)aL5E zOmDKPO5mN(>kMFmIBPPr!@+P^kkTuL!2_oHY=+|R)UUP@rXB}WTmk4^!andkdnnjo zFq`1<<{hrB#Njeh4m!5(UHJv3LBWuakgN?{6xWgiKt_XmHB)=2y{o&}Tm=w;dCR&X z^wC4wfH)MdutKIhY5UT^4@rt=L%I3wzM6T8ClS%)_{|MW7la+aO_DL6T8(j=tk+k~ z(lSpakTaH+xhs)VsT6sEN%x)9RF`k@;j4hcIvR=4NQH58bK73DokAAu228C~&+u8) zqt^9&zxFhQKlXb%m9>)+qCuLj-<(h@(8v*ML`;+S{kiiv0AArHyTwW)nY>w7ADVgn z)z@2T-1P)F%i=_{_YJ=q6YxQ zaew-+Ey1Hmdugl6r2J@6am(&w=#Q#TNML=7E+5A__&) z^liWt{Z)m-dJ9TQp}co7sCw&L;1lRUdegL3A2Pq+7~h^@1b*@+M5;N3&KAUYZGY}_ zeup!y#f*6(sO=KXw7Nd903}DBB+4b!1U!&Kc}=E~jZ&>lyiw_!=J4O!caUIIe^i%>-kPM`<>;~Gk0u11}B=~r?m8UrG7|P{ValFIW&ELFs)uKXK7?Us2Shzx7{EN5P zF|LT&*;y@DyP<+mhp}Z5gMyr#3kC+kq(qzPrDDLRi7j)OtfevE%03&@=4O&_Q1QR=|Huis?+ z{5r^kmc}YXqB!MQLBd1E^i@z{mn!J}OYx-`v6F!HoJu8arG^&|?x0A-?A%;7k1BGC zCLIJV7bKdFG*^CkwqAs3EEujMEwtX}X6hFVxiKdcu?Te^W&BC?5!szU_#JjOu;Cw{ z(x}|Jb*q1Hkk#Nz5{LAIMzU;^A{S-`ik2Q_kpBSAgWra1Z;)4|AU#v|^z^)6GSWJ? z8r@~tSAaOzgF;Ujo4Yr3WMLEA8Y{*5}9>04Bczkjamz zg+rjiYAGL+S+jlwYlZS(g;Yr(rRjUHZ7tkDHep?bGkJe zz%971f}(9XNNo%aVN+$)LD!U&?q52+r5z_F5}>?wN7AZ0$=b;Y4r&0|Z{J=ze0;Z; zjN1X<;h(kysIIBEx&D5gvbWC5dX^);Wk+I;-Lkk^ujQ(_!{EF7Hqo*AY(drRB5*cL zo$zpBTS0?@a*x|?o+i(;(W@hM=*gmbf5$X`w8fc{;_NeH_nB!$BU2aVEab@KG+ zK)AalAZiqGwfxHPPC z!SLJL+uX6@w;LC*!$mwGFMZBm0}|*yN5ze})$9XWL;C#&mPXmtbv3)H%x(x#?m&Pi zB#N0Ur@ekmBoc>&t^e_o|chuUaRE|;U0NHyU|h` zvMmE4ntO1lpX4HKwuG1KfB*?3D4k4upoU*-L4Grj#ons~7q`QDF$m#;=s<=OKHLE$FZ6PN&HyrM_WPZb_M3Wx@ z&^SHNB09QnR&dqE+j{8g?iXel8kYRn`Lp%elk7qWf(#X!reTXf)>u^sBQ&oq^npSi_lIxW%9!Qi#AuY}5C6*&rN9zd zfCd4^B*Q4^=HiG|Y9w%caT0ce`(O;Bc_(GF>Fj{Yn9kBaCJhV$E&)g|a(Q`~AL!Z8 zU(Z-rS;Gnn3V<%p61_7+b9CtT!?8PsAHW;h0*Pq2{mU{y%SI%Y^kSSn8joPc&?Q%Ny?IOV;zBU|o| zOL~%n%}jI*u`8(Z=^uae>nb`eoK>Z(ZY@LPrdu8G-}sFRQiamU=;#%I#y$JTKLoAP z=j*-=^D{Z$B_FT@4BfnU=j|{&%dGAGB{9$CacP(7KbKGqie$QkoMn@>LO3=Y__cU- zOQ@_CYcMESf?@(N$f^0Bbh6sf(Un+sg#q27Bb;^)$pCPEX)NV2*v~hQ5SK=rURm+# zh*c)OCZ} zoM09$-sfcHY@Kn@x_6He5M!s^2YIwNU#e&WeYXdekXMuPTz0vV2Y@4ZKpmhzLqdit zoz27YfgD*xXmFe%aNh<+|7s_GZf<`E9RSS3R=n09jmOP~P0&CB@AvvN%C z+4AUD>fVB%=%eO-qd%k!P4D3UkdNqeeH>aat?UsisDFwu33D1fC`5xWlx9Erjet~7 zupFWE0+3Dc)pQi1*mbU3JLNWrpycZ_)M3)s3eaH@33m2ShWz}RQ`4;JWo7RD(0y-n zelhNH&0imH6?x&OlCKnOpNtu$*2t6Z+Oqc@Uzk?@R-l0>qoja4YJbai#5&khzC z(T|l+n3O`bwY5u2OV2G1gEE?dfk#AwVVUi~8&0!$b;7+~Op2I!@L48ap)C3Xst@uH z+H>Mv-_aSDD!nR~nQYmU!07{)2)2DC&TKBq{g?e6K+gCj!>Y}YDFuLd@+E4hSScxi z5*26^fP-?(VKaagU>F8+b>T*?2aiE`gMR1@2m>s(PG053l@sf9bUl;!UCoXt4tPsC z{D(5W(9_EY4jb}0LJmJ&P`R_L(VQSr7%E^=>x<|-FD??L#$@8Vi@_;u>(ydJNHUHi z?-T$aJK1q4BgmPeLWSKfua!0jviBHH?whcRH$e+x1Xr~fnRR!q1RXr1I+^NgGU7Ud_J-n zGkX$0#^}9!;D1@zfOfwQBQ4esYz;U)nK=PAHP3Np6_D(6l6*R1gy`ssoYBn;h6nPY zf4@9YWB&fpuU2&d0NQ}i3{MacLEZ=;U3~=gUL(NkjfHiYjvRSRhNZ?Jmwc{Zm~7A6 z=l8M{4ZuPgVCs6@NpD^K92+w|>zsx!Jn`S$giq0fI+)T9$_*>7^H6_5;dV-1K9lA0?M$MK@H;zEkl> z|8pB>z*bvz#zk9)WHdA=mfKeeyo|D$i~{%pz(xAjcV}aOFBi})V0Ui;6d`DOu+#`p zPW#cMO_yfA6`93_IGzqfP4k^0`5tLT)-{f1jyuHOR^37 zY!}PkJHGwTLm=wODIV$L>dY9X1WPO8K{Wwln%4!&tP&F9 z=o+{JlStLdN?O4lxu6EP)G$y#0=oe`JoEaoaEBjE@s7vzMrTN@ZbO#nvJoV(XdN^V zHP;YV3e87))zSg^%Wuc2;459fHuDs1R6+7qdeV1v-{?feSi*h^48_Krz@Q6Y<;~wp zrTVynnu=y2DbO@kMkzRTtM-0*W=4~B&Pc=2YzD&b_ha$1_REPv*{m{3G1L6ZqpcPZ zfvU4H=hb2mbp()=pV${uSm&oB<__rQ#Pr-;SU(gL*3@E+bxOy7W$ui!O7WHi&~W6< zkl)r!2fdNgjT<+{J;w5L+|*Y+pp_4Z*{46>CznS}c19bTlS%K+J5D~hepfejBqxYm z|Mi@xlZX+nyX=p?S14^`n5oI1wC4B<9D$_6=-s4Qb5mfUS>xrv<2Yl>m*l6LqfCVegc_$__|--}pwGuQYhC6S$b-FV2{P9yBU=MHE_mwquqx!A+*6yH9V;^(X3OK% zphoXHT1L)b=$n;D?@pMVk{9OPrZM@cxm}4Qs&@Ofzm+JNY}X*>{L3$j_;}#?K|%Cr z3qUB2!_j&m&CY{Xx%6{@Rx`khC3Z#GE$gX3Ojq!1(0y&v9tycGn5$cOJL^Eb0N{Lf zJz@WskR;R9S=sdTbn||wIXcbSVdCYPA(s67d_Z=vvQFhY`Ke8%K%PfZ6g-gL{-DT} zU|8dE%YMuwpvOhTrzafjUV9X{A5a+_u6D;{%Q77c0w5aX+$|E!bVdGq+pRO5sDnu% z>P(>8eJ=i@dLQ`g_ta0FoA-}{kDRfP=W3;?$y*c|4KL?VeMngVof7&`EUd?6IJ0 z_e-);A7Ahg<~G~gUXSiLk$ZA~mWH8_GFezuD2f-(9UcB!hTV)m+>hEU|5)ulPk(3Y$kBQ-U zo`!yVFBhB^-EBS!Kx|a{{DAjhM}HTmtH4jzkWu=Lv6C6Eri1lj{uMvJvaSal*@>E^ zfkJ=xp7QG#_`fkh-$sbD2jzukH`y1D0PF=lG*%#Ha{!9Ud$(A~u>8&F(Sv!qo5C0c zzJ2Zhij(hu*yr%H6Ay;O-=XG)r1xXKiMR;vDVDz!4YQX3Pb1UGZsDY5q|3$pWSVdE+<~p z0C(N<=StP*oYPI(gl(({~fLNwdP_3Xmq>=DunPc`>< zY89JksLvD>B7I4eq3&@|NQl?{A#ttb4n(8om(6+&jwN^&%?YJ|*R*~Ot@0cFDV3%M zlEv}rrAwH^yC~e`eqL8^ zldt7G*Vz6SExQX<*%v#M?g`V+#CPJyufC?$;P6qXc%Uro!e@^WVMw!jMJxX}$ZPxS z)!ogjq&Gx=jdOhamsGq<#&$h$uNP;Dwp)3dUAyxt!ly+57Zdd>H50i~%Z@z3D?<(e zr!gFYh}cosl!=TFZzoOJH2KOj7S0JJ`Z4V6{0fQ7$7BpGQ{Radk;01&zHJyUsA8tMD9?14f=inqm1Ld2Wzkr{(4f0GOc9p@G{NL!Aa(L1=N~FxyOk zEIkqg-fmkqh^8Ee>ugJaU=8nbz)m$?1*tnV;2byicDulo=D-$yeGCN1f4z9^mi_Ds zIK(Pun%O{64BZ^b=otM=$Do*eZsTLPWoU> z)Z@;^IC-oyx!36q++%W=XQ3fCq45uz)z#G%0Wv~qWIwk@?%p)lJjggyRambJ9-L{? zI}Q$w1je{kvr*(zpjGcH9gGwlfdgGbIxy>x$R zqZ`=I=oezKzBteXJ$3LK-a3-s%u=bq)kXG`2h0Bai`0bMb*O9CK>93`U>p~-QNLa( z)B&3`zg*9&)iPHCbC+w0A|H%Pv%i#HpDWot*r+cnB#@sQ$<#z*0u4@*+a4ze$PK0L3#i>acP+4}(gIy}y+?aQg|+v%A}7!Uqm zDaQgiV^LTLy+p=u_y2uwpApDd7pYYO}hFxVqP?eliz|B^N}=S77Ly z@^VS+F?t=)J>|W+VlxEc&B+nJL&-uLpIA@~44Bbjf#e64E%4^~=WR-_H9_NtIzIq% zm*Uk&B|eve>csvG5dKU+cCxUuM?jaC6i!amZgm6tm_=e}xRT$%(DQt>DC-Cc6sY zxcS9J)qXJ>Nt+f%0Ud<y2-<1&+GSy{kUEYs0EXZA6} zVZ?i}_qw+f4g}B)ay;#d zBUYZ>SA?$kug&+6@0%4>hRwc`S30?`nSr-#07w6Jz?NOsL(pB|Zv?qKSY{vuieK6l zKfBXWk`~Df!45OR@`RY8B3DUCNzT~A@`U8%$e^Ggax3P2{g`TwY_*s<@098TXdS4d zZ)_YzuCbEYc2vE*yX+^ImMD(!t*tHcBQI1l`mt9ho*cB=2Hq;v$!!9KKfs-3Mis4#+VL( zCP_0O8YX6DbFeo+n%$}R<<|FyRP%MhLE$P6EFW+~pnVTCfHBUvTmhD`Wcolttd+lZ+tvuSTm@alk=sOaa_j$mF&ZsnE-_Ac$e>vi|y%WR!ot=xeRg_`=v zVnHBba*-Uw1i;-&fCl(G6~EeD`)=LSOFWc}=c>!K!zgr)k1{gkzk54FIc#oj&fMQ$ z;o?ixySW3|1GYe3m}*MIFumSdEEv{g2I4w@YzMgz10d2m9Ep5(EoZ=1OkSR2b#;|2 z1Rx77;n;LNLFFR72*HlQDZc~X0(tjv#+!4%RstxBppZ}#kP7&51Dq`Ihf1#>%u@Z9 zEQYuwE6XM>E?(p?Rt^f(PB%!Dr|r$aZ82F{*x+tk*x49^d?pn@*b8<{CAoHAu{%X^ zf{@!;2Kmh;NCi+RlJ#7MiiNNEos9u4o8)$^wT+GD4eZ$1kPv0m#L*)27BjGGP$;L* zxU=xWJnM;`ZJ9v?91ioPlrkYgU|#a7#4cZUYmX8X+0{;&6T5QdG!Vhhhr%x<_g|A| zn4Z4xi#zhfcsSI;$47>&LC6$&_gisu-t01$2Q}$uTrOOEIrH0MhgQzr#RBB2!Tk|} zqWFc0-N-sr2&fYV^K=wfV?at_Zj(bKyqg>>?UC>yejICMm8j0l9hjE@0vAxgVBA6AzAKE|a2XEWj+Q^UFkCh8eZPBWg8ARgocot61f*ocv zV7AUZH)18-R>DQ<`8i=r_-agH&GOZ8S7e?0kct1+4F1z~nlgJLweT<(4^O)Lkkqz6 z4>xDP?w4SX4^^`Xn5i#MxpHd!>+)^H?fSEohuq3o>v$vm3s{ZN${3NlH4A)>#)P(~ zpE&B*NZU16@U|6rm9Sy^p8F8#J=ZQ_^V3rWsOKJN1F>Fb&DY`c*Dc%L@vZaoEJeFc zX6ukVTTV#rs``FDLMm!o-aloa%3_j|8`q38Xz9cxBp87qp4j7>ps2v7JYd0q=8eqB z$$1`tT$KYYE~C}j2T&CPA z^7q@8@iT@0_=r50*#%%i`Y{>HRHj|*ivDuo_1e3hd%(#Uj2^s?0Ljt?!3??jmHn(~ zALzDj2qiR-bTOd4d8Nbf@IzL*e;)4t+uO$bv;Pg1ymaXq4iseFxhU&#%kJsXl07VP z{GCFH5)eq+(eJmD{{3yJjl^TVEDZ#1f{4V^&~Qca^r_hmG3NC)4!S_Mda?NT6(%f- z?<%C+DamJ}e%?jIN)2gl46jSLm1iXNPB{~KAn6X!6&>u zJ3Bj-H8hZIpPL$jj2ldhYiwS->+%GBF@X}HL*3+ajSqiL?F z-$Q~pL$sI(HuLgwS{hau9#o*n>kb8uY@4o4oj8m^V55 z!+=N|E>%k$jghRFl-r)Km_7GyjsI%!J9*IEVZY;Bu@|6Km1cv)(uuie3aZay~N2$7nN0*O((<_jRJ#+JcoCX=`pketAQdc*&o5 zt1#T9YWIWPDm678)<9BRWDOX&r^q>Ev{R@%L3JSPMxT40Av5NllN^Px35lYN8dwvW zo}S)$E;&Gd2ugJlx&z{t91^@oSmZMXdMaJ27+$u!OsoT3bu4IGD)qq2cU&l}!z4RJ zDsHC+oZ{NeN9EZ?J*8Sanoa2i;PMuXiOqH1vWQJt@v+D`MdQD2=iXK1xAXbJ*%-@h z%F*i~7mpRGtE)G!b=vO^!;L)#M^ksIFjIb@GdHZou@;}XiD{^}YBG0qb#-oH)E(;U zrWUT>O!HbQY60Hm^P@enOP35h_Z%wxE*tMH>L#xk1O%8s@n}UR6XMDd=K)aO!I0nf zJAyB-sK=MKR5)TINh|M3rBg*z4cnT&OXyTRyk7eE)3b69(mSbfTiHoN!-zfwwp_m% z%~iEq+9LUwV~h%2qY;%<=4fMc;Up(}`1^+s`v%>BL$!$A`xMp^b?a8)&F{x)WP}_% z&6XJQY&hjycWMM@`_>#fMNDahSO;B;4JT!no*|Rac$4_8GLqpqIS9c@a^NlNf zb`E8PTcj>3^-_tBv<3#tF4G~*kNut0-}n7Ub#)Ih8pI%{fVSi7r%4vJRBJyew$|50 z_+cqIx8?+}4l&8WQTN=e@77XqSEFb3uZURa=2Xd`|K`U4R?o>TJR_V#e%l_+QE(lN zerk@JoQSpX zja%m134S{DX?Rl~1E8(J=s(tMflD#M4-}?In|Ik6uZjZ)(rU0?Rsa~2ChxfusbvLF z;g+qrR5opZC!|Fmv==>m=zy=%KuyGamt4&?`5U0sDav7N8~wgep?^DSuqr-&q>>~+ zV$e0lhgB~Y)-N*R+cf-TelRtCqqCr6MvAnHL8rhJ*{G?h^Rd>+H8bV1QxiB}!-;i~ zn(4Ip#pN(Sv$5U$eiF#y=;&x)5^>L+QE_YfPu~qElENfOjZ`obnXeK+AdpzX!^54s zkoB2giW>H0185so#~Mz95d6a!PRc4O7*yza?x`Ch)n|-dzJ#OcQ!BIFjq|(@C~oy7n)}y_a|*4sH4xo=x9X{Y z-S}Dcxh^S^YNa1w8^TcApK&do^{W&2zbm-P3HjUeF!`;1>v5kk4ri=HVWe*Du8Kh~ z)Rvz9DVm3CZ`Er?!}zqK^E#v5B`c6j7&`8R4=YI1I&DiS#{S?W&D`8dw`e<76^OB^ z5#}wKW@^Y7plb{tKYj}>Ag#%_Dai*qf{uUu)NJXK5<4p!yr?L2xHv<0ayv$<`Sa(- zgjAdW&91iG#&CsMl|i^4c+|^_f8zu$l0&w`1PmF=ug8+5s~C*=HxVXcz}P}bX^n7OO`_d ztlRHEF|g9E`FU%GJ5uj+exbZQ8F>5L|2U`lAu-Zboq)V~Hs?)FwC-Ni%Gc4&yTBAq zPE?@6DlrzfQZWlwyxiPVyQ>?L@>J_3lUR$o{V*O_b_Q`xB}XThoa4MyJ%3wJNG0cP z*qt2qpbzbdrv`2dwz#Z&3F=<#nYb6`QpFCSw3Z;#*re>irtB@R3A#m8RaM2M#7Exo zG!e8g(we`ZEW{nd&Arlhy#4m%`Jg+9JNc~9b7Ib3mwqc>R{^hb!B7;L*qdDwwD$pC zpBK&^nPGc2Y+@|^*<5sfEx!GzT|aob@#d}F zi(HaXAX`GRvxm>*@f|ZV*VI&EIfGXQ`-~0;r?bm z-n82Fr02*Z26p;a+6_IMH#ZTZNJ`O`Lpdbq7N%-0GwqaNTKRUD?(N(dmAl14&P&60 zF}EpoMvhlsuou8gKoMBq!b4h%?XM52C@qaijcdv;2nh=}kAJxHqIyTea25O5)wzWk zvm@Amefbgp%ykDiwZ+BI5wv*E7>paVG_x(cTUur=kFI+Jl%k0k9L{8Q2Upa>8J_4= zUsW)QDQr*x0ci>ct9xExm^US3KkXj&8_E-8YO=D1gz?Dk0~Jm*`gk@5oJZwUSgv7T zm(2PmnnopnwD6HOPZ6mA6Kps9E!`*BNH0oVq^XXEy}+(Mb?ZwqSdm6RZGVYS6sMo? z2A0jXawuGc_&T`7?U~Ma06B1j4&H%#ur7(AJQlNsQq16z`|v!bzjY@iG0|>wZyWRt ze7klPPdwE#t&?@0Qo5T?>zxdz^XZzYnL-i!>lxvDTZ-&q4Sw^j`g7Scbl&%i_Vb3w za&>O1lk6d2kN!>O;5%Mi$3d0Z0e3)?ywW~e^lpKy+A~f3{rZZfb+X1D@7rb19``FD zwj8;aehyLm{x}Uy3;3do`l%wM@2t23?!cM7dOolN^B)!kS-;Zj;f>Wfsr3k@~P8Q)lCQnNU$hg(0RrB1w^b2n~o9atJ9MISBCfam%K?nN26S7GP!bz*}khW_eiM*oRM1A*8My47&^A=F0DV`t=% zr@C?;_60-^qvBfDnU$Do%uQS~n^Qy$Xh>`_C%1x+QBtb;`@l|Q00k2^f)8%Kd`jm^ zve{kGuwpl``pNji#e)T49+Ou`&f(IT^v{Od3Mo2FXh4g3I5*Q%q0e2JsP(7yZ-rPq z-dso}E&%Atccxv4v%jUsw?D*P!@TP>=k(R(LN)-Y_b7cY@mQGJ$i4W(8tL$4h=oZ$vL%+G^+O+PZ^-KIQN~**wvkX93wa z_#!BJKuu`n2sVcXslHG((z^H(P<92B zR#rb~2S>UCV(-8`Sy@?TU8u8r2W;^iTwy!1U+7);W!F>*7p{tS%T0glb;1{eN!;Mh zl5fMlHkL5`=8T+Bdx7}Du5S*t7(S&dEx3eln~2C%Vi$#eu#?$fc-9}r$`#I z@Sl?bKjzBcbpL%(PX8eu`t-V+gR}I%H6Zi?cN&XY&Q9R1e5R(55Pl^IcL9#~KiJ6N zqhyMIf&6*<(0c_=Qz&D|KX0q%rkYA_SXQV6$g$Urcye=_DKv;$qI=_7QJft;CPQ-G zDJ?zeDi{T)lsP)OXp8vm6Pn}~gy*`07ss%hcr>841DX>iCnrJEk=>ZjXf|tIDjKH1 zMfnP^t5yd0LM%jgTx$7u_U6NQvT7Cn_B;RElt7W}POjG_Qhr=}p$rBJa4=p#YW!V- zhu)lH-AoMmJ&K8D8^5XL8uW4vPQknjyxSeT8RS`;?jY}Qw`&}U3{a5Vao^mMYN*Os zm2ye#LLysgCij+uXGxpMo{}T_tb=U(3N9Iyd0p`F$R56TX{cMTk5OeRW2CUDVhX-^ zthmwVYfMG$dB9@d_I3ctmBL05{5&RyzUrX82a=qTL#uYd5=~V?VsidsME97g8!G4S zR68%*z>ey4g3k;O-cS6bFvKDK)lXKS6N#kOD2>NZ%vb+d*YVMp6ZA9EtXiWS(eBAx zS*5boQ-3bCFB|PFA2=AuFhjzzqO~R-htm}D`Kpz*Fyfg6otcf<@q@7-$*;jm&fYGy z_~A}}=PUG9kXYOV>MP6e?~c_Anf#vaAQQE)xuCC@+-q-x~1(O>4f>gnm|R>9ub zVw;tS8+uVh343PAOalfU?ljtg{(QGzFcZd<6V}Ur{biyHhghkdnTJ2#5=q`wtN(4k zCj`v$$@y5$fhvIi{TDpi4JD}aOa};3iKBf;btNUl)*R4ARh54@16B@>vj3j#+6;)_ z&Ejq*iJC1FL$(T2ee(&$A@u^>!T$1T(v{nkk}71lUx(Q&e)}#$yMd+Xvd1E(FI9fa zbsEX-{~5{sTVak}HQ=62?_sYB$P+g|g16~Xt0PbR<>4VITs_|#-0arAUA_$~h<3N1 zmEn++?!9kiqj%uyhout&l0L0jao77{2~>LZL%qXo2{{@Peyj(F0g-H&^)S;{V8SET z>6j-O#k@XumT41G#`9--pYo{6CSWKH7r+BmCF?~^p3*uE=f_61R(J1ekNUZ&#H3dg zc&}21vp?Ad6mQuH$wIj!^CR0R!EBZzRBm;s&>XL;Xw`5Q*zb0r0_>o;EcB|XxH)Bn z`QO2q9u10V(s}`Y&R?ewht~VU^=!;CHMjp)p7kNpXBCYoih%_(zDVG#+KZ%fCESqP zOQh@2&WiUFHET)aE^nycI!XE1@LB>*k&@Dy(diynEyO05a_0n>7-{`^A;Flb$MXi_ zQ=!z_@axA^Dmnuv-zk7VSCgt?E}yT)2hCbvBg*`BkU*JAfb$ELK7Hp3p`qZWIAz^# znb#H%i#AvP3$B@t4qyhdug4-n>FJis%8PyoMrEdahu^XDABE;0B6d};Enn-~z8=4& z>snAR(XenD6(uG2jtniVw|CO8|Mlsnht;!ft8&dPe2ZjX&xcI45Xymvu&|DfX;RP# zq)Y!^NQT?4YmYb)m;O!;PpTsZ@pF)_y~uJ54SG#t>@YNe4OY$0Mzz?P?3Co%SanSV zkYdvs8bsXL-hJup?gl&>bmCLo?JAUT)$~(CnE)QlaHqS^T94D^e>!X~zPmESt>Nv? z#0HT@m-gun`l9uCDV2rIxdeGiLbmT_iWl#$MUiX~L7q2`b4t77`|EmEr%#9xju37b zk5ArDq=?_%63DSv!Vh-8gPty9f=+)ZK0vhw?1Ijy&oj@DaQL}nz*hqKl>g{wt7to} z(F3NenewSmr-949zZF^@K~bJp;+GlCay(2%W5g&QatppA{`jq-aAYqYDJ2Jr({XVj zBP03l1GC)e|gU@tiVo3 zHy{+NTsAl3Y_@YEnwe_wozZX{1txW&?D~;EU=SVfojY&0lJ!zznW@a2=K_oqqbSRr z|1+rn@c07%^SZ-JZt|u-rVC7K@1ObE2u60f9t+0TXlK) zUGdqRA0?)Tu6|J6a1t`ibfOd9=^SN3B7Za-M#F(&G!YCyB5=K50bIw%e;;&5z-SCW zB49KeM#F(&G!cv@g3&|(O#`EuVKg(0W`@zs01ScARyrgZjE2K#I8Y-q=!$nAmFYiT z1zSDJkbmK0#hjx_hNpphp??3}cMmqpeL#B4{rBlxqY$GJtVaEGibw0n&)%pFm zE-x?d6nvS-pC`b5qR$H~&Kx~@v_IWmX&Nvj;`i0e{Qdj)&9`M&-C)+$CGEbO2lU@F z;O;%K?xX$ByB~k7`1AK5aBJ~T;E`y1>i^f-)%}Ucf$h_Ipk7j3Yzz#6V&Ez);GWLk z>&xpqBGS_M+7H+K{+2uK^wXMOUtS*H-ww0j!TqY*+PT29p)BS4KmYvv9Jp1x-s1Ce z!PEI=yYJq)ckf)<=9&ERc4w;g{;SW2%~U>6|M=&R4KNfw|M+1cE-t?LZr=Y-Z|=JR zy}DKhcoO>N+i%l$#(=bbt+EAf;o2Ox{{I&Eq}YSpoA1AW{`AR6Utj<8moFy${r$x@ za_PJ8o&#=Zv^P`xFR}5@y~BqO0~a>e#>K^@?Z1EiVZn_0kCreu+ph$M*6OQSK;Hn* j^#Da;j@j)0KYzzFaKu;LyKKI{3#8K1)z4*}Q$iB}IoAhg literal 31964 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 YA~V*eCE3e5#+{4lDGTGglg_{Y2V>Ev(*OVf diff --git a/packages/devtools_app/test/test_infra/goldens/memory/load_offline_data_trace_tab.png b/packages/devtools_app/test/test_infra/goldens/memory/load_offline_data_trace_tab.png index 97737a2505359b3046586e52a6dd2c469087b67c..bacc8c8b52adac28b8d9c7ee56c5f7455833d622 100644 GIT binary patch delta 26022 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 AkN^Mx delta 26324 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 PS{7jrd;Cm07;@$R!Mx0{ diff --git a/packages/devtools_app/test/test_infra/goldens/settings_dialog_default.png b/packages/devtools_app/test/test_infra/goldens/settings_dialog_default.png index e394284c04f7979ea057798494420df87d39a50d..0d5ba8cb7b143eb11a22cd82008f6c21d4f82617 100644 GIT binary patch delta 2906 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 E0|A^O_W%F@ diff --git a/packages/devtools_app/test/test_infra/goldens/settings_dialog_modified.png b/packages/devtools_app/test/test_infra/goldens/settings_dialog_modified.png index 5439001a8accb58cf486fc5a3c43652fe2423e6e..d73e69222e11eb2a6972fd931062ef6629ad042e 100644 GIT binary patch delta 3233 zcmX|D4O~)J8^7ktwoGTWtk)r}EbXn#rD@`4t>#G4*2=Q-D^1iy=LZ;maH+PMuT2+} z77DoBv^2$!!WT(VTXTv^=Fk+CQq=q)GE@RF-*a#7y}uuDIQKcv^PKTb_J@2i zzUJai`_M)L;b6w4oj3m29zT?`zhJ1U(r(jJ9Bp~+S*fpA93C1!6$`u08;0X-+^){{ zOPn>2g7Aw&>U55V%27ABjIdR?p?~w0v-onjwBx!JccJ@A+T3Xih86LBUsFF#I=!(s z&cFQ8NK2Z!ksCffw4he{aq|xub+oX^Oo4(YuWv}0rHYXcu6B&*o){Keul2?d&s3g0 z)LkCvQlZ{)B8YRmv|M??5~3$KIS>-l$txjfgCpgv0R#=s)WLFwx4UK`4OW&6tF>bH zTZJa zM-}zW)}Nh3&0cNax*mdF?0TK5pWQ6(2qbmi&ujag8(iG540-SA=j;oTxNutI=6>5l zpXpUic?^p`*@>>5$zQVyf-1bS-8DzaAE8rMei;4%9e^*J;y-|ouU>B{t}Eu18zR#U z-zVgM3PHw#ExB!CkHwL3foi%XCa+IAtE=o>NSOP0t#d-lBaQ+!4%uf@3D$ra*RAW2 z)zD!y879+m&8G7uz^1`2S~jP%>N!3JUJiDzCUl(%#({;gQsD+y9ws3#>CN8wce z)yVXE?XdHk216H)s%Fgom3E#~FXs?NBVUT*#;z(CDD%{piz%V%@NS;`7m|#xijU|u z^G^K3%)5B6`78%y<>)Gk&t6QAiHXg^MF*_k&AQcn1^_j46p)C%@l|H99!@}sC*hr} z+LHrY0bTqzN4Lfb8~|-$ACJWMU>1j_e@%-iTk^PsKYBD$j2I?6`)^neaa-pS(9I# zF!iO^39n!McEK)ZqjHqzj5wwXx+tpdHc>5=`H%VW>d*F70it&ms}~T$Ls0EZ(`btW zp|GLJJsvD3g3v#~{KP%$h=oLpk}$B+?ZrM+1O-Gs zNfv~;xbe^APar757R?EU3gUJ-E8MiLyMkXuQs!PwP2K7Ptk6$SpZWehHi<(5jxv79S)6U<#&E_%kCoNH=YzG_ap*Ia|OnCz_ve7N8gaoh;mDf$3z zY=*Z;!Pe>Ns)s#6lhL&3=;(s6VCu-tn7$cqV7q3IA5Wb;PeajJaS;(;n`h!^+julB zDJiL7jGHnso=@o;#~`)6Q%p@^!y~QY>Zq6U8eIn8n7Iy zAZD#ag$~9A`D>UNW}h+BvF7m4$37(XoT-%65XCv>E*va|&9=JD>g$|l0TigS(lSFh z`^Q!0;jjAz7zt40jKxyT2is_$0Y{!0+|-EUrD#x4GJbi!E{` zbS2#+PIfPL%#ma`j(mWBTl&N;#myr*W~X{oDW85M5yq)+@z|;w)mK14iygJ;!NB(s z0;1B00@Ke^W8N$7Wa2nj3kz{nF{jT-?VW3xBYdq(X;#YxZu8ix_+itl|MqjL7mi*m zSI0~a!8lC{ZT#8exAR!-K-O6LV0vD2nleq4j@9kT)+To==K+}XXn-jbHp2oWH!rCj zNRX3H9o^XbASz6vN*uY#%{SA4WHyAOd@+pZDG#K^i!%e;(bhNPfNm~YGgI=UQ@M}X|N^$?qBMWA*27Y$jjrG`8N6txd4dlbJ^$_LFYJ6 z+&xECTyHK3v%Bo7e-jo^pB6wi2EmPPELj9Rirg%eIr@31W60|w=*3*BBS{u9eJ5kW z1{@-$`;bEfG{$@0yX)<02KhKmfAzLvPQqC}Ngfh}$uO{YbaXQH(4VB#kZkMTHBIaT ztFqDd57bP4(`YopD&_sPD$lx_ws2))pK$@7VEgFJGM5SftTB4dfS!~2By-yhaJ)dz z3j+`xeRw>X@tY!;N3iKk&L-!j-(CMN3&az?&9RnCYY!QFm zb9ws#^g z4k##DQ|w1QG5Ix7()xGSKp;={u(X{vzqgAY8}F2!I-Q zA62_wY6ga_0Cnbd%S4#|uf^jSF!6kgsK)>*pd*%lzwwF(1qr6{3?WYggl%_UW)DHo zQ<0-TkUl;1H-uPwk@^mTFydPXLqfS&t`|8XY@(~fLU;reap!%2ba>zpb!<6 zYk}u=k*o+WMsaB(u#TI)v1}C#q9Og7j?*Bnp}{6q61W}QK?0EL1Ch)wtP*vB%)a>! z`E%vCj89+?@HxkbU}Fp`4?;p@mjj6mD!bup#&+*+;g9Gu6Z!7UxQLKnCG)u~o zg+se3Bdr8RL;vcx9gx)%u0SxFxy~nv@)c`Qx8L+Xb7(&&1dF`_Zn;GnkW_q$!f`h3oJIbT*l{|01(kPMyE5FtRm{~IH0mOBD7|v4@pATmO{MA z-3}PwY~QvcZr#c56GjFQMC(QSN5g5bwKELO)`0KWNJIR^i1EnpA{gnI2tj7eXowd@Rz#Nrz`rgRx#5LC4@mP~_*m~fr;x=f+Kw?iVp*ec2oE4tn=ioD4q_Dv z>|2Z&a6c!UNVWv{LPCa~z|ibKR2zZ9;3{4K|YEtdLqswo(;8549%e74@FNfV;rEMU*fbf!`hkInctP#?TRUzfR@@LJ9LB%G+lBdTNSVH+>?h)8={TeCJ z`=38wkoh=L+VRmZxBFhG=p=P)hQ*$cyFt&l=(l)5A}7fHd~)CWUq44 zisHE~sHruJi;4x#C}y`|Lg*sA?3k3F&+PJoGt6-{lNosRAJKM}IO})e^ z!D$UIM>(DV--(Sd`a3!lYaU^k%HfT=g}>;nj=nOu@V!C-?&!$o7I^V~7fo{#BPx%X z>M!sqBX@~*`_m{VicYspVIgRcOlAikr>uaWFKnZJGJv3-sps#yI96m0t|kob&QYc$sPLykCvr`i;Y~`FiJAMVjF~9aREP2z#~&w;Ooq^BKvS1snXNR%KD&* z-`Y#%4QoGM|6a`f=Eo59x}J^d-SuRwr#*Ol;m&FGi`iAX^xHFcW!E5xKKE4Ka7SC~ z@64g3`JI3R03cvmarYG1)5U4k$$92_arD+LsE_n-5aeQS36A*U5*MqPtcf$xuP$RD z<^rC5z3->sMO~<6STbh_!2Ns7xb7m|mOt=Mo4C0xS29>a}+a z?$i6mI==SPtwp(pVDaiBlJq!^oF@W^s&dlOvb~R+0HtNOGFWX}2=Ltzy&@D!op-xE zAQx6V%#ySd9QF{ff|@Le-mngc#43hHi7}1*FNH%Vi z^t8=ZHpDf&v=pdH8y(o=@}8cVWUKHAd+yLV6@Pa(2i7gJ8Nu&{d#K-D_@{{xYyf}< zqV(iunuLyZOQWz-esyZ$KloSV;7UPRw_}3H2B4}kWA&|H50l-IC8|mQk$%6s zI$bD~O?aGVr^m{N-!8x;@2?hIrEivJl2{%2!h3vD#EZek@YiP&RG3W=bkqgOFbEpT zE$$7Aw)T!Ywmu`~GUc;{rdS0B?(P`-g~)9bzdfDdT)D{R$U*eZN7nf3)6XTDPu`4c zw_UX>>EU?Qp^0{I=&M)T7Xi9Z3GyUn%wIs&GSPb8@yG#09AsU{i5Ppo@?-xJY!3fSd zGRv}spvUlHo&JoOTh~`_7^oATYGaB0;-;9KD)R2rPa?-kRUf-%Ntz2y99>&e$~RfESdd+`9HeMLTyD9Us>7Ug!;Kh@^Wa?;%YxuI8(DvWT>hq_ zD{i!xp}Ei%Kj$mx`&sG00lp4Je+U@R%}ign8iH6(+t$H*A7a1)TE)(8n4G*+uUu|+ z`I3J#f$LN)lawiz?3+CaR{_$q1=T&8R9C^dgr% z^(zfnXUtqbcmU!gwJz_|UX(l$D8vF)XUmZr7XS_q3#1w$Srf;RI^D0@P{~H(4%qmx ztQy}f=TK`TQ`*+nqXZ?g2PIv{b?6%~^6{a#z#BarkF=664w9rr?%|#kLx}E2y|iUq z2u9RGvob#m?YbqiHmt=F`fX(z!79l89DhDFR>w$Z52mfsw z&kY@H_nwCFpcgcNV$YMI4SA#|7bRw$R{+fI`;ajML4EWT2jZ!fK$EUxd%Yhw$U5td zsf=Z4#s|0chq3~~crk5!*oa3KfnhlQP+aM^m-6?6suJp31D~?KKpUmMu&ZshBHubS z+1SY`e-se=Z2tH6nca%2nKcv6A01`9n=inY4f2Y_CVQ}Vxwpr#0i*Xh-=KQo%Rb^! zYez+(zSBa;Nc?5+=u0q`)_UO%x_YrDO|N_WTV0dc8ZuUSpfJsj@!yl-GLH*MCN{%8Wc%}kPAW6`(bS!gp9{Ag;w zew+v|`!9#+OOW%AKEK@$V(@=f>`sDQqq{yp+}eXgG80zUfIjpw8=0Eu8=d?Nc90u0 zx5FEVMN2Y*9)+;GJ6u7gw7y1Sv&t5)Jj`6vVGp+Bv02ZSK=21UqNPZJ(&Ohjz}z9d zX;E}O(oHmzjvzFNw#a_KQ65QZAz=>O7y&q4m;=c;#zl5^p&`I?^{*oc_JKmPx_1H$ zz&XiyyYn%SGC`vKXx0UBv(JRFZV5!+k8}?DPb8@m{GWlcya*60dS!74ySLa7oO0Cz z!J5b;QQeso-1d`1FrW>1sD@m8JJ#0({H!cXMLJ*Rsdig}rMGVeK)LModF1ct5fK^V zLrY0gQ&!Lc=0=2vfM-eD?Mp(~&F^`TAhs7=+HIZj(}IyLFrba@lmnQ6bhU^Bt!|xs z-Faqd9B&oH>bPV&h7tsKQ=qu&-%2w^#oPQPY^VTjG z>7I{^vqLz9a4#lLf6S8D9Sz4;A>g?B$PlV|Jas5a@DKwI^nl8?d-o&1kVF1@TEj9) zQfK#YA~Qs}Ru%*N|0|cw?iX(1uTf<7^ z6tt5*S?Yi%8!XgHi$IekuT+kpLHy?s%mGWzNmb@Jnt8)ZiyTYul%Nw7Yk>I9J~0!^9VjVFv~oVj z4tAsL06B6p3(0R|U^jx*1dj@{OdLOgp6%m1G_)`;xDXHbI_;kKk)kg=^ oLoTiF#JUxqm(-#@+CcveQb(0rMWVR}zz&2vbmU;s{(ztV3%59^!vFvP diff --git a/packages/devtools_app/test/test_infra/scenes/memory/default.dart b/packages/devtools_app/test/test_infra/scenes/memory/default.dart index 2ce1ef5db17..f9f15a12675 100644 --- a/packages/devtools_app/test/test_infra/scenes/memory/default.dart +++ b/packages/devtools_app/test/test_infra/scenes/memory/default.dart @@ -56,14 +56,18 @@ abstract class MemoryDefaultSceneHeaps { {'B': 1, 'C': 2, 'D': 3}, {'B': 1, 'C': 2, 'D': 3}, ] - .map((e) => () async => FakeHeapSnapshotGraph()..addClassInstances(e)) + .map( + (e) => + () async => FakeHeapSnapshotGraph()..addClassInstances(e), + ) .toList(); - static final golden = - goldenHeapTests - // ignore: avoid-redundant-async, match signature - .map((e) => () async => e.loadHeap()) - .toList(); + static final golden = goldenHeapTests + .map( + (e) => + () => e.loadHeap(), + ) + .toList(); static List get all => [ ...forDiffTesting, @@ -154,11 +158,11 @@ class MemoryDefaultScene extends Scene { final profileController = ProfilePaneController(rootPackage: 'root') ..setFilter(showAllFilter); - controller = - MemoryController()..init( - connectedDiff: diffController, - connectedProfile: profileController, - ); + controller = MemoryController() + ..init( + connectedDiff: diffController, + connectedProfile: profileController, + ); await controller.initialized; diff --git a/packages/devtools_app/test/test_infra/scenes/standalone_ui/editor_service/simulated_editor.dart b/packages/devtools_app/test/test_infra/scenes/standalone_ui/editor_service/simulated_editor.dart index fb82ee270c6..41c7eeec437 100644 --- a/packages/devtools_app/test/test_infra/scenes/standalone_ui/editor_service/simulated_editor.dart +++ b/packages/devtools_app/test/test_infra/scenes/standalone_ui/editor_service/simulated_editor.dart @@ -282,11 +282,10 @@ class SimulatedEditor { FutureOr enablePlatformType(String platformType) { for (var MapEntry(key: id, value: device) in devices.entries) { if (!device.supported && device.platformType == platformType) { - device = - devices[id] = EditorDevice.fromJson({ - ...device.toJson(), - 'supported': true, - }); + device = devices[id] = EditorDevice.fromJson({ + ...device.toJson(), + 'supported': true, + }); sendDeviceChanged(device); } } diff --git a/packages/devtools_app/test/test_infra/scenes/standalone_ui/mock_editor_widget.dart b/packages/devtools_app/test/test_infra/scenes/standalone_ui/mock_editor_widget.dart index 7ebbc86602d..196401e8bad 100644 --- a/packages/devtools_app/test/test_infra/scenes/standalone_ui/mock_editor_widget.dart +++ b/packages/devtools_app/test/test_infra/scenes/standalone_ui/mock_editor_widget.dart @@ -136,18 +136,16 @@ class _MockEditorWidgetState extends State children: [ const Text('Editor: '), ElevatedButton( - onPressed: - editor.connected - ? null - : _withUpdate(editor.connectEditor), + onPressed: editor.connected + ? null + : _withUpdate(editor.connectEditor), child: const Text('Connect'), ), const SizedBox(width: denseSpacing), ElevatedButton( - onPressed: - editor.connected - ? _withUpdate(editor.disconnectEditor) - : null, + onPressed: editor.connected + ? _withUpdate(editor.disconnectEditor) + : null, child: const Text('Disconnect'), ), ], @@ -173,42 +171,38 @@ class _MockEditorWidgetState extends State Row( children: [ ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'macos', - flutterMode: 'debug', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'macos', + flutterMode: 'debug', + ), child: const Text('Desktop debug'), ), const SizedBox(width: denseSpacing), ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'macos', - flutterMode: 'profile', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'macos', + flutterMode: 'profile', + ), child: const Text('Desktop profile'), ), const SizedBox(width: denseSpacing), ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'macos', - flutterMode: 'release', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'macos', + flutterMode: 'release', + ), child: const Text('Desktop release'), ), const SizedBox(width: denseSpacing), ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'macos', - flutterMode: 'jit_release', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'macos', + flutterMode: 'jit_release', + ), child: const Text('Desktop jit_release'), ), ], @@ -217,32 +211,29 @@ class _MockEditorWidgetState extends State Row( children: [ ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'chrome', - flutterMode: 'debug', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'chrome', + flutterMode: 'debug', + ), child: const Text('Web debug'), ), const SizedBox(width: denseSpacing), ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'chrome', - flutterMode: 'profile', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'chrome', + flutterMode: 'profile', + ), child: const Text('Web profile'), ), const SizedBox(width: denseSpacing), ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Flutter', - deviceId: 'chrome', - flutterMode: 'release', - ), + onPressed: () => editor.startSession( + debuggerType: 'Flutter', + deviceId: 'chrome', + flutterMode: 'release', + ), child: const Text('Web release'), ), ], @@ -251,11 +242,10 @@ class _MockEditorWidgetState extends State Row( children: [ ElevatedButton( - onPressed: - () => editor.startSession( - debuggerType: 'Dart', - deviceId: 'macos', - ), + onPressed: () => editor.startSession( + debuggerType: 'Dart', + deviceId: 'macos', + ), child: const Text('Dart CLI'), ), ], @@ -294,24 +284,21 @@ class _MockEditorWidgetState extends State builder: (context, logRing, _) { return ListView.builder( itemCount: logRing.length, - itemBuilder: - (context, index) => - OutlineDecoration.onlyBottom( - child: Container( - width: double.infinity, - padding: - const EdgeInsets.symmetric( - vertical: denseSpacing, - ), - child: Text( - logRing.elementAt(index), - style: - Theme.of( - context, - ).fixedFontStyle, - ), - ), + itemBuilder: (context, index) => + OutlineDecoration.onlyBottom( + child: Container( + width: double.infinity, + padding: const EdgeInsets.symmetric( + vertical: denseSpacing, + ), + child: Text( + logRing.elementAt(index), + style: Theme.of( + context, + ).fixedFontStyle, ), + ), + ), ); }, ), diff --git a/packages/devtools_app/test/test_infra/scenes/standalone_ui/property_editor_sidebar.dart b/packages/devtools_app/test/test_infra/scenes/standalone_ui/property_editor_sidebar.dart index 8d1a8feccb1..6346811359d 100644 --- a/packages/devtools_app/test/test_infra/scenes/standalone_ui/property_editor_sidebar.dart +++ b/packages/devtools_app/test/test_infra/scenes/standalone_ui/property_editor_sidebar.dart @@ -66,17 +66,16 @@ class _PropertyEditorState extends State<_PropertyEditorSidebar> { Widget build(BuildContext context) { return IdeThemedMaterialApp( home: Scaffold( - body: - clientLog != null && clientDtd != null && editor != null - ? MockEditorWidget( - editor: editor!, - clientLog: clientLog!, - child: PropertyEditorPanel(clientDtd!), - ) - : _DtdUriForm( - onSaved: _connectToDtd, - formKey: GlobalKey(), - ), + body: clientLog != null && clientDtd != null && editor != null + ? MockEditorWidget( + editor: editor!, + clientLog: clientLog!, + child: PropertyEditorPanel(clientDtd!), + ) + : _DtdUriForm( + onSaved: _connectToDtd, + formKey: GlobalKey(), + ), ), ); } diff --git a/packages/devtools_app/test/test_infra/test_data/cpu_profiler/cpu_profile.dart b/packages/devtools_app/test/test_infra/test_data/cpu_profiler/cpu_profile.dart index 23f3e500d44..df193d74ece 100644 --- a/packages/devtools_app/test/test_infra/test_data/cpu_profiler/cpu_profile.dart +++ b/packages/devtools_app/test/test_infra/test_data/cpu_profiler/cpu_profile.dart @@ -678,60 +678,62 @@ final goldenResolvedUriMap = { 'package:flutter/widgets/binding.dart', }; -final goldenCpuProfileStackFrames = Map.from(subProfileStackFrames)..addAll({ - '140357727781376-12': { - 'category': 'Dart', - 'name': 'RenderPhysicalModel.paint', - 'parent': '140357727781376-9', - 'resolvedUrl': - 'path/to/flutter/packages/flutter/lib/src/rendering/proxy_box.dart', - 'packageUri': 'package:flutter/lib/src/rendering/proxy_box.dart', - 'sourceLine': null, - }, - '140357727781376-13': { - 'category': 'Dart', - 'name': 'RenderCustomMultiChildLayoutBox.paint', - 'parent': '140357727781376-12', - 'resolvedUrl': - 'path/to/flutter/packages/flutter/lib/src/rendering/custom_layout.dart', - 'packageUri': 'package:flutter/rendering/custom_layout.dart', - 'sourceLine': null, - }, - '140357727781376-14': { - 'category': 'Dart', - 'name': '_RenderCustomMultiChildLayoutBox.defaultPaint', - 'parent': '140357727781376-13', - 'resolvedUrl': 'org-dartlang-sdk:///third_party/dart/sdk/lib/vm/hash.dart', - 'packageUri': 'dart:vm/hash.dart', - 'sourceLine': null, - }, - '140357727781376-15': { - 'category': 'Dart', - 'name': 'RenderObject._paintWithContext', - 'parent': '140357727781376-14', - 'resolvedUrl': - 'path/to/flutter/packages/flutter/lib/src/rendering/object.dart', - 'packageUri': 'package:flutter/rendering/object.dart', - 'sourceLine': null, - }, - '140357727781376-16': { - 'category': 'Dart', - 'name': 'RenderStack.paintStack', - 'parent': '140357727781376-14', - 'resolvedUrl': - 'path/to/flutter/packages/flutter/lib/src/rendering/stack.dart', - 'packageUri': 'package:flutter/rendering/stack.dart', - 'sourceLine': null, - }, - '140357727781376-17': { - 'category': 'Dart', - 'name': '_WidgetsFlutterBinding&BindingBase&Gesture._invokeFrameCallback', - 'parent': '140357727781376-16', - 'resolvedUrl': '', - 'packageUri': '', - 'sourceLine': null, - }, -}); +final goldenCpuProfileStackFrames = Map.from(subProfileStackFrames) + ..addAll({ + '140357727781376-12': { + 'category': 'Dart', + 'name': 'RenderPhysicalModel.paint', + 'parent': '140357727781376-9', + 'resolvedUrl': + 'path/to/flutter/packages/flutter/lib/src/rendering/proxy_box.dart', + 'packageUri': 'package:flutter/lib/src/rendering/proxy_box.dart', + 'sourceLine': null, + }, + '140357727781376-13': { + 'category': 'Dart', + 'name': 'RenderCustomMultiChildLayoutBox.paint', + 'parent': '140357727781376-12', + 'resolvedUrl': + 'path/to/flutter/packages/flutter/lib/src/rendering/custom_layout.dart', + 'packageUri': 'package:flutter/rendering/custom_layout.dart', + 'sourceLine': null, + }, + '140357727781376-14': { + 'category': 'Dart', + 'name': '_RenderCustomMultiChildLayoutBox.defaultPaint', + 'parent': '140357727781376-13', + 'resolvedUrl': + 'org-dartlang-sdk:///third_party/dart/sdk/lib/vm/hash.dart', + 'packageUri': 'dart:vm/hash.dart', + 'sourceLine': null, + }, + '140357727781376-15': { + 'category': 'Dart', + 'name': 'RenderObject._paintWithContext', + 'parent': '140357727781376-14', + 'resolvedUrl': + 'path/to/flutter/packages/flutter/lib/src/rendering/object.dart', + 'packageUri': 'package:flutter/rendering/object.dart', + 'sourceLine': null, + }, + '140357727781376-16': { + 'category': 'Dart', + 'name': 'RenderStack.paintStack', + 'parent': '140357727781376-14', + 'resolvedUrl': + 'path/to/flutter/packages/flutter/lib/src/rendering/stack.dart', + 'packageUri': 'package:flutter/rendering/stack.dart', + 'sourceLine': null, + }, + '140357727781376-17': { + 'category': 'Dart', + 'name': '_WidgetsFlutterBinding&BindingBase&Gesture._invokeFrameCallback', + 'parent': '140357727781376-16', + 'resolvedUrl': '', + 'packageUri': '', + 'sourceLine': null, + }, + }); final subProfileStackFrames = { '140357727781376-1': { @@ -1045,58 +1047,59 @@ final filteredCpuSampleTraceEvents = [ }, ]; -final goldenCpuProfileTraceEvents = List.of(subProfileTraceEvents)..addAll([ - { - 'ph': 'P', - 'name': '', - 'pid': 77616, - 'tid': 42247, - 'ts': 47377800363, - 'cat': 'Dart', - 'args': {'userTag': 'Default', 'vmTag': 'VM'}, - 'sf': '140357727781376-14', - }, - { - 'ph': 'P', - 'name': '', - 'pid': 77616, - 'tid': 42247, - 'ts': 47377800463, - 'cat': 'Dart', - 'args': {'userTag': 'Default', 'vmTag': 'VM'}, - 'sf': '140357727781376-14', - }, - { - 'ph': 'P', - 'name': '', - 'pid': 77616, - 'tid': 42247, - 'ts': 47377800563, - 'cat': 'Dart', - 'args': {'userTag': 'Default', 'vmTag': 'VM'}, - 'sf': '140357727781376-14', - }, - { - 'ph': 'P', - 'name': '', - 'pid': 77616, - 'tid': 42247, - 'ts': 47377800663, - 'cat': 'Dart', - 'args': {'userTag': 'Default', 'vmTag': 'VM'}, - 'sf': '140357727781376-15', - }, - { - 'ph': 'P', - 'name': '', - 'pid': 77616, - 'tid': 42247, - 'ts': 47377800763, - 'cat': 'Dart', - 'args': {'userTag': 'Default', 'vmTag': 'VM'}, - 'sf': '140357727781376-17', - }, -]); +final goldenCpuProfileTraceEvents = List.of(subProfileTraceEvents) + ..addAll([ + { + 'ph': 'P', + 'name': '', + 'pid': 77616, + 'tid': 42247, + 'ts': 47377800363, + 'cat': 'Dart', + 'args': {'userTag': 'Default', 'vmTag': 'VM'}, + 'sf': '140357727781376-14', + }, + { + 'ph': 'P', + 'name': '', + 'pid': 77616, + 'tid': 42247, + 'ts': 47377800463, + 'cat': 'Dart', + 'args': {'userTag': 'Default', 'vmTag': 'VM'}, + 'sf': '140357727781376-14', + }, + { + 'ph': 'P', + 'name': '', + 'pid': 77616, + 'tid': 42247, + 'ts': 47377800563, + 'cat': 'Dart', + 'args': {'userTag': 'Default', 'vmTag': 'VM'}, + 'sf': '140357727781376-14', + }, + { + 'ph': 'P', + 'name': '', + 'pid': 77616, + 'tid': 42247, + 'ts': 47377800663, + 'cat': 'Dart', + 'args': {'userTag': 'Default', 'vmTag': 'VM'}, + 'sf': '140357727781376-15', + }, + { + 'ph': 'P', + 'name': '', + 'pid': 77616, + 'tid': 42247, + 'ts': 47377800763, + 'cat': 'Dart', + 'args': {'userTag': 'Default', 'vmTag': 'VM'}, + 'sf': '140357727781376-17', + }, + ]); final subProfileTraceEvents = [ { @@ -1208,12 +1211,11 @@ final profileMetaData = CpuProfileMetaData( sampleCount: 10, samplePeriod: 1000, stackDepth: 128, - time: - TimeRange() - ..start = const Duration() - // Note this intentionally adds 10000 microseconds more than what - // was measured, regression test for Issue #8870. - ..end = const Duration(microseconds: 20000), + time: TimeRange() + ..start = const Duration() + // Note this intentionally adds 10000 microseconds more than what + // was measured, regression test for Issue #8870. + ..end = const Duration(microseconds: 20000), ); final tagFrameA = CpuStackFrame( @@ -1382,18 +1384,16 @@ final stackFrameG = CpuStackFrame( final testStackFrameWithRoot = CpuStackFrame.root(profileMetaData) ..addChild(testStackFrame.deepCopy()); -final testStackFrame = - stackFrameA..addChild( - stackFrameB - ..addChild(stackFrameC) - ..addChild( - stackFrameD - ..addChild( - stackFrameE..addChild(stackFrameF..addChild(stackFrameC2)), - ) - ..addChild(stackFrameF2..addChild(stackFrameC3)), - ), - ); +final testStackFrame = stackFrameA + ..addChild( + stackFrameB + ..addChild(stackFrameC) + ..addChild( + stackFrameD + ..addChild(stackFrameE..addChild(stackFrameF..addChild(stackFrameC2))) + ..addChild(stackFrameF2..addChild(stackFrameC3)), + ), + ); final testTagRootedStackFrame = tagFrameA..addChild(testStackFrame.deepCopy()); @@ -1529,10 +1529,9 @@ final zeroProfileMetaData = CpuProfileMetaData( sampleCount: 0, samplePeriod: 50, stackDepth: 128, - time: - TimeRange() - ..start = const Duration() - ..end = const Duration(microseconds: 100), + time: TimeRange() + ..start = const Duration() + ..end = const Duration(microseconds: 100), ); final zeroStackFrame = CpuStackFrame( diff --git a/packages/devtools_app/test/test_infra/test_data/debugger/vm_service_object_tree.dart b/packages/devtools_app/test/test_infra/test_data/debugger/vm_service_object_tree.dart index f23c9315845..8ad6c416cc4 100644 --- a/packages/devtools_app/test/test_infra/test_data/debugger/vm_service_object_tree.dart +++ b/packages/devtools_app/test/test_infra/test_data/debugger/vm_service_object_tree.dart @@ -43,19 +43,18 @@ final testClass = Class( ); // We need to invoke `Script.parse` to build the internal token position table. -final testScript = - Script.parse( - Script( - uri: 'fooScript.dart', - library: testLibRef, - id: '1234', - tokenPosTable: [ - [10, 10, 1], - [20, 20, 1], - [30, 30, 1], - ], - ).toJson(), - )!; +final testScript = Script.parse( + Script( + uri: 'fooScript.dart', + library: testLibRef, + id: '1234', + tokenPosTable: [ + [10, 10, 1], + [20, 20, 1], + [30, 30, 1], + ], + ).toJson(), +)!; final testFunction = Func( name: 'fooFunction', diff --git a/packages/devtools_app/test/test_infra/test_data/memory/heap/heap_data.dart b/packages/devtools_app/test/test_infra/test_data/memory/heap/heap_data.dart index d8392e640d0..7d955a9fd77 100644 --- a/packages/devtools_app/test/test_infra/test_data/memory/heap/heap_data.dart +++ b/packages/devtools_app/test/test_infra/test_data/memory/heap/heap_data.dart @@ -23,8 +23,9 @@ class GoldenHeapTest extends HeapTest { @override Future loadHeap() async { - final (graph, _) = - await HeapGraphLoaderFile.fromPath('$_dataDir$fileName').load(); + final (graph, _) = await HeapGraphLoaderFile.fromPath( + '$_dataDir$fileName', + ).load(); return graph; } } diff --git a/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart b/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart index a6a373587e3..12894d799cd 100644 --- a/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart +++ b/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart @@ -17,16 +17,14 @@ import '../../utils/test_utils.dart'; part '_perfetto_events_raw.dart'; -PerfettoTimeline perfettoVmTimeline = - PerfettoTimeline.parse({ - 'trace': base64Encode( - (rawPerformanceData[OfflinePerformanceData.traceBinaryKey] - as List) - .cast(), - ), - 'timeOriginMicros': 0, - 'timeExtentMicros': 800000000000, - })!; +PerfettoTimeline perfettoVmTimeline = PerfettoTimeline.parse({ + 'trace': base64Encode( + (rawPerformanceData[OfflinePerformanceData.traceBinaryKey] as List) + .cast(), + ), + 'timeOriginMicros': 0, + 'timeExtentMicros': 800000000000, +})!; Map rawPerformanceData = (samplePerformanceData[ScreenMetaData.performance.id] as Map) @@ -180,34 +178,34 @@ abstract class FlutterFrame2 { endMicros: 713834379102, ); - static final rasterEvent = - rasterizerDoDrawEvent..addChild( - rasterizerDrawToSurfacesEvent..addAllChildren([ - gpuSurfaceMetalImpellerAcquireFrameEvent..addChild( - surfaceMTLWrapCurrentMetalLayerDrawableEvent - ..addChild(waitForNextDrawableEvent), - ), - compositorContextScopedFrameRasterEvent..addAllChildren([ - layerTreePrerollEvent, - iOSExternalViewEmbedderPostPrerollActionEvent, - layerTreePaintEvent, - ]), - surfaceFrameSubmitEvent..addAllChildren([ - surfaceFrameBuildDisplayListEvent, - displayListDispatcherEndRecordingAsPictureEvent, - rendererRenderEvent..addChild( - entityPassOnRenderEvent..addChild( - createGlyphAtlasEvent..addAllChildren([ - canAppendToExistingAtlasEvent, - optimumAtlasSizeForFontGlyphPairsEvent, - createAtlasBitmapEvent, - uploadGlyphTextureAtlasEvent, - ]), - ), + static final rasterEvent = rasterizerDoDrawEvent + ..addChild( + rasterizerDrawToSurfacesEvent..addAllChildren([ + gpuSurfaceMetalImpellerAcquireFrameEvent..addChild( + surfaceMTLWrapCurrentMetalLayerDrawableEvent + ..addChild(waitForNextDrawableEvent), + ), + compositorContextScopedFrameRasterEvent..addAllChildren([ + layerTreePrerollEvent, + iOSExternalViewEmbedderPostPrerollActionEvent, + layerTreePaintEvent, + ]), + surfaceFrameSubmitEvent..addAllChildren([ + surfaceFrameBuildDisplayListEvent, + displayListDispatcherEndRecordingAsPictureEvent, + rendererRenderEvent..addChild( + entityPassOnRenderEvent..addChild( + createGlyphAtlasEvent..addAllChildren([ + canAppendToExistingAtlasEvent, + optimumAtlasSizeForFontGlyphPairsEvent, + createAtlasBitmapEvent, + uploadGlyphTextureAtlasEvent, + ]), ), - ]), + ), ]), - ); + ]), + ); static final rasterizerDoDrawEvent = testTimelineEvent( name: 'Rasterizer::DoDraw', type: TimelineEventType.raster, @@ -367,20 +365,18 @@ abstract class FlutterFrame2 { /// Data for Frame (id: 4) abstract class FlutterFrame4 { - static final frame = - FlutterFrame.fromJson(_frameJson) - ..setEventFlow(uiEvent) - ..setEventFlow(rasterEvent); + static final frame = FlutterFrame.fromJson(_frameJson) + ..setEventFlow(uiEvent) + ..setEventFlow(rasterEvent); /// A frame with extra timeline events for the purpose of testing. /// /// Some events included in [uiEventWithExtras] (and `rasterEventWithExtras` /// if un-commented) are not part of the original trace from with /// [FlutterFrame4] was formed. - static final frameWithExtras = - FlutterFrame.fromJson(_frameJson) - ..setEventFlow(uiEventWithExtras) - ..setEventFlow(rasterEvent); + static final frameWithExtras = FlutterFrame.fromJson(_frameJson) + ..setEventFlow(uiEventWithExtras) + ..setEventFlow(rasterEvent); static final _frameJson = { 'number': 4, @@ -425,17 +421,16 @@ abstract class FlutterFrame4 { CreateGlyphAtlas [713836210893 μs - 713836210899 μs] '''; - static final uiEvent = - animatorBeginFrameEvent..addAllChildren([ - layoutRootEvent..addChild(layoutEvent), - updatingCompositingBitsRootEvent - ..addChild(updatingCompositingBitsEvent), - paintRootEvent..addChild(paintEvent), - compositingEvent..addChild(animatorRenderEvent), - semanticsRootEvent..addChild(semanticsEvent), - finalizeTreeEvent, - postFrameEvent, - ]); + static final uiEvent = animatorBeginFrameEvent + ..addAllChildren([ + layoutRootEvent..addChild(layoutEvent), + updatingCompositingBitsRootEvent..addChild(updatingCompositingBitsEvent), + paintRootEvent..addChild(paintEvent), + compositingEvent..addChild(animatorRenderEvent), + semanticsRootEvent..addChild(semanticsEvent), + finalizeTreeEvent, + postFrameEvent, + ]); static FlutterTimelineEvent uiEventWithExtras = animatorBeginFrameEvent.shallowCopy()..addAllChildren([ @@ -751,27 +746,27 @@ abstract class FlutterFrame4 { endMicros: 713836202360, ); - static final rasterEvent = - rasterizerDoDrawEvent..addChild( - rasterizerDrawToSurfacesEvent..addAllChildren([ - gpuSurfaceMetalImpellerAcquireFrameEvent..addChild( - surfaceMTLWrapCurrentMetalLayerDrawableEvent - ..addChild(waitForNextDrawableEvent), + static final rasterEvent = rasterizerDoDrawEvent + ..addChild( + rasterizerDrawToSurfacesEvent..addAllChildren([ + gpuSurfaceMetalImpellerAcquireFrameEvent..addChild( + surfaceMTLWrapCurrentMetalLayerDrawableEvent + ..addChild(waitForNextDrawableEvent), + ), + compositorContextScopedFrameRasterEvent..addAllChildren([ + layerTreePrerollEvent, + iOSExternalViewEmbedderPostPrerollActionEvent, + layerTreePaintEvent, + ]), + surfaceFrameSubmitEvent..addAllChildren([ + surfaceFrameBuildDisplayListEvent, + displayListDispatcherEndRecordingAsPictureEvent, + rendererRenderEvent..addChild( + entityPassOnRenderEvent..addChild(createGlyphAtlasEvent), ), - compositorContextScopedFrameRasterEvent..addAllChildren([ - layerTreePrerollEvent, - iOSExternalViewEmbedderPostPrerollActionEvent, - layerTreePaintEvent, - ]), - surfaceFrameSubmitEvent..addAllChildren([ - surfaceFrameBuildDisplayListEvent, - displayListDispatcherEndRecordingAsPictureEvent, - rendererRenderEvent..addChild( - entityPassOnRenderEvent..addChild(createGlyphAtlasEvent), - ), - ]), ]), - ); + ]), + ); // static final rasterEventWithExtras = rasterizerDoDrawEvent.shallowCopy() // ..addChild( @@ -935,10 +930,9 @@ abstract class FlutterFrame4 { /// Data for Frame (id: 6) abstract class FlutterFrame6 { - static final frame = - FlutterFrame.fromJson(_frameJson) - ..setEventFlow(uiEvent) - ..setEventFlow(rasterEvent); + static final frame = FlutterFrame.fromJson(_frameJson) + ..setEventFlow(uiEvent) + ..setEventFlow(rasterEvent); static final frameWithoutTimelineEvents = FlutterFrame.fromJson(_frameJson); @@ -985,17 +979,16 @@ abstract class FlutterFrame6 { CreateGlyphAtlas [713836331499 μs - 713836331505 μs] '''; - static final uiEvent = - animatorBeginFrameEvent..addAllChildren([ - layoutRootEvent..addChild(layoutEvent), - updatingCompositingBitsRootEvent - ..addChild(updatingCompositingBitsEvent), - paintRootEvent..addChild(paintEvent), - compositingEvent..addChild(animatorRenderEvent), - semanticsRootEvent..addChild(semanticsEvent), - finalizeTreeEvent, - postFrameEvent, - ]); + static final uiEvent = animatorBeginFrameEvent + ..addAllChildren([ + layoutRootEvent..addChild(layoutEvent), + updatingCompositingBitsRootEvent..addChild(updatingCompositingBitsEvent), + paintRootEvent..addChild(paintEvent), + compositingEvent..addChild(animatorRenderEvent), + semanticsRootEvent..addChild(semanticsEvent), + finalizeTreeEvent, + postFrameEvent, + ]); static final animatorBeginFrameEvent = testTimelineEvent( name: 'Animator::BeginFrame', @@ -1209,27 +1202,27 @@ abstract class FlutterFrame6 { endMicros: 713836330989, ); - static final rasterEvent = - rasterizerDoDrawEvent..addChild( - rasterizerDrawToSurfacesEvent..addAllChildren([ - gpuSurfaceMetalImpellerAcquireFrameEvent..addChild( - surfaceMTLWrapCurrentMetalLayerDrawableEvent - ..addChild(waitForNextDrawableEvent), + static final rasterEvent = rasterizerDoDrawEvent + ..addChild( + rasterizerDrawToSurfacesEvent..addAllChildren([ + gpuSurfaceMetalImpellerAcquireFrameEvent..addChild( + surfaceMTLWrapCurrentMetalLayerDrawableEvent + ..addChild(waitForNextDrawableEvent), + ), + compositorContextScopedFrameRasterEvent..addAllChildren([ + layerTreePrerollEvent, + iOSExternalViewEmbedderPostPrerollActionEvent, + layerTreePaintEvent, + ]), + surfaceFrameSubmitEvent..addAllChildren([ + surfaceFrameBuildDisplayListEvent, + displayListDispatcherEndRecordingAsPictureEvent, + rendererRenderEvent..addChild( + entityPassOnRenderEvent..addChild(createGlyphAtlasEvent), ), - compositorContextScopedFrameRasterEvent..addAllChildren([ - layerTreePrerollEvent, - iOSExternalViewEmbedderPostPrerollActionEvent, - layerTreePaintEvent, - ]), - surfaceFrameSubmitEvent..addAllChildren([ - surfaceFrameBuildDisplayListEvent, - displayListDispatcherEndRecordingAsPictureEvent, - rendererRenderEvent..addChild( - entityPassOnRenderEvent..addChild(createGlyphAtlasEvent), - ), - ]), ]), - ); + ]), + ); static final rasterizerDoDrawEvent = testTimelineEvent( name: 'Rasterizer::DoDraw', diff --git a/packages/devtools_app/test/test_infra/utils/ansi.dart b/packages/devtools_app/test/test_infra/utils/ansi.dart index b3e77d130ef..08a0e656c67 100644 --- a/packages/devtools_app/test/test_infra/utils/ansi.dart +++ b/packages/devtools_app/test/test_infra/utils/ansi.dart @@ -34,12 +34,11 @@ class AnsiWriter { /// Directly index the xterm 256 color palette. void xterm(int color, {bool bg = false}) { - final c = - color < 0 - ? 0 - : color > 255 - ? 255 - : color; + final c = color < 0 + ? 0 + : color > 255 + ? 255 + : color; if (bg) { _background = c; diff --git a/packages/devtools_app/test/test_infra/utils/rendering_tester.dart b/packages/devtools_app/test/test_infra/utils/rendering_tester.dart index 0e54df055c0..200b78c0933 100644 --- a/packages/devtools_app/test/test_infra/utils/rendering_tester.dart +++ b/packages/devtools_app/test/test_infra/utils/rendering_tester.dart @@ -471,8 +471,8 @@ class TestPushLayerPaintingContext extends PaintingContext { // Absorbs errors that don't have "overflowed" in their error details. void absorbOverflowedErrors() { - final errorDetails = - TestRenderingFlutterBinding.instance.takeAllFlutterErrorDetails(); + final errorDetails = TestRenderingFlutterBinding.instance + .takeAllFlutterErrorDetails(); final filtered = errorDetails.where((FlutterErrorDetails details) { return !details.toString().contains('overflowed'); }); @@ -483,8 +483,8 @@ void absorbOverflowedErrors() { // Reports any FlutterErrors. void expectNoFlutterErrors() { - final errorDetails = - TestRenderingFlutterBinding.instance.takeAllFlutterErrorDetails(); + final errorDetails = TestRenderingFlutterBinding.instance + .takeAllFlutterErrorDetails(); errorDetails.forEach(FlutterError.reportError); } diff --git a/packages/devtools_app/test/test_infra/utils/test_utils.dart b/packages/devtools_app/test/test_infra/utils/test_utils.dart index b85665b8b5b..e3898715985 100644 --- a/packages/devtools_app/test/test_infra/utils/test_utils.dart +++ b/packages/devtools_app/test/test_infra/utils/test_utils.dart @@ -29,8 +29,9 @@ FlutterTimelineEvent testTimelineEvent({ when(mockFirstTrackEvent.timestampMicros).thenReturn(startMicros); final frameNumberAsString = args[PerfettoTrackEvent.frameNumberArg] as String?; - final frameNumber = - frameNumberAsString != null ? int.tryParse(frameNumberAsString) : null; + final frameNumber = frameNumberAsString != null + ? int.tryParse(frameNumberAsString) + : null; when(mockFirstTrackEvent.flutterFrameNumber).thenReturn(frameNumber); final devToolsTag = args[PerfettoTrackEvent.devtoolsTagArg] as String?; final isShaderEvent = devToolsTag == PerfettoTrackEvent.shadersArg; diff --git a/packages/devtools_app/test_driver/integration_test.dart b/packages/devtools_app/test_driver/integration_test.dart index 520654de253..841105f01ff 100644 --- a/packages/devtools_app/test_driver/integration_test.dart +++ b/packages/devtools_app/test_driver/integration_test.dart @@ -21,79 +21,81 @@ Future main() async { final driver = await FlutterDriver.connect(); await integrationDriver( driver: driver, - onScreenshot: ( - String screenshotName, - List screenshotBytes, [ - Map? args, - ]) async { - final shouldUpdateGoldens = args?['update_goldens'] == true; - - // TODO(https://github.com/flutter/flutter/issues/118470): remove this. - // We need this to ensure all golden image checks run. Without this - // workaround, the flutter integration test framework will crash on the - // failed expectation. - final lastScreenshot = args?['last_screenshot'] == true; - - final goldenFile = File('$_goldensDirectoryPath/$screenshotName.png'); - - if (shouldUpdateGoldens) { - if (!goldenFile.existsSync()) { - // Create the goldens directory if it does not exist. - Directory(_goldensDirectoryPath).createSync(); - } - goldenFile.writeAsBytesSync(screenshotBytes, flush: true); - print('Golden image updated: $screenshotName.png'); - return true; - } - - bool equal = false; - double percentDiff = 1.0; - if (goldenFile.existsSync()) { - final goldenBytes = goldenFile.readAsBytesSync(); - equal = const DeepCollectionEquality().equals( - goldenBytes, - screenshotBytes, - ); - if (!equal) { - percentDiff = _percentDiff(goldenBytes, screenshotBytes); - } - } - - final failuresDirectory = Directory(_failuresDirectoryPath); - - if (!equal) { - final percentDiffDisplay = '${(percentDiff * 100).toStringAsFixed(4)}%'; - if (percentDiff < _defaultDiffTolerance) { - print( - 'Warning: $screenshotName.png differed from the golden image by ' - '$percentDiffDisplay. Since this is less than the acceptable ' - 'tolerance ${(_defaultDiffTolerance * 100).toStringAsFixed(4)}%, ' - 'the test still passes.', - ); + onScreenshot: + ( + String screenshotName, + List screenshotBytes, [ + Map? args, + ]) async { + final shouldUpdateGoldens = args?['update_goldens'] == true; + + // TODO(https://github.com/flutter/flutter/issues/118470): remove this. + // We need this to ensure all golden image checks run. Without this + // workaround, the flutter integration test framework will crash on the + // failed expectation. + final lastScreenshot = args?['last_screenshot'] == true; + + final goldenFile = File('$_goldensDirectoryPath/$screenshotName.png'); + + if (shouldUpdateGoldens) { + if (!goldenFile.existsSync()) { + // Create the goldens directory if it does not exist. + Directory(_goldensDirectoryPath).createSync(); + } + goldenFile.writeAsBytesSync(screenshotBytes, flush: true); + print('Golden image updated: $screenshotName.png'); + return true; + } + + bool equal = false; + double percentDiff = 1.0; + if (goldenFile.existsSync()) { + final goldenBytes = goldenFile.readAsBytesSync(); + equal = const DeepCollectionEquality().equals( + goldenBytes, + screenshotBytes, + ); + if (!equal) { + percentDiff = _percentDiff(goldenBytes, screenshotBytes); + } + } + + final failuresDirectory = Directory(_failuresDirectoryPath); + + if (!equal) { + final percentDiffDisplay = + '${(percentDiff * 100).toStringAsFixed(4)}%'; + if (percentDiff < _defaultDiffTolerance) { + print( + 'Warning: $screenshotName.png differed from the golden image by ' + '$percentDiffDisplay. Since this is less than the acceptable ' + 'tolerance ${(_defaultDiffTolerance * 100).toStringAsFixed(4)}%, ' + 'the test still passes.', + ); + return true; + } + print( + 'Golden image test failed: $screenshotName.png. The test image ' + 'differed from the golden image by $percentDiffDisplay.', + ); + + // Create the goldens and failures directories if they do not exist. + Directory(_goldensDirectoryPath).createSync(); + failuresDirectory.createSync(); + + File( + '$_failuresDirectoryPath/$screenshotName.png', + ).writeAsBytesSync(screenshotBytes); + } + + if (lastScreenshot && + failuresDirectory.existsSync() && + failuresDirectory.listSync().isNotEmpty) { + return false; + } + return true; - } - print( - 'Golden image test failed: $screenshotName.png. The test image ' - 'differed from the golden image by $percentDiffDisplay.', - ); - - // Create the goldens and failures directories if they do not exist. - Directory(_goldensDirectoryPath).createSync(); - failuresDirectory.createSync(); - - File( - '$_failuresDirectoryPath/$screenshotName.png', - ).writeAsBytesSync(screenshotBytes); - } - - if (lastScreenshot && - failuresDirectory.existsSync() && - failuresDirectory.listSync().isNotEmpty) { - return false; - } - - return true; - }, + }, ); } diff --git a/packages/devtools_app_shared/lib/src/service/service_manager.dart b/packages/devtools_app_shared/lib/src/service/service_manager.dart index 2d39c3d719a..46852296829 100644 --- a/packages/devtools_app_shared/lib/src/service/service_manager.dart +++ b/packages/devtools_app_shared/lib/src/service/service_manager.dart @@ -293,12 +293,12 @@ class ServiceManager { await callLifecycleCallbacks( ServiceManagerLifecycle.beforeCloseVmService, - this.service, + service, ); _closeVmServiceConnection(); await callLifecycleCallbacks( ServiceManagerLifecycle.afterCloseVmService, - this.service, + service, ); resolvedUriManager.vmServiceClosed(); @@ -547,7 +547,7 @@ class ServiceManager { Future _lookupPackageRootByEval(Library rootLibrary) async { final eval = EvalOnDartLibrary( rootLibrary.uri!, - this.service! as VmService, + service! as VmService, serviceManager: this, // Swallow exceptions since this evaluation may be called on an older // version of package:test where we do not expect the evaluation to diff --git a/packages/devtools_app_shared/lib/src/ui/text_field.dart b/packages/devtools_app_shared/lib/src/ui/text_field.dart index 68b98d57ee9..04a0d38e770 100644 --- a/packages/devtools_app_shared/lib/src/ui/text_field.dart +++ b/packages/devtools_app_shared/lib/src/ui/text_field.dart @@ -75,19 +75,19 @@ final class DevToolsClearableTextField extends StatelessWidget { hintStyle: theme.subtleTextStyle, prefixIcon: prefixIcon, suffixIcon: SizedBox( - height: inputDecorationElementHeight, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - ...additionalSuffixActions, - InputDecorationSuffixButton.clear( - onPressed: () { - controller.clear(); - onChanged?.call(''); - }, - ), - ], - ), + height: inputDecorationElementHeight, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + ...additionalSuffixActions, + InputDecorationSuffixButton.clear( + onPressed: () { + controller.clear(); + onChanged?.call(''); + }, + ), + ], + ), ), ), ), From 549984237e9e3b2acc246c3443a62aa96ec78f39 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Fri, 2 May 2025 10:25:56 -0700 Subject: [PATCH 016/107] Fix a focus traversal issue with search fields (#9166) * Fix a focus traversal issue with search fields * rnotes * merge --- .../lib/src/shared/ui/search.dart | 122 +++++++++--------- .../release_notes/NEXT_RELEASE_NOTES.md | 1 + 2 files changed, 63 insertions(+), 60 deletions(-) diff --git a/packages/devtools_app/lib/src/shared/ui/search.dart b/packages/devtools_app/lib/src/shared/ui/search.dart index fb1064e65cf..9ef8d834197 100644 --- a/packages/devtools_app/lib/src/shared/ui/search.dart +++ b/packages/devtools_app/lib/src/shared/ui/search.dart @@ -1010,67 +1010,69 @@ class StatelessSearchField controller.searchFieldFocusNode?.requestFocus(); } - final searchField = TextField( - key: searchFieldKey, - autofocus: true, - enabled: searchFieldEnabled, - focusNode: controller.searchFieldFocusNode, - controller: controller.searchTextFieldController, - style: textStyle, - maxLines: _maxLines, - onChanged: onChanged, - onEditingComplete: () { - controller.searchFieldFocusNode?.requestFocus(); - }, - // Guarantee that the TextField on all platforms renders in the same - // color for border, label text, and cursor. Primarly, so golden screen - // snapshots will compare with the exact color. - // Guarantee that the TextField on all platforms renders in the same - // color for border, label text, and cursor. Primarly, so golden screen - // snapshots will compare with the exact color. - decoration: - decoration ?? - InputDecoration( - constraints: BoxConstraints( - minHeight: searchFieldHeight ?? defaultTextFieldHeight, - ), - contentPadding: const EdgeInsets.symmetric( - horizontal: densePadding, - ), - border: const OutlineInputBorder(), - hintText: 'Search', - hintStyle: theme.subtleTextStyle, - labelText: label, - labelStyle: theme.subtleTextStyle, - prefixIcon: Icon(Icons.search, size: defaultIconSize), - prefix: prefix != null - ? Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - prefix!, - SizedBox( - height: inputDecorationElementHeight, - width: defaultIconSize, - child: Transform.rotate( - angle: degToRad(90), - child: PaddedDivider.vertical(), + final searchField = FocusTraversalGroup( + child: TextField( + key: searchFieldKey, + autofocus: true, + enabled: searchFieldEnabled, + focusNode: controller.searchFieldFocusNode, + controller: controller.searchTextFieldController, + style: textStyle, + maxLines: _maxLines, + onChanged: onChanged, + onEditingComplete: () { + controller.searchFieldFocusNode?.requestFocus(); + }, + // Guarantee that the TextField on all platforms renders in the same + // color for border, label text, and cursor. Primarly, so golden screen + // snapshots will compare with the exact color. + // Guarantee that the TextField on all platforms renders in the same + // color for border, label text, and cursor. Primarly, so golden screen + // snapshots will compare with the exact color. + decoration: + decoration ?? + InputDecoration( + constraints: BoxConstraints( + minHeight: searchFieldHeight ?? defaultTextFieldHeight, + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: densePadding, + ), + border: const OutlineInputBorder(), + hintText: 'Search', + hintStyle: theme.subtleTextStyle, + labelText: label, + labelStyle: theme.subtleTextStyle, + prefixIcon: Icon(Icons.search, size: defaultIconSize), + prefix: prefix != null + ? Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + prefix!, + SizedBox( + height: inputDecorationElementHeight, + width: defaultIconSize, + child: Transform.rotate( + angle: degToRad(90), + child: PaddedDivider.vertical(), + ), ), - ), - ], - ) - : null, - suffix: - suffix ?? - _SearchFieldSuffix( - controller: controller, - supportsNavigation: supportsNavigation, - onClose: () { - onClose?.call(); - onChanged(''); - }, - ), - ), + ], + ) + : null, + suffix: + suffix ?? + _SearchFieldSuffix( + controller: controller, + supportsNavigation: supportsNavigation, + onClose: () { + onClose?.call(); + onChanged(''); + }, + ), + ), + ), ); if (shouldRequestFocus) { diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index a2f41894e59..915e386117f 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -18,6 +18,7 @@ To learn more about DevTools, check out the - Prevent web apps from remaining paused after triggering a hot-restart from DevTools. - [#9125](https://github.com/flutter/devtools/pull/9125) - Dismiss stale banner messages when the connected app state changes. - [#9148](https://github.com/flutter/devtools/pull/9148) +- Fix a focus traversal issue with search fields. [#9166](https://github.com/flutter/devtools/pull/9166) ## Inspector updates From d4a0a34cea51ba4d0981a36fbabfcb7dbab4241f Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Fri, 2 May 2025 10:26:14 -0700 Subject: [PATCH 017/107] Clean up abstract classes that only contain static methods (#9170) * Clean up abstract classes that only contain static methods * remove unused parameter --- .../lib/src/framework/framework_core.dart | 4 ++-- .../src/screens/debugger/debugger_model.dart | 4 ++-- .../lib/src/screens/debugger/span_parser.dart | 4 ++-- .../charts/android_chart_controller.dart | 4 ++-- .../controller/charts/vm_chart_controller.dart | 4 ++-- .../_property_editor_sidebar_constants.dart | 4 ++-- .../lib/src/shared/analytics/gtags.dart | 4 ++-- .../lib/src/shared/charts/flame_chart.dart | 5 ++--- .../lib/src/shared/development_helpers.dart | 6 ++++-- .../lib/src/shared/feature_flags.dart | 7 +++---- .../lib/src/shared/http/_http_date.dart | 6 ++---- .../primitives/diagnostics_text_styles.dart | 5 ++--- .../lib/src/shared/utils/utils.dart | 1 + .../tracing/tracing_pane_controller_test.dart | 4 ++-- .../test/test_infra/scenes/memory/default.dart | 4 ++-- .../performance/sample_performance_data.dart | 8 +++----- .../lib/src/server/file_system.dart | 4 ++-- .../lib/src/server/handlers/_app_size.dart | 5 ++--- .../lib/src/server/handlers/_deeplink.dart | 5 ++--- .../server/handlers/_devtools_extensions.dart | 5 ++--- .../lib/src/server/handlers/_dtd.dart | 5 ++--- .../lib/src/server/handlers/_preferences.dart | 5 ++--- .../lib/src/server/handlers/_release_notes.dart | 5 ++--- .../lib/src/server/handlers/_storage.dart | 5 ++--- .../lib/src/server/handlers/_survey.dart | 5 ++--- .../{_general.dart => _vm_service.dart} | 7 ++----- .../lib/src/server/server_api.dart | 4 ++-- .../test/server/general_api_test.dart | 17 ++++++++--------- 28 files changed, 65 insertions(+), 81 deletions(-) rename packages/devtools_shared/lib/src/server/handlers/{_general.dart => _vm_service.dart} (98%) diff --git a/packages/devtools_app/lib/src/framework/framework_core.dart b/packages/devtools_app/lib/src/framework/framework_core.dart index 87a3f219ec5..d7c4ac5ec88 100644 --- a/packages/devtools_app/lib/src/framework/framework_core.dart +++ b/packages/devtools_app/lib/src/framework/framework_core.dart @@ -44,8 +44,8 @@ typedef ErrorReporter = void Function(String title, Object error); final _log = Logger('framework_core'); -// ignore: avoid_classes_with_only_static_members, intentional grouping of static methods. -abstract class FrameworkCore { +/// A namespace for core framework objects and methods. +extension FrameworkCore on Never { static final _memoryObserver = MemoryObserver(); /// Initializes the DevTools framework, which includes setting up global diff --git a/packages/devtools_app/lib/src/screens/debugger/debugger_model.dart b/packages/devtools_app/lib/src/screens/debugger/debugger_model.dart index 7dc18d8bc3b..12affb77fdf 100644 --- a/packages/devtools_app/lib/src/screens/debugger/debugger_model.dart +++ b/packages/devtools_app/lib/src/screens/debugger/debugger_model.dart @@ -236,8 +236,8 @@ class StackFrameAndSourcePosition { } } -// ignore: avoid_classes_with_only_static_members, fine for utility method. -abstract class ScriptRefUtils { +/// A namespace for [ScriptRef] utilities. +extension ScriptRefUtils on Never { static String fileName(ScriptRef scriptRef) => fileNameFromUri(Uri.parse(scriptRef.uri!).path)!; } diff --git a/packages/devtools_app/lib/src/screens/debugger/span_parser.dart b/packages/devtools_app/lib/src/screens/debugger/span_parser.dart index c6d3511458c..69c96c48ffc 100644 --- a/packages/devtools_app/lib/src/screens/debugger/span_parser.dart +++ b/packages/devtools_app/lib/src/screens/debugger/span_parser.dart @@ -9,8 +9,8 @@ import 'package:collection/collection.dart'; import 'package:string_scanner/string_scanner.dart'; //TODO(jacobr): cleanup. -// ignore: avoid_classes_with_only_static_members -abstract class SpanParser { +/// A namespace for [SpanParser] utilities. +extension SpanParser on Never { /// Takes a TextMate [Grammar] and a [String] and outputs a list of /// [ScopeSpan]s corresponding to the parsed input. static List parse(Grammar grammar, String src) { diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/android_chart_controller.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/android_chart_controller.dart index 12d1bfade6f..247615b6eae 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/android_chart_controller.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/android_chart_controller.dart @@ -13,8 +13,8 @@ import '../../../../../../shared/charts/chart_trace.dart' import '../../../../shared/primitives/memory_timeline.dart'; import '../../data/charts.dart'; -// ignore: avoid_classes_with_only_static_members, enum-like classes are ok -class _Color { +/// A namespace for Android memory chart color constants. +extension _Color on Never { static const otherColor = Color(0xffff8800); // HoloOrangeDark; static const nativeHeapColor = Color(0xff33b5e5); // HoloBlueLight static final graphicColor = Colors.greenAccent.shade400; diff --git a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/vm_chart_controller.dart b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/vm_chart_controller.dart index a8c5df9f7e3..a84a8dc67aa 100644 --- a/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/vm_chart_controller.dart +++ b/packages/devtools_app/lib/src/screens/memory/panes/chart/controller/charts/vm_chart_controller.dart @@ -13,8 +13,8 @@ import '../../../../../../shared/charts/chart_trace.dart' import '../../../../shared/primitives/memory_timeline.dart'; import '../../data/charts.dart'; -// ignore: avoid_classes_with_only_static_members, enum-like classes are ok -class _Colors { +/// A namespace for VM memory chart color constants. +extension _Colors on Never { static final capacity = Colors.grey[400]!; static const used = Color(0xff33b5e5); static const externals = Color(0xff4ddeff); diff --git a/packages/devtools_app/lib/src/shared/analytics/constants/_property_editor_sidebar_constants.dart b/packages/devtools_app/lib/src/shared/analytics/constants/_property_editor_sidebar_constants.dart index 3e903f9cbeb..73a1882aa1b 100644 --- a/packages/devtools_app/lib/src/shared/analytics/constants/_property_editor_sidebar_constants.dart +++ b/packages/devtools_app/lib/src/shared/analytics/constants/_property_editor_sidebar_constants.dart @@ -4,8 +4,8 @@ part of '../constants.dart'; -// ignore: avoid_classes_with_only_static_members, used for namespacing. -class PropertyEditorSidebar { +/// A namespace for Property Editor analytics. +extension PropertyEditorSidebar on Never { /// Analytics id to track events that come from the DTD editor sidebar. static String get id => 'propertyEditorSidebar'; diff --git a/packages/devtools_app/lib/src/shared/analytics/gtags.dart b/packages/devtools_app/lib/src/shared/analytics/gtags.dart index 87564ddea18..4e43b03772b 100644 --- a/packages/devtools_app/lib/src/shared/analytics/gtags.dart +++ b/packages/devtools_app/lib/src/shared/analytics/gtags.dart @@ -21,8 +21,8 @@ import 'analytics.dart' as ga; external void _gTagCommandName(String command, String name, [JSObject? params]); // TODO(jacobr): refactor this code if we do not migrate off gtags. -// ignore: avoid_classes_with_only_static_members -class GTag { +/// A namespace for gtags. +extension GTag on Never { static const _event = 'event'; static const _exception = 'exception'; diff --git a/packages/devtools_app/lib/src/shared/charts/flame_chart.dart b/packages/devtools_app/lib/src/shared/charts/flame_chart.dart index 5151208b286..ce5b4149bbb 100644 --- a/packages/devtools_app/lib/src/shared/charts/flame_chart.dart +++ b/packages/devtools_app/lib/src/shared/charts/flame_chart.dart @@ -889,9 +889,8 @@ extension NodeListExtension on List { } } -// TODO(jacobr): cleanup up this util class with just static members. -// ignore: avoid_classes_with_only_static_members -class FlameChartUtils { +/// A namespace for flame chart utilities. +extension FlameChartUtils on Never { static double leftPaddingForNode( int index, List nodes, { diff --git a/packages/devtools_app/lib/src/shared/development_helpers.dart b/packages/devtools_app/lib/src/shared/development_helpers.dart index 770016a560d..1ade4bf20e3 100644 --- a/packages/devtools_app/lib/src/shared/development_helpers.dart +++ b/packages/devtools_app/lib/src/shared/development_helpers.dart @@ -84,8 +84,10 @@ void resetDevToolsExtensionEnabledStates() => /// server connection. final stubExtensionEnabledStates = {}; -// ignore: avoid_classes_with_only_static_members, useful for testing. -abstract class StubDevToolsExtensions { +/// A namespace for stubbed DevTools extensions. +/// +/// These are useful for testing and local development. +extension StubDevToolsExtensions on Never { /// Extension for package:foo detected from a running app that requires a /// connected app. static final fooExtension = DevToolsExtensionConfig.parse({ diff --git a/packages/devtools_app/lib/src/shared/feature_flags.dart b/packages/devtools_app/lib/src/shared/feature_flags.dart index d3dc5730d6c..c15e1298b80 100644 --- a/packages/devtools_app/lib/src/shared/feature_flags.dart +++ b/packages/devtools_app/lib/src/shared/feature_flags.dart @@ -41,13 +41,12 @@ const _kNetworkDisconnectExperience = bool.fromEnvironment( defaultValue: true, ); -// It is ok to have enum-like static only classes. -// ignore: avoid_classes_with_only_static_members -/// Flags to hide features under construction. +/// A namespace for feature flags, which set the visibility of features under +/// active development. /// /// When adding a new feature flag, the developer is responsible for adding it /// to the [_allFlags] map for debugging purposes. -abstract class FeatureFlags { +extension FeatureFlags on Never { /// Flag to enable the DevTools memory observer, which attempts to help users /// avoid OOM crashes. /// diff --git a/packages/devtools_app/lib/src/shared/http/_http_date.dart b/packages/devtools_app/lib/src/shared/http/_http_date.dart index 863eff93507..38f31d97bbc 100644 --- a/packages/devtools_app/lib/src/shared/http/_http_date.dart +++ b/packages/devtools_app/lib/src/shared/http/_http_date.dart @@ -14,10 +14,8 @@ part of 'http.dart'; -// TODO(jacobr): cleanup this class with only static members. -// ignore: avoid_classes_with_only_static_members -/// Utility functions for working with dates with HTTP specific date formats. -class HttpDate { +/// A namespace for HTTP date utilities. +extension HttpDate on Never { // Parse a cookie date string. static DateTime _parseCookieDate(String date) { const monthsLowerCase = const [ diff --git a/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart b/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart index c8aafc05600..5773f02f3c2 100644 --- a/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart +++ b/packages/devtools_app/lib/src/shared/primitives/diagnostics_text_styles.dart @@ -5,9 +5,8 @@ import 'package:devtools_app_shared/ui.dart'; import 'package:flutter/material.dart'; -// Enum-like static classes are ok. -// ignore: avoid_classes_with_only_static_members -class DiagnosticsTextStyles { +/// A namespace for diagnostic text styles and utilities. +extension DiagnosticsTextStyles on Never { static TextStyle unimportant(ColorScheme colorScheme) => TextStyle( color: colorScheme.isLight ? Colors.grey.shade500 : Colors.grey.shade600, ); diff --git a/packages/devtools_app/lib/src/shared/utils/utils.dart b/packages/devtools_app/lib/src/shared/utils/utils.dart index 4d05451b999..c1db55d2ab5 100644 --- a/packages/devtools_app/lib/src/shared/utils/utils.dart +++ b/packages/devtools_app/lib/src/shared/utils/utils.dart @@ -18,6 +18,7 @@ import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; import 'package:vm_service/vm_service.dart'; +// ignore: avoid-importing-entrypoint-exports, required to access version. import '../../../devtools.dart' as devtools; import '../../service/connected_app/connected_app.dart'; import '../framework/app_error_handling.dart'; diff --git a/packages/devtools_app/test/screens/memory/tracing/tracing_pane_controller_test.dart b/packages/devtools_app/test/screens/memory/tracing/tracing_pane_controller_test.dart index 1d9849e5f04..151559fa669 100644 --- a/packages/devtools_app/test/screens/memory/tracing/tracing_pane_controller_test.dart +++ b/packages/devtools_app/test/screens/memory/tracing/tracing_pane_controller_test.dart @@ -7,8 +7,8 @@ import 'package:devtools_app/src/screens/memory/panes/tracing/tracing_pane_contr import 'package:flutter_test/flutter_test.dart'; import 'package:vm_service/vm_service.dart'; -// ignore: avoid_classes_with_only_static_members, ok for enum-like class -class _Tests { +/// A namespace for memory tracing tests. +extension _Tests on Never { static final empty = TracePaneController(rootPackage: ''); static final selection = TracePaneController( diff --git a/packages/devtools_app/test/test_infra/scenes/memory/default.dart b/packages/devtools_app/test/test_infra/scenes/memory/default.dart index f9f15a12675..b04c251471f 100644 --- a/packages/devtools_app/test/test_infra/scenes/memory/default.dart +++ b/packages/devtools_app/test/test_infra/scenes/memory/default.dart @@ -27,8 +27,8 @@ import '../scene_test_extensions.dart'; // To run: // flutter run -t test/test_infra/scenes/memory/default.stager_app.g.dart -d macos -// ignore: avoid_classes_with_only_static_members, enum like classes are ok -abstract class MemoryDefaultSceneHeaps { +/// A namespace for stubbed data used in memory tests. +extension MemoryDefaultSceneHeaps on Never { /// Many instances of the same class with different long paths. /// /// If sorted by retaining path this class will be the second from the top. diff --git a/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart b/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart index 12894d799cd..8a9362ca124 100644 --- a/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart +++ b/packages/devtools_app/test/test_infra/test_data/performance/sample_performance_data.dart @@ -4,8 +4,6 @@ // This is the Perfetto data from [samplePerformanceData] as data class objects. -// ignore_for_file: avoid_classes_with_only_static_members - import 'dart:convert'; import 'package:devtools_app/devtools_app.dart'; @@ -129,7 +127,7 @@ final timelineEventWithShaderJank = testTimelineEvent( ); /// Data for Frame (id: 2) -abstract class FlutterFrame2 { +extension FlutterFrame2 on Never { static final frame = FlutterFrame.fromJson({ 'number': 2, @@ -364,7 +362,7 @@ abstract class FlutterFrame2 { } /// Data for Frame (id: 4) -abstract class FlutterFrame4 { +extension FlutterFrame4 on Never { static final frame = FlutterFrame.fromJson(_frameJson) ..setEventFlow(uiEvent) ..setEventFlow(rasterEvent); @@ -929,7 +927,7 @@ abstract class FlutterFrame4 { } /// Data for Frame (id: 6) -abstract class FlutterFrame6 { +extension FlutterFrame6 on Never { static final frame = FlutterFrame.fromJson(_frameJson) ..setEventFlow(uiEvent) ..setEventFlow(rasterEvent); diff --git a/packages/devtools_shared/lib/src/server/file_system.dart b/packages/devtools_shared/lib/src/server/file_system.dart index 18f2a0baeaa..80d24409b5f 100644 --- a/packages/devtools_shared/lib/src/server/file_system.dart +++ b/packages/devtools_shared/lib/src/server/file_system.dart @@ -9,8 +9,8 @@ import 'package:path/path.dart' as path; import 'devtools_store.dart'; -// ignore: avoid_classes_with_only_static_members, requires refactor. -class LocalFileSystem { +/// A namespace local file system utlities. +extension LocalFileSystem on Never { static String _userHomeDir() { final envKey = Platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME'; return Platform.environment[envKey] ?? '.'; diff --git a/packages/devtools_shared/lib/src/server/handlers/_app_size.dart b/packages/devtools_shared/lib/src/server/handlers/_app_size.dart index 683522764ed..f7f31a5be2b 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_app_size.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_app_size.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _AppSizeHandler { +/// A namespace for app size server request handlers. +extension _AppSizeHandler on Never { static shelf.Response getBaseAppSizeFile( ServerApi api, Map queryParams, diff --git a/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart b/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart index c65f749f57b..b5c86417bfe 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_deeplink.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _DeeplinkApiHandler { +/// A namespace for deep link server request handlers. +extension _DeeplinkApiHandler on Never { static Future handleAndroidBuildVariants( ServerApi api, Map queryParams, diff --git a/packages/devtools_shared/lib/src/server/handlers/_devtools_extensions.dart b/packages/devtools_shared/lib/src/server/handlers/_devtools_extensions.dart index 3e2172530b5..f7c63671630 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_devtools_extensions.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_devtools_extensions.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _ExtensionsApiHandler { +/// A namespace for DevTools extensions server request handlers. +extension _ExtensionsApiHandler on Never { static Future handleServeAvailableExtensions( ServerApi api, Map queryParams, diff --git a/packages/devtools_shared/lib/src/server/handlers/_dtd.dart b/packages/devtools_shared/lib/src/server/handlers/_dtd.dart index 5b6fb59d5cb..b7f381b4b3e 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_dtd.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_dtd.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _DtdApiHandler { +/// A namespace for Dart Tooling Daemon (DTD) server request handlers. +extension _DtdApiHandler on Never { static shelf.Response handleGetDtdUri( ServerApi api, DtdInfo? dtd, diff --git a/packages/devtools_shared/lib/src/server/handlers/_preferences.dart b/packages/devtools_shared/lib/src/server/handlers/_preferences.dart index 400e02fd89c..e5b69f62a27 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_preferences.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_preferences.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _PreferencesApiHandler { +/// A namespace for preferences server request handlers. +extension _PreferencesApiHandler on Never { static shelf.Response getPreferenceValue( ServerApi api, Map queryParams, diff --git a/packages/devtools_shared/lib/src/server/handlers/_release_notes.dart b/packages/devtools_shared/lib/src/server/handlers/_release_notes.dart index 2382088a82f..492bedc01a8 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_release_notes.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_release_notes.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _ReleaseNotesHandler { +/// A namespace for release notes server request handlers. +extension _ReleaseNotesHandler on Never { static shelf.Response getLastReleaseNotesVersion( ServerApi api, DevToolsUsage devToolsStore, diff --git a/packages/devtools_shared/lib/src/server/handlers/_storage.dart b/packages/devtools_shared/lib/src/server/handlers/_storage.dart index deeea33bd69..391447e3d7a 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_storage.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_storage.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _StorageHandler { +/// A namespace for local storage request handlers. +extension _StorageHandler on Never { static shelf.Response handleGetStorageValue( ServerApi api, DevToolsUsage devToolsStore, { diff --git a/packages/devtools_shared/lib/src/server/handlers/_survey.dart b/packages/devtools_shared/lib/src/server/handlers/_survey.dart index 0423fd14289..40e7f98dd4f 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_survey.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_survey.dart @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; -abstract class _SurveyHandler { +/// A namespace for DevTools survey server request handlers. +extension _SurveyHandler on Never { static shelf.Response setActiveSurvey( ServerApi api, Map queryParams, diff --git a/packages/devtools_shared/lib/src/server/handlers/_general.dart b/packages/devtools_shared/lib/src/server/handlers/_vm_service.dart similarity index 98% rename from packages/devtools_shared/lib/src/server/handlers/_general.dart rename to packages/devtools_shared/lib/src/server/handlers/_vm_service.dart index f8f7e3005c8..15722ffec2a 100644 --- a/packages/devtools_shared/lib/src/server/handlers/_general.dart +++ b/packages/devtools_shared/lib/src/server/handlers/_vm_service.dart @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. -// ignore_for_file: avoid_classes_with_only_static_members - part of '../server_api.dart'; +/// A namespace for VM service related server request handlers. @visibleForTesting -abstract class Handler { +extension VmServiceHandler on Never { /// Stores the calculated package roots for VM service connections that are /// initiated in [handleNotifyForVmServiceConnection]. /// @@ -68,7 +67,6 @@ abstract class Handler { vmServiceUriAsString: vmServiceUriAsString, vmServiceUri: vmServiceUri, connected: connected, - api: api, dtd: dartToolingDaemon, ); if (detectRootResponse.success) { @@ -98,7 +96,6 @@ abstract class Handler { required String vmServiceUriAsString, required Uri vmServiceUri, required bool connected, - required ServerApi api, required DartToolingDaemon dtd, }) async { final Uri rootPackageUri; diff --git a/packages/devtools_shared/lib/src/server/server_api.dart b/packages/devtools_shared/lib/src/server/server_api.dart index 8a39deb8cd2..5254041f3e5 100644 --- a/packages/devtools_shared/lib/src/server/server_api.dart +++ b/packages/devtools_shared/lib/src/server/server_api.dart @@ -32,7 +32,7 @@ part 'handlers/_app_size.dart'; part 'handlers/_deeplink.dart'; part 'handlers/_devtools_extensions.dart'; part 'handlers/_dtd.dart'; -part 'handlers/_general.dart'; +part 'handlers/_vm_service.dart'; part 'handlers/_preferences.dart'; part 'handlers/_release_notes.dart'; part 'handlers/_storage.dart'; @@ -64,7 +64,7 @@ class ServerApi { final queryParams = request.requestedUri.queryParameters; switch (request.url.path) { case apiNotifyForVmServiceConnection: - return Handler.handleNotifyForVmServiceConnection( + return VmServiceHandler.handleNotifyForVmServiceConnection( api, queryParams, dtd, diff --git a/packages/devtools_shared/test/server/general_api_test.dart b/packages/devtools_shared/test/server/general_api_test.dart index 4e2c46be605..fff2abb5aa2 100644 --- a/packages/devtools_shared/test/server/general_api_test.dart +++ b/packages/devtools_shared/test/server/general_api_test.dart @@ -115,7 +115,7 @@ void main() { required Uri root, required bool connected, }) async { - await server.Handler.updateDtdWorkspaceRoots( + await server.VmServiceHandler.updateDtdWorkspaceRoots( testDtdConnection!, dtdConnectionInfo: dtd!.info!, rootFromVmService: root, @@ -180,11 +180,11 @@ void main() { test('succeeds for a connect event', () async { final vmServiceUri = normalizeVmServiceUri(vmServiceUriString!); expect(vmServiceUri, isNotNull); - final response = await server.Handler.detectRootPackageForVmService( + final response = + await server.VmServiceHandler.detectRootPackageForVmService( vmServiceUriAsString: vmServiceUriString!, vmServiceUri: vmServiceUri!, connected: true, - api: ServerApi(), dtd: testDtdConnection!, ); expect(response.success, true); @@ -194,11 +194,11 @@ void main() { }); test('succeeds for a disconnect event when cache is empty', () async { - final response = await server.Handler.detectRootPackageForVmService( + final response = + await server.VmServiceHandler.detectRootPackageForVmService( vmServiceUriAsString: vmServiceUriString!, vmServiceUri: Uri.parse('ws://127.0.0.1:63555/fake-uri=/ws'), connected: false, - api: ServerApi(), dtd: testDtdConnection!, ); expect(response, (success: true, message: null, uri: null)); @@ -209,11 +209,11 @@ void main() { () async { final vmServiceUri = normalizeVmServiceUri(vmServiceUriString!); expect(vmServiceUri, isNotNull); - final response = await server.Handler.detectRootPackageForVmService( + final response = + await server.VmServiceHandler.detectRootPackageForVmService( vmServiceUriAsString: vmServiceUriString!, vmServiceUri: vmServiceUri!, connected: true, - api: ServerApi(), dtd: testDtdConnection!, ); expect(response.success, true); @@ -222,11 +222,10 @@ void main() { expect(response.uri!.toString(), endsWith(app!.directory.path)); final disconnectResponse = - await server.Handler.detectRootPackageForVmService( + await server.VmServiceHandler.detectRootPackageForVmService( vmServiceUriAsString: vmServiceUriString!, vmServiceUri: vmServiceUri, connected: false, - api: ServerApi(), dtd: testDtdConnection!, ); expect(disconnectResponse.success, true); From 3187c2cc2fb5e508972504891257c0651d99fa46 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Fri, 2 May 2025 13:20:53 -0700 Subject: [PATCH 018/107] Use consistent widget inspector icon across Flutter and DevTools (#9163) --- .../icons/widget-select-dgrey.png | Bin 1267 -> 0 bytes .../icons/widget-select-lgrey.png | Bin 1333 -> 0 bytes .../icons/widget-select-white.png | Bin 904 -> 0 bytes .../service/service_extension_widgets.dart | 2 +- .../lib/src/service/service_extensions.dart | 5 +++-- packages/devtools_app/pubspec.yaml | 1 + ...ation_animated_physical_model_selected.png | Bin 57710 -> 57377 bytes ...ration_inspector_errors_1_initial_load.png | Bin 35462 -> 35122 bytes ...tion_inspector_errors_2_error_selected.png | Bin 61097 -> 60715 bytes .../integration_inspector_initial_load.png | Bin 29717 -> 29367 bytes ...ntegration_inspector_richtext_selected.png | Bin 45887 -> 45572 bytes ...ntegration_inspector_scaffold_selected.png | Bin 57710 -> 57379 bytes .../integration_inspector_select_center.png | Bin 54373 -> 54064 bytes ...n_inspector_select_center_details_tree.png | Bin 45823 -> 45504 bytes ...ion_inspector_v2_errors_1_initial_load.png | Bin 36706 -> 36377 bytes ...n_inspector_v2_errors_2_error_selected.png | Bin 48028 -> 47663 bytes ..._inspector_v2_hideable_widget_selected.png | Bin 59648 -> 59294 bytes ...2_hideable_widget_selected_from_search.png | Bin 59648 -> 59294 bytes ...or_v2_implementation_widgets_collapsed.png | Bin 43178 -> 42829 bytes ...tor_v2_implementation_widgets_expanded.png | Bin 59651 -> 59316 bytes ...ector_v2_implementation_widgets_hidden.png | Bin 33180 -> 32840 bytes .../integration_inspector_v2_initial_load.png | Bin 30604 -> 30278 bytes ...egration_inspector_v2_revert_to_legacy.png | Bin 54373 -> 54064 bytes ...integration_inspector_v2_select_center.png | Bin 37029 -> 36752 bytes 24 files changed, 5 insertions(+), 3 deletions(-) delete mode 100644 packages/devtools_app/icons/widget-select-dgrey.png delete mode 100644 packages/devtools_app/icons/widget-select-lgrey.png delete mode 100644 packages/devtools_app/icons/widget-select-white.png diff --git a/packages/devtools_app/icons/widget-select-dgrey.png b/packages/devtools_app/icons/widget-select-dgrey.png deleted file mode 100644 index 40ade7a597f7819d96f9973213a4f928b538add7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1267 zcmVdW-SPP z$vvj(ldvYzmwC+6^WuC2@-^gF)wLSf>1-LnG3><^etq%vGQLmzkdYs^YeF+CY!vNEqoov*IGBev}S-{dnP9*>&fw7 zi;9XixCxw>mv<3gr}5S9hJ-Q!0Ou3zI-td(Ts%HLewV=OoseMU&tZ2YX1fw1Eqsm^ zyE1|9?(PTye=q?4kf3dhWU)b)v0Ey!O@d4zhum!|0;veY;Ko3Z- z9kOne^nHz;R1H!nXJ)&kVooI_YWVsX{dGElSvLnsyFu(W>e$Un-{Rup)F-f!}WBD7K@_AOP_% zAUDGH*kWO8=~MJiPfu?{C=t*)2Q0u$Q;RDG#2PuZn;}xqZj(8!gU1!y84xKF8)eh5 zqCK$z;A^A~+uhM<)L&LswymS1V?gSWw+-bPMST1*LusL~T>}<2wrckIX%8CF8KO@z zGc!N$>gsxIYwV!W^As|}z)XBHIy%}(N^Lf4ccXJfK=VLa0?;-{>~jM+(bh2mfYfm3 ziRfG`FB!Y2LcSHd27Xb1N-*OgQyABBf5}QN4y}frzOG`g;0@`S! zO@Kq_48W&uqQVj7EW{$CQFh%993wgAgd^$bV$eX&0G^WtX2^^=1+RhpVfrwee^h zm<2cL*hSi@zXb4~$a276679UmYSG32f)qOA4+8$y*49d+PNnQQ0d|l+NUY-2UIF;u zB?z9Ae?j0USvQlA2$<>Zbe?tIENoaqL?(3YKoYld@s;9ukvlc{cOpPK*x002ovPDHLkV1jf9IsyOy diff --git a/packages/devtools_app/icons/widget-select-lgrey.png b/packages/devtools_app/icons/widget-select-lgrey.png deleted file mode 100644 index a13d87348f92c23740823f3052751df97c7ba528..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1333 zcmV-51(P-$r8x5cH^MMmA8Q)=f zlo~kzAqS+7QM)ZmF|5Ua@m~RZHXcupPEAcUEv2aMo9ha&6e&g7Q7fCToIqQ!p^T&b zv$MZ$%;j>=27|$yWxR66GPVr~@m;qes~}wWKouTWbmfI+k(gXXyAX=Sp83g@*~4Vr zQ^?r{x|tB;0*c>u=XvkgnjDZRNZ1z-VSDD#lE3KPTsx;{2UsgHH)qVCk=tSy>x_XD z*mLG7q}fr7ea=*JSWgb%bomfn<*SHj`}{nelyQQYhl62nGMUL_v)Kpa%(YWXJCIDK z--8LSb5UsH0~ojRcTtEH=qVJ6=W(B~oLZvXWjZMbu=IyalfG4ESN=x(yaV0n6$?&c zNFOa0m5bOHPf9Q?Ar*FjT`6%7ILNtC18)2MBp8WAE_0kWNFT<&m_SNB?}cC30d}Rt z1!S;v^}D00N)L>`;67&NJ@UB|zK%FOpPxGhdHo_XrB*;hV4Y~1Mde7ZfT&;@I_#?( zpvOr@@pVF-#$8}Slz$aCKnks`EnVH+-G7K0ZKYcUDMSPL{69lhqh!XbzyW5ixd-it zbTwz3E8+lhoZZl>rU-hYb@<4;n;9hg)ZGC>RMTRFfr`BkM{ghCaSPryM05BGikP%L z(hN4u6^KBfX%Z3t9c{;ND0ujEsC~jnC~Z3l{M}EG6>O|S-H3KVuf*T$U8-!~OBkPL z7x|8kjv@?R^2Hfd_5`B5htpL;(0_*28mz>-z1MvOn6l2!&iP8?7me^A0ko#rB6{JU z+(i1FwjhLt%i=&a&AQ%u4UQ$O^Vl0d1NU-UTg!SBuv!rNo%cH5_nh~><(~R? zp7VVEpELL4+;{r=n$he)Z|y+4-5v#hM{ag=au>**|Nm=%Yhypyl457cGY$q*NR9-s&g2v=d;SKP{8`L3U=R{ z*wn}bhDDW$#wJM6fN1Q7Z~aOyGT$N*e)D}}T!%T|JXQUsNbn3iE%3lMVJ|cwe$^P_ zv^woeTJ`INOK1Uv##B-vaxXL>_#WZLT^K@K`gW@U@r7o)LuJMahGh~WSwD1y}h0000.from( extensions.toggleSelectWidgetMode, title: 'Select widget mode', - iconAsset: 'icons/widget-select-white.png', + iconData: CupertinoIcons.cursor_rays, gaScreenName: gac.inspector, gaItem: gac.selectWidgetMode, tooltip: 'Toggle select widget mode', diff --git a/packages/devtools_app/pubspec.yaml b/packages/devtools_app/pubspec.yaml index dc888a41e21..73e6bb61e2c 100644 --- a/packages/devtools_app/pubspec.yaml +++ b/packages/devtools_app/pubspec.yaml @@ -20,6 +20,7 @@ resolution: workspace dependencies: async: ^2.0.0 collection: ^1.15.0 + cupertino_icons: ^1.0.0 dap: ^1.1.0 dds_service_extensions: ^2.0.0 devtools_app_shared: diff --git a/packages/devtools_app/test/test_infra/goldens/integration_animated_physical_model_selected.png b/packages/devtools_app/test/test_infra/goldens/integration_animated_physical_model_selected.png index af266ce6aea684e46f16109e5beb969fb5f2c75d..346fae48fce0edc6239875e561a3b0b730aa5473 100644 GIT binary patch literal 57377 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
    YFP>6dusJ8vS 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 RrQ@^Qwk2}2P!Ft literal 35462 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 NeH~-%l1n%4{Xe`cVWt28 literal 61097 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 ~`g2Zm!4=CLjPNKUa_k~+;rGSv zcr@5W{N#|Y&OuwVti(co?jIa@5}X>{i2wswL|Pjy?D5R!Pw_T71%ZJMhpUk&`-e|NGo1}J*EH^hZCp%lx zph;$pbYg#hzZ$n8h}RD5@ie>9@A0-a-_P98%K|be8!CE~Rcinze|e?-ipcavY1uTY z*NK^+GC}vi)Za^`>Qrn>G%SR)pm7Se=9{8NNP<-F&SsLo*gBQy=xdqDN zO_suYKg8n%F-+Y_!n%@@zBxHLole=1;&)vO6fyasA6ie)Rk@gXG=|`Kcq+0ybSR{h zsk)@_vIwl+q+OH3>dMLoQ*BEdo8kU+!x58E;ZODTQ}gPV2{VVt(*a-UXOvZ2`*_^( zL1uCBz%SI{|m6eqhhFI5tLhCK9ZXicZLOYyfAwJyOyP<(m?TmSoHWj;LX4M;Y7@LKK zg)8?_>+3_oyi<92gNR>KC=?prbvDcf%sMNJW5ATK5F8r}9*5ma+u5H#D|dHyb1A4A z6lxmocV3eXA3;W1#DVqGc=YH|qpHj)nU8XC+(bimZLNICi|+of=V;T+xmiNna+P4% zm%dFs(yWlMO3;}(Zdb$ivC*U_>f-eqH;^ltNb~|bOct!SKdp$a=;6u}i{7#gvE-Pi zimy(edGlz}1wo8ouES;N3S`R-!;ig71J)IjDZ9Hw!kCF|uI?bwbW%*U@rH}rtcS|4?VQ6~qqkLK1XC$? z@><=|qDu|hmp!2nhdRy{Ib3n%wjLjR<>(0PV1KcGu4Z8$7&1deJmnX$>U}Q}Rvonm zSLt@$gaj}Xy#V;#yB6@GTIkth?V89}*&gVjhU}c2Cjct7v`AuSh;222%eku% z_i@GH#Pb+19d%9p?9R@M-p9C#P9(a0!GW2*x6l@bd!i3O5SRXK$o%Cdj(Ln=?~a)RePEzu?glomJ(;7#=v)OtRd+KM0UY zHt)2TYK_Z!KluDejHLa9pHVv!&Bc0!AW0XV{oZ1=FJv{l~ihCUmkl&7_ zIV@io5o5wnPVb#m+P?XYh&xpvj4SinN5?(1jsx&fT|*;k<=U%+XXGS24{ek|xTdZi z34*f_!40jU5nl7{MGUv|Dp^@+>9U!qr!sJKCGyelFDy0@i>hgAes{siFogGe+~tby zx&!actQBfV@>sRt;pUd1@Pd!2FkGA5hK{ufn?qz?+l?v%5IP4P8XDMXr3`*p4j+{# zL6q}YZA{S5qdn?m_vesk59jUfE_HSF^j_}`FIj?bAmaPs!)Z$?_CoSDiImc5{5sJ+ zGO0S!(9%iO8u`77`N^i|@bxaVm^~CRA6N%Kq)iS3du+3CRH! z{n$3wmm(@7FuCF+E^Nd)|wFZ|X;7>Ef*yrGH<6*BfuL~k8I)L9sg27z8zm0Xfg8R$IIUu&ppFS8bI54 zUrGID+}o)*IJ$knyt;Hde9eGHdrF$nuT7KR#-l_pDf$_g3|(6%{QOe6EM>RV4# z+}*3<;^Nem!{8rz-@pH7h#^%GqMck zwb9?=mYfgErlT0D@`P!r0U5Nqwl=St2s!)q@hxC0b>SC(#e4K~SjsTrJX$uyY%n}b z4Q$Qb=&r~W2SVfRH}zn@2nR?Q(*SpwNgEL`1oy5oDUQ1=!ME%IE3*0uKAfGIIbwed z(C?({u{eMQgB^^C9M2P7-R6$or?Ijk)OB=Hz)_@5{A}X$eK|qb@{Xl#%kk3eST@4i z`6M)>c?lgtAc}wy$ORk{Xj=9rzkTKYw&!EzgRzHz|$z+M`$iivJGQs~Wd zH+bLRG!^!N6jyb>t9aIV3XoTqo5I@WBBxOiy%o5wxy_(;bI9{EO&nxIlw3idFE=SO zTzd+@3xQ0dAoNLk5|C-%&J#9vFikdsOaG$JBY=|c$lkegCzkC@yM=Cr&436_zSrp{ zq?if@xU7W>0g_p?j7yr0A1Grax-Ca4wY`lb| zr=tyDHD|n##cDpY$8zJnbOfV%aAo4tQ-S|3_3t;ust5YNKmYsQE_|BoR}lC63$cDc zsQv!q*SoB=7|DO1VW2)C`QK;4oc^yhWWX5g>EQuDD!{X3!BQXwy5IFg-x=Ru*jct{ zIlzO_gi3?>$=BBx_{VQf+Tm$aQwBhux;QR_Fw~s8)1Ca!==vKM96IJUfmLU8qU|;f zb};MWR&aK5%F4`?1|I#)nKQs{Zn+78e-2f89ef08u{{ff&jZ}oiTsB~Mlu2M2`C>R zs2%Hys2|%+y-ff|EMRc_#Q*9Hpwx7*H2fpQus= zQwDuo(6SP?rPvohLo2HYi?}#$3zg2EP(UgJL&G2ot^spk9wRhQXfW(DAZ7sZ6`lrk zH3rkSdyz@%HVL4)^zkdl&aPxwhQBVX1wi2;Kz4RSFm^3%-*H9&z?h$(4={oz;2Kma zexVHfrD^?ubi>D7%&HjxfDmc(G9;VFWyHnD$M)aEUtqkvx~d{A?GFO!xKa`#g#k4= zx%YsP0Cq6$qcwqj#9szkA^Wu^76TbqZpzxzC7WwUmD^4i)Yb|~DdOiD=E6H+ms)N! zxtP@pRC44BuU_=GZiBNI4e!m0{5^1N)HfooVJ$;E#qI>KY~!4nd~A6 z7no0B`p%vVq^71`C3s3zE`3IDh0lfMw1`D~z#W36a{F<@V-1>%PwO!s2zT1tYDw$=IaQtf&p(n?~vBc6|0Q{ zenoUc>R^N4K&GakC29xr5OIXE!zSGA_dgbtTH3+L3Pr^5hAFtbr_u z^Dmx#lT%PIm3xZ!i&S(l?-v#CZ?D8S2YP`@)7{C*VR7D@@edtc?B<;w>`An~iBJMC zt=t-sAx0PWQ>{0{A}2MKe$ib^NMBzcyDY8bR0?)GB$ z!1VDE=A$);vCNi1tXVM$?Ma|7^>D6R-wiKy+q{-$PPB^f)FKCLoS=7z>Y-;+$cSB&ANu0yljR7(!@BPBW5H|giix{3 z$02?EhjqVQkvHDQ3=ZNUMb+fSX!EZngKsfw_?*}2VftMA?b4tJq zrKH?01G1Hp^4JE17ehlWnGtxi_yutJ$pr;$u^B6sg{InIxlf5B{wO`9Dg}hvVC{rlJ3IRwo+XgM;>4&AV&_4CWPqx+5pUW zL5-VYLFnIL9bCnqdn^(+QhdKkui#Jbz)OLD1KTWJ#q%yTsydX#(g4%}ZGBPW%|!OZ zLipeIA&_hk!~q^I27xyZVj9{F&^j9EUUX{tO?KRgRpc?qS=4=V!MSfQrkCRPkZ|}o z-Acx95M6F9h-N$%A~hXfi2nN>*c6GD1Y`VP#ji(@2ivM+6Tg5N{#49zWfz`XqPr(_ zd@!CcuEcWs;*&X6bY75!RxORZsdC z#NoTU$np9%{PgI>*cMK=}0Nx)zt6f1x zii{?#u=oVw=nA!PYc+*>Y|-l?y5%nc1H_#FA10Z*aDXT{I5;Oaw`8ciyj-Kite2)Z zkN%})3nI}Yoiz`=ZY0~Ez||0vyMrv&zQclkfaC^U_)JtxLvj2UdH(v2xegqv0VR|? z+TWj|o~totSz|ZTc4Yls+}prr2K*pD(0p6<^zv{~)1Ytvlau{gt7F)}`$ zV>kL)KNm#4Mrp-$ntmijlOi8P6s<0v4pi6aEY$)X{yluYIZ!FDX{xHGj*pMWAXisc z2fu&kcs}OXT_=EP878S1o1h%3VlQ9iWmF2esiIfw7BE~0YjOz&p-NVL{a2~3=JDPn z?-&Y7-ccL43~eS4t3H;8Rd-ik`ajea-(T3v3wT~Jm&bOhHU>GIr~P2w-g9)Yzo9() zhf>4SuW&epeN7#$ptK=7pAyVKE8ijG7lZm|u+Q|K@Fg!d!>l({C#kpA4xTla zZ)_0pV5HEai)^fk>fs?K<mjF4w(6U$k>P)UP) zzIqjnd!d2)J1HM;3%L_e zOZa27mv>Qt;HpHK@3$ChmhFjZWZE0`2X!3!rvKABnGBM{cd1)Y#*7;3qftAV4VGJH znkI^&n|T{q`J{m@UOh#nK``;o|8XBqs52c}5!KBsmxWp#dbsqC##k~CktzOg7%aw* zAV9EMTe=Lk&26(-O1!MVV7&s#r8>t2^QFV@YAOL{r+89iv@biUfDN%;viTPeL&Rc1 zq8#Y1@#@Oz@R{vir@^IUaWjiKU0Z|=Y^(9X&g`n0b%m(u%uSE4k32KcGX1FIU9;`$MJ+KZRsJe@b*=hNGiRPp9G8onH|RZOCKkXHE% z)cCDa{0oEdsY|#pjsvh=pYbMxN_-3XA?*s~@V%?&`Bwj1dsfO*>y+edJZ~{0bR5lq z#k)wl0WbG4c6KfUlr~7c#qn7A3E2?G>tIJ7UO!mjW!c+SrMIcTm@F+L&n&Iszh_=VaB0CneGbjSf#vep;N$qCrfgrO0W?SA_9b_~0eVJ+(<KAk76ZA#$8f?hgBQ!h83e6Ai`o7=o2y)vjB z$(*~i>@DZCWM-EB61Ngw?lapNd9TcJC?^I9+=ZV|lIo%(jq?5N;A|26C{30e7*Pza zY1ZjhqU3^7GC+sFNRVBYblSljw>_oJ z5pw-ERt-i(E6!L~D4{tS98NjTZAGYs!z1TB@okr*eN(GZuE8GI1&s618EK2JoI|l} z7cQLNl|+wV1b0I7AL)z0q*_I#Paqj#2 zigV~}(DSws>ec1t(#ff%Z9<@P>XmV1RMcH9YJe|xV}z`8l3-@uJ!|KB?%WHL`HW`< z=CpODdIct=xiU`6RdZ9lQB}+k#_L3J_s@!AT~{Y$yyy`vwdXQ}_tJZ5i{bk0t_=BR zOkcJL%q_D_S5&J;`;|~(y?rM%Jgv;OtmB=IfXB2?M$~+;+N43K$q^R!l8lPCTnQ1pF(=8-AXI zuJjjLj1{8@6POc!n#?Ess@OAur=iCPr&hCBZjyvjJ>zW4AHdVU zK2+hde1J?EFjE{iJVs3uX|}xk`tW&)9Icfa2U%a!jh;S6Vp<%M9B0ryD)Qr@P+m+~ zcD>TNYF1Jq`>?ZgVpe(B%@PIEBwg1;r_YudH!|u7;t+s) zwxTCAZZ9eH>~feJ?n+4njZAG+DXx9Eny9cTRBJtamh8?-t^2u^ye8uBffa)2C%Rfl zL{oSgzbTYjb7jP|%R?i@r$2EcH zCm-c08^wFYQdMKu3zb;zI9v|FaIR%c@=xpLvLb4zZ1EK4?tovwsOKZY`sB*~n}K|@Y4>6CTVFYCy`Le5!{Da$cI5Yx&0XP&8>hx%Zwus} z3JeEBvKmV$ev2(IuyzbtzNL{?=`8?C9Bxrs;T889@Aw6ahf{CQfY1FV%U2SbrzkVs z_P(B$CY8^|OJ5K^c<>2e_&|KOWl}@2Hq?c@SblTANoFZFHF%2LN>q=wDox*do7h2X*}c4CWECUT%_&Z@&Fw(OEK8_!;?^++SaYhmffHO+P!BWX;U* zf`f0xin-U<`Z5a)1dZcUP8QayJdiUKnxk`{C}22C7Ev4<vm?i(~Ef zq?=L8Ojik8^62PjR&}+2uCB7Hi-hdDAi25ObdzS?E~sf^>!NiN>L2_D>}Ki)pi)|{+#@1pd7&>> z1k$Ft8u`UTE;Eh3;wJ+$EG+S*7~jQ-tq|qbAYccv?$>9^1DQ&i*6YTJ9;+uoWFCXC z0?Y*8%h7@%yvYw|NQAufy6%=ILncxQIU921w zoh;z&u+UL^PwkMA;Jz^^j8t_k z;PRSIwf8y-^9_(1aDqB8F&;=PNgDy~F^Jp47tPV&)?DX;B`zf#O?pw$=U)k^#Js>X$N-MJl z6a{%q%LtQji<05v9PV{#40I6>QnbQLKUatR52>(iOnEkKA_MwS*BYf!OX)B0c(4j1 zhNCdcjSq+hea)ztrjzY-S?)Zz8qM4zDq)(jQ^mSf<@8OY1-thu-NOCKoPF@tMDrz< z7wcrb0q4)Y@c`*Ab=7Uzx~<3mb;IM2yVEc~h7}NPgMC;sZw)$hny_!nF4(vs zaI`n4u5zv2X$6c45~jZPmNfA|NJXp9g6{*zZE&jfy;H5LGnJWqa)uhMv_Qz$Y&ZHh z_-p6hq(2BP93JV3&F(PWuZd1uIb82J7iqa&)|P2%IK~j!ixMq&URgA&SWYjbU8qE* zsWcp!wP=e+U7;D`m@57nii6QmiBZ)Sh`#0HOCU!sC7fp}FW>k+oUiMQu;#Vu2!GFG z(t25Ve_pkEF%Bggp5(Q~48mja{e5@ra7F#6OY8^5E^Fp@2y_PIVbGm0zHy9Om$7h2 z1)gDPe<&#u{m{ViWhcfFWk%#QY|t|jV6pfu zRsg%~ehMiq=Y%)cUnCw3+s&GHC7dRg#_}8F|JyVKG8&(#oHBcwEb;BNbGD32Qp)#1 zs?f|#8E|y{NpApu(~HC+qvgV**c+ffd=Lo1!Lgelt@2dL3eWKPynMl!V9xl_obhu^ z&qDUMqf z5UxnTQ>t@Y=73C8i5YFi?5q!i#qL_uAfVyR2M0kFMDEH!E+{uiE2RPsPOPVsJ&Y(e z5l?uOl)vn7x?u9c75lu#NSv|D*qVL{DxDJvDuVw#VwTrVldZocJ$Fon+WY}A$vX^w z&z$6cj%1FRnfWO&pZYFiyrA&fsZY`{vTaU-k1CvjRokHmRQAw%{e1P%b}H}sy$y9) zS=qo`>1roeS1aVObvXhD!XQ7Rn!0J!07%V~=HWp^yG^RXx{z0FVzN<@s!hmgL4>K%$8jF?CVMEiON3v22~~fWZJ`J7rb5Ic3ixL zZRI_JgKQ~_ET~2v#;-zmJnzam(MtWy#B#bbk@Tv6sXNK{mTHF60B|MnOPixtv8QwK z-L^)%(cfix)psq?t7ROThiZa_XbS#bm@g8u&vzs;XCwq)HM@a<#4rI07T*pqN!8Vc z=0L50!iSk^udZFT1eT!GxTQ{Dy;OCy4nl#RRuXuQP zc!J^)A>9@hz0%t{oUPTp#z-xrxpMpw5FwV{?N$JQYftFC4#vuQxNM@R`U{F z#b==#C={Sv;}#9*S%~Uk4>nE({x9w3Ms?BGX@5Zz?3Njb1H;NeM(xs#q;$`XDpgR& zEn7%vpUa|DZ1(5XXSY=a<1=pZW|{M*W$_INw+WnW#N$)K0s0ql)T|AgH9yfZGt;c~ zRbstkBsPQps(g?uvDw5qGF=^=Qp+J0UF#ccdVCDYqXsB*OPM#iBG5J7S_LLrquf%?~l@#F8=={@ni}=NZpoyKHvQHRkPMD$;?NR zV^oqK{=)`j0UIEFk(nr|(|r%~^=s2tRep^B4O~+|(Z<5OyjW3nwGPOzysxt9j^nW? zB*f{h@mgP-XF~nYot3_H_wF^dQo%{bytqG7b2sI~$v_t=B`Ve!KA{9Yt=i-i2j*nH ze?Vn2TZQK`)kH=|Fe`q0sw~o!4fEPuq|}0L$Os)3viZt~GAL1m{N?tucd^plFH_u7=ypwOu>Q&8%Bc!WXU%q56+v21N0sr04$*W~e-g>ba9)}T&UJWFeFdtega zGi$>;>GTGyq~Co+l_TRXI8EAW4%~z;jV)QrQQLpyh8^Bp#DPTXsYjA6=kM*(|8k7v zLqEf2f56ZAU-LhA{ahEOa_~l(u?=neooHH}6w0M2v+Cbt{&M;u?C78pIhLM{7~f?nne2^x>dalDjtPx@$dbyL6BnU z+cV8GSkxJGXbQP)j@g3Bf4d0!U2jkT-m&g-Mf*kEgbd!OaTHylWqr!|I-p5fk;>xq zANv4#uE^CGF#h0m%5G2;pHLd#9=^4w4`09A%+syV07W$7QTR+Qs635N>%&hrZG zirt<};AUe0eQ+`#$HxX!S%>v9CH$9!BTcColyGpjZ2uH9Rt))Vt2uua4}PgMF}t`p zGb7P*frW_pF4r&8AAg^ii_8nYr*BRM9vW`G4(#;xnbiWddw@9;-u^}b($BY$p!gSn z13fk=0*M<&xpCBW<9W<2eds~zR@Js&-uvqsR2JHKUuJ)V&Hj8!{zvS>pdCbvEUnM} zY07lIn_MaV=+P^D*_6Ixx3g#P8mJX2vzyUoVPb06B2Y77HgA-ufaSX`6vP{To1Q6T z5>T%StUpI>rb&y`mdlP$)J$cipA0P_p06AKCtP-s?AN^8Z_+yXUk@B_SYC3iA#<_& z@ZH`sRLh*{3V(wU&n6dAC?!V^9NsZ7Tzzh$ zfbaeqC!j@a$9{^?`;y&!WWTnmnAKkt>Hbh>qdcE6WyN<_X%m+cwMBiFjM&p7H_js^ zgs_O<&UOPvp|VH1HBIG+-a;aCeN_(A_1sH`ma9dEy&EDTJpAXcirB9{!XCW3UXI{> zX))s7Ywe`0v>N(#WxM*hMkEy4f1(_Lx+v+?PI_EAX<)(U_wqo$vvuUty4<$f2TY;o zne2;t4cwp^YFa1~y+d)>3KQM*lxpDK z8Q|L&9^lJ%tgVFxbfT9YjKD;B6j$f>!Vya0L=8BbHt)L>HMbcP}HH3@hs-@3Wou-w^c52C8~WpJS*U**Imon187LJ0BIz$Ejp_SRW0YhACGmp z9l&#C=ZCYWw`sD}FNp%L&Ad@|DYFx#fkRTHoXMkw|HA|Sum=^4N=l*f15^1t6^QiL zuOEYu^@?`={~HZ_+<1fSJ2BKQetj3;zC)XNDkVro5W%Ok3B<#%PB}J$coLYTluI-J z)4+?*=L|>Q&irP~mKl1p8qRGz37WFLR(! zn9?5KL~DMZ;$43j*1A-w^^ZNEa}2+!_%S%P{A@)>htF&csy?^OYGkAAU}r$7S4J3r zAIDTMcXx@g{JCxdrG-BQfy73y*`*j?e({Oq#Y|_F&upJGZMOmk{u{ezX^u>SOPX&< z|8!EU1hn^1>JsyAR~0Cu!dD;$MG+*NX!Hs*5iu5uMY@>`jLMOBGq3b?0dGY4#|`=jTvKy1>Sn)D?Lks-w7@{{ z(jCE|=n%e6}8sT zk|C!^fM-c5D#91$mX8DQY`MEOb}Cf-Qy5#r!Nq)o!yx$qs{Y}17ps}Z5~p5aS5WrE zzT%AEXt8p4R0%HU%UmZY_xpX2O5M$HrU~+yWdcwA{NF~dzdM156?8fAJq590Zg%!l z5RHBVqj$D6Hy^dCGSvo8-IyghXW-#f9)MGs1@+iCl1w4p|4uJMQ3ByZP<*61TKN?` zwTR`*xA>Rn7RdP%3=w*C(0=%qR8p+3es$FngmLVP)jU?iX?1_9Eq)E_nkjEWrA?w5 z*3B44mmG7JfF=<<&tm~u#ZQPw{tVwo&HkDq)uoex7C$#b;aLX7UE+AD+$1YT{=)FqaW;qpYqz6lN;uy78}Gg(tz-Z=a3*lbafwFFmC~n~!Tlpq_*; z_6YDT;8vr1>{1An6UZifyZ!znUWBNp5e;3I^q3v{hXP zGhW_%<#^}&)o&#$&0FKTWAA2Eq^&zslr$v#x_k_}k|8I_zfI6yeD)afD#@sK=h@g>vdLH6QbH{X;@xd$Cgac=<%j zcqL{E7wz4Q$EBh}ec_}kY0O?f6sYZc(fZmI1o8iV)n#q8XuhP$pZ-buJ3X6)5o<)$ z25Ncg6weCo$H4Ua2(u&T%t*t2fvX1EP5UjWxEN=ZH*UA(=g*(Th@K?jn%VJ8_>toL zc9kUjx^Tm9)C{3h-#$@;Z*QS7plmBb(;%P_x{bJmYQT2eww1&BX`}NE4I}4Fuj2>0 zmG_TCZA_Ctv81gnDy6rztqttnRFaC>pRMg)SGmhL-2dv0zp*7YQ|U)yTvEuXbHptT z*vV=6LoIDTFfe;(Kp4L#WmJ4ViRWv69XE>pxyvXeA#_~9IM;i;S{Uthv;;$s6dh6@ zGeBqJ6tb!BA?=LMGihkDMZX6n0B)<kgHmf_g;FgRc*Po4XfF0Nnmhnle+ANH;}p!O8xNrA5(Gz(W;K=%P*O2 zi(yq(o$D(*gL<`lPd?@0uZ2L&4J;HDg}nG?I~j8ZmIim6gpSI@bBBe&>tgsCC;XkS^RwrlWFzb7(tu#?+8?#xK*$`cMWTgaSpF)>Y znhXqyMtHE7U1s$2G2SJj#!6A~{d6O{cu%xGr>u;}WxZPX?AfWh=ZM$`X2vgGJly0& zjE@_;l*gg-IR$m6<|;e&2N0g>PEJk?1){Jcub@zPzK&>QUUnPGXdol_!@W6pDSN|# zgS>o#oZj?g-7WBh_MeSX7w)1sI{?Rn_cAoVhtUhE_Ne3*-b;Y1}ZfhMyG5U9CT|SLHzD48da34I! zUy(U3o!KRvy(%9~!KUqw90fsvU72 z2Q*2Z8(M(pV=RE}%}CE}!(j~ehf{U5?`lv-cC%Q=rJfenikGr_v^;w>6f;y5GX@Ss zL)vo~aqOX5amLNwPb3@ZQhfd%wb40;uJzsVw(t7-J~X3$&2bQ3dY4hd@%3!WYd>0C zQ`_y^vlx`j(R3wCq$D5bX|fU?Ud^D#pROJr^0wY+*ps#gk3R8vV|O0Qa7Mq^YJhs{ zxlTG4nf2o44)#~nY0vyA?f8DbKQ2M5`$C|07fS;9$w2hNJ;VJ7@beeaHx!<(p&FR$ z4;DmwiV2hiekeZGABX3gEftl&sYJ~*zkBE9>>_u^&(Edplekg~dZgiw!7+BEMY91b z;kDri@2LLo8zp9%S2-RPh3xF?G@C~2{{z_KBAdzT(b5&OxvehGVw*oTXUS~oJp4s{ zcbSI8`8ehO#wE}4pO`opr}~mcJfTpOr*P2=`AgS8u2?}GjGMO#w{NvrDv{eHNQV5vA7Gwln%)s`qyBDU^XPd?yy%$M?dXSP=&{`Zg@A@+7kx)R8;K9E zi{)JOeO$ZK-_eYI@L)iF{T!r!w)fv3K*$o^jv!_C3fgukYz&Y~C&3%vmu02%sX$Lc zfJk}n*1}rG>7_$jK?$#f-1|?_dHR`(iGjK{W8szcg(z&!?kR}HrWsY(ATr5~6Zz{$ zLz0-7xgxET~$HYwtcryo?-9oB4FSGZn+C*p}F^Lz}`=!FK!hll1;#(H3LQz?Rv@ z!llKbhh)OK_x5ZVL1?2M7q#Xn#1 zIyVcC;NVvYp0oe6Nn41oVJ0X4Ch(SUID2ZRl|bM%@Tim~n03 zBIB;tN|CRjXw{~F-}rd-d}eyO=}cLA`klZQ<2eOouf)*dC@1W7@b&M36 z*=m8nW!LBN#1|aJHb*#hPQtQxR=MLGb_+#nuy&$ZuwajB+SPoxN6pcK4sygSe_9kh ztW<(Fv_+GU#6yp&v-)jae=UCwU2sQ0a0X3dKwr>_7Lb8$`}xx@W&G>cuWF|P&3cZQ zUR?BTMqB6SbLzHW(TUXdEvC_T3NpQx?lR6r!JbZ?A6}A5dbfc_=9a^T|G}KPkyC;D zG=6AhQ!(<{f2Aw(@zYJrxGh#GNCA# zlHMNyRaWXxNO0S;YmQV>tC_r_8QwZWYaZ&ts;1hdSc~ZTt@4xr-awr7eq`^COe2@P7(K|De{9z z7zGIl!tZFrtxe&WkEYVmRzhL|gQ5wxJzOwsF+4ED0U6BBY@l=%-Ld;s=0a$gyBe6+ zon9>%DQtZfYrdDm$Y_7^`jk1V`)9O0ogB8RAdL@4)%D@^8frw!Cx z=Z^Q1-n}!owg_0)wUMpT1$K*%m;YwP!F!D9Zt%LfeW4+m32^qk7B|n68q7^$dW9 zWO(gJTX%w3FKcSU-vgOB9=Gn5n?F@x_OF^MIJufl{tBGG#9yV>1q|X}d<_Qg)9N%c-yCV+OB($|5RX$jzz?3# z`}z4rO_sxskNDhv{s`}tOIP{U)6;5QVI2x`Qj!RK>{C#)5ulRo)Mv6WRmT`Y?fK9? z6vVLaK72^`PE(&AarLGWJ<^-SJ{kUq82Am=w1t1|3NV;Dsxk5J=Z>d|RmU`^DGP&# zqoUMy)s^s*?!r&{ZUr!6%P5o~_?@Crt!~`!8zFIRp$19sdZ8=1*=tDR-J`BbY-bl} zqz<^9>^wXk)uPm`AOglkcSpO(ZL=fb&lWM5ILxY`uM(n8wNHx z>d0gKeW6cT&wO*|ohytslN2PbYAyhOQ0z4`ZV)C94-O5zgfA8TbzEm&;_Nnq?#%7A zFCBXid3HXIiy$SY4XNA;uyoa<#fK)Z57JrxMDso`^~j}yWG9#P_i?==RNO#zW=}8^Ko73b;YpvUTZz& zzVGK*Yj3Zv30v1#!=s)q0RS0mEOyxA-Z-&wqI>sFI1t<9O1x<)f&b)EQGo4Hq7V!IeC z7HMB$gMc@KSWZ+fcC_pHo#=MLWwyB!cRK5_^~^}xtnDhhmfN|-T&W*?nrWj{C%%>p zy97HxlPBe47MZlUW|^6^aBR`X5UE6 zqOWKkhTpLL2v8eg*y;JOd)0hq!mt~7Lx5R&u9YDqnpdw{A7o}qXU;9&ry+xxTy%V| znyrUjPUQ)~Dn`_4pa#F_gn1Ocok@yyA6%4-p2#A%c=5A8m`|YJ8(o*l#p`JDUpNl` zb;(TYSPA}E$*oGM1LM>;o+W_ot^91j7#%3MFf=r8Ol>tk^Qm1uJ4W7V*ZK43xdk#|7S3BH>343<%oL5QNlfh8|;?x>Gc27RPP*?UQjBAAtttZ0Vj0`?FJiPitU0rBy@oACLiqOaF8jq|l z_60_ynj1kl=-eGPWp2;6SU=;2r2wR<6GP#s)`+qi^;RwU`L#|+@cdbaJ;sig5v`tYP#W9p>#{OG>5 zIh8*sC{T2u!>I|I;~29-_<_k``u;YrNnh^9I7Jr;yF3f^f06KB?C?Aoc@Q#ZPYUxqATr9P$h-_;T#Ul{#~N`a|JeP-k!zqaEqEZc zKw@Ih&4+-+7WF5@F9oWY3cPx~!oR}(w%Oz7FDX{Ia>ycrNOKIAyy;yT(m^7LReDUzMhY! z5I}NetS`-nio(Z^HL`+a=a@9r!qj5&$ke0&y(ptWMktg!;w_7+CO&?Qf&RaYuV26V zIS(|HK01Nri!kj7bv9hE`j7W%pEmRMZr;a>{MH`AMy``450|!6^uGhc=qsrj#3=>PJlDGLVykJSpN^Y*!&-vl02+uFnT6GL}W6itcx>*9tjs{@6SR*vT|K4=~WCLfTEM3sPet zSpy%Ro^q%ZH(b{^Ic{uP@4alB_*@_huU)l808>k_LMkSU8T7J21_Bdp?SA=3Ij8_( zkH6Z2T@AK4doVp8yD(>0-NPaF(VT-)f#CnD`L5&T%L4PtaF;`X1Yn73R$>;jiqW=| z3jAw4HcUrON>Fg}^-9URsYMelV-u0-2YuHZK12fi+mHemKJf`odkM5j&D-T@F>7eE z)28;@dmnfEcN+j_m`<<#5M{{A#g(Xap*hYhePgMaLsz4dlhewyG&<}9M*g7<5j_sR zyKACcQ%4-V`PEk6y}Hx${;w2TZ5}vxsbr=uA217QvrJc=HWKYLP25a(mzkz-vU#Y{8!?>k=a-{0rrB)6T)k~8 z8;w0q7`Y7X14;TGLX;A2@?@^Us7f#A(TG#wFDWU(Td!EL;?!#4*!h6nn3I)NI%qrI z-HwF@2jbqX@Nq zCF98-4f3#!YH?xKW1~qQ4Y8y5%4Ty|dgaySmv@8Ld0gC~@5`OA=?DK&kjJ?W9z0lS z*Gly9*`nlnsf#`~b{TSzYI>yY4m*{&fa>bhuV1Z9$7sXt9^|HUOYX^Br`}r|H_1oF zXJkxI7EdZupK8z#EGU2AeeNMhqK=N&TMOLl%T;n&5MKh3=+k`B+}u2%!{^&|0sjvl z(uH|`!B4cev~14lQ25n!>b20*v0oPK{iPO?Gas@Nqwm@yW1del%s-17HW;ZMDJO@< z&AM(;o<5HJF>xVein7rH(uSr64MK!9~KjxbD>SCKP$Kzn+0j(QkT3S5gWJWDh;PJLvF!;jxyT zW(WTXa3Dktmf^WY;j&dlFK9LQ#^z}m)WR-SY2e=V=y2Y_HjV>X&GHnWA48 zt`(0rmXmi-3Ea2~vnvFA^*e0x>Z%^xmf%Qti=GGJ;eO8iNsT?DT&3jx6+^{hW@JoK zV^)^xyAA6;rUXRB=obxVR0?^Ibk_q25c(x)i|mk1$e592fgl;fP<}NRVjNm4S-9^( zf=zw?p~+)9ojz|HcZ5=~ef#nTM}&*Is*)O0xOQPA5b5%}G_|HY&nb=6oQd`K^Mim; zS0}xa0(2ljPfVgPE>ey+kLD*nKeqjuyEh0ivdT?QEK7OlbdW^T)k(9V1V+Xhj6Y92 zVej8oA&}hB*`s@Sc51NS*|?nxq~gYLqfOM2V4bvRjl(HBdXQ&Vw|8~=Y%)97Kcnt? z;)}P#X#b3wd)&D(`eUyX8B=qiCZV;_42O~*c_ayh+}fl|WUUKe)c1byPe1-E)ol5S zobn@BchffK#`cwQL4jKW@7%c_&~H~r{elqQi$O!J_9uYwZWB#3lX_(0nLg-z1OFpq z9V?K&zv_tbdG7vFL{LrFBt}fLp*c(}u(38I`PIE2>xKmdA62KA)a7k&zFYM0kBk>- z$6mvxOoG^v(5a~80X=%;&y>*QV#et-WS(E!Xt~#o-_FBDKTRWGrWj?=;+uA+;HIvu=#n{ zXYa^Q>A8QmsI>m`wngm)&tnwsP_c+RU-li7qh`e312Gb^s*vDFefwfj=tQDk;L&v% zA{fo^Zw?>u0=$Gn$}8TkGYKX2MmfIO^I>oCL#9C$X~3qCs2wq``f0~;$wsx8%xa%^ zJ090ezRyI)%0@lYBQM6sNG~fwwUt%F%M;}DYM$K4a*Rs}Q?aRXe!AAC$3sulOXt~# z8m3BhRXswHcAeCKosne`V=7V=j+=IyhCbw$9MDGbC2LT7xfjn~IeKb% zMS1A@29Nl6AB#&vOhW&xn_Ab2*`+TLHnQ*7UTVfIfFoycOV-k5iNdL1Np=JOOX4zOl|989PFI zj}IA&bnQE)5G2{>Wfs!2r?zm{&lr=2OyCVB8y#)WF##gEAIFvecz@z~{OFOH?cf0Q zoo&+qNsM6M!9!UtIL`R2t47h!sxx?Tho|u(HEoQzqV{Ezjvl zV4&ELP|9?1@j&+!wRc^kZpNdw*ok>$UCH)DuaDoItLT3kUmJ$y&J&>1`<;jQ??kH* z-P^Sp!e(`Rx|Fm8X|m_FOS(2TpMMcudrri;aN4!Aep)mu`*7;>>F1BY)yPgoWJ^Jl z$(!{9u&g`krb0R}`d*9+CZU1FjE9X6$5zTF8=Rs*38m>PH%}(B+~5d1+ydw3<}7lc zb+^87fwf-E&rB8a&zZG;P#X|@`PuW~s%UPVN1kn)DM^IasWlQC>gEy_p;vq!0`E>@gwJpK7lZ-{CQhpd(cy=*p*DpICAe`?iOwyn@=4c6w?W=nuQdz?6hu31%74d z#>w;T7cYJkWN9?5Ig&SheIwehKx4=HMiu&)i(s7TmUQtA>Q5&YwT72wq9<^L-}d$G zC{xu;LR6J-%dBnW(k&{U!tNd(yk0UYDqCgS$0qJ7EatpVzb|ngazC7kvH^o5yvbkW z+RN4Y_4GkOejD{Z!Eb<`XU?gNRt2q5|cvv8W z>>%i=mV^?=gNx9DxqO8^z?15C(~HkwwFAjv+K9-OlvGrt3@2!I`8PtP>GbnwZQa@( zrsE&YSx^WjX}_{GLYqqPTwJvNK~}8?nLBH9wrT|6bfE5M9Ub=on-gt#0mURZSm6Ak z9JOrRJYUb>KE``zm{-w&^FV@foVtbS_)7@G{o9clZ&tkgmCxbR%WmKuI?1rFE6BLO zE*MHelFe7<^)}CUpi4x?q@4G%c~_n4sS=U@C};8+P^hCu(3?x!D1bH0@)prQ72H|! z=meiog!-IsO{FAp3pY1-n~RIRUu)GO6zq^V{%!NsUK4ZKV{#~o&;oDhl8>C;Q|bmxJBb&Wog1)TxL1s%Ez zgLbOn4}f?`8efZ@wep-B4c?L3Supv7!(_Vv&d6uDEibnx93-uT<(&tG2*@z2?Ci8qNzfjW>iM9BztIsU=g{48I=#9#1(`dN3;9Q!% z)wr6{%1oI1){(qO@$hwU_B+;8A6GpP#Mcm}&8Yos`|j?Cx_l#v^J?{qy?I)@4c;Ej z4l7_h`Luao^itJ?b+QaI=GfGE9jPJxAy7!jor|Lg_opn8Dj*mD=Ol~%A?pTM7!fjob@;NHpBPgoMrsPK0 zagg*pwOhJK-~23@w?Y1Dc(xL=ZP)51fZ3iy)2erwy86H==pTVThrO3Y7PWv+TE=fb zlX^_}jx``x=$(d>9LR7&O8`{n`DAS0od?aiZ z4tu*2VYMO25r3+>BmHIj9fmw8AL}F2EXnc{Z)!tE-*% z7(8xsyT@>1GPHRVzNPq1zYpxaP4IZS1%gOLJ*AVzT8uZZXFrpm6H2#>lvw)@jH=Lb zo;bHJ_k_dLq<;JDwzKHsl4(* zw!S5R-3k~)Tf5!Bk;L|TA#Mi296t}bMy~%o^ z*LY~)wbyy$)eWVa^J>h3#`1KEiE8_%$8E=Eq#KULRZF%zL-Ux|*ZUcbtcUs7LZR3D zROa8vw*Xlmy1o!949eWCF4zH(b^ZGFr^|V22=d(0(iL@Ypq&ufXo{xC2MWl*#*Z2a zaGfOF!=KVn0{HGmoJtQqoX2pR(zfZ{PLJlxrOx@HgBQsqw9`P#37)F=KCEw{sO}a<6>iPL97+tppKu2sp$nJ zT2w)yh1aWiA(|>f{1Z}DU9;;+a`Ide#Y@Ap|CG<|`S1oedZQ{)%lG{Dm*Rf>0s&bg zY}b}6H9a#E(Jmt+ll_&x0y}koBR@a*#BHli&{Z4;QhuP`kW>m$OIujJZw6}_wFBK< zrtV%17e9VV`S0B>ph| zgzf)?s!yvW>K^nHE!wpjvsGn_Ll1ZTaIVVT^|-hHWaxw_Xu z-_Oj+^6`hzxB*6Mc8Jv4F(Fg8v=42w5fptTSINs{7~JGWbb@1p?6B)FWt8SgP@GgF zD9Z3huK9-q+?Vpaa?hFnvICFM>24RxkG6cdkB z#FzFlokFcFnI++veq_ro4Q?h9(ve-EN{0gh0c zKnr`&a{vDQuLA>yu2^MdewPj!IEa@Bf;?M1RRpeI&nbnMYxG&!+iMirFRatDkP|qg zNK&rsfSpak1|(S+wfEIMHg|QEJ2~{})29bl$sa$S4h-^A-s<|P8(xP~^yCV(VZt%z zbCFR|`BwX>@9s%UNlQoPHnIW24fBjDALJ;Yqf3?0WmQPq%u>e`6dOPPMbE3~1zdRE z(y}|dHTwwCetHoptu-1?9(sB@|ErV>rGvZtmU1+-jVQX1-n^+*seMKnC{Vd2;3MJS zwG$dEFHkzxlGlrt|;@SfUd1xqWNcjQuwGCc6VkVxBf{POd ze!5V&;G=lS8zV%S7Zk+*w?4W@0D+5`jfd zjIzg-(ku-uJ?2fXQ-F#niXpwXov$&l+TPmo_X!R^83epAP0IA1QbvHQ(|R zvPH^?)r*6U(m)9ptRB=-ZCjQobce0Sp->fk0qHGu*J6(SU+m)LjezA@tQI7v0!L~p zrZ?pF#?F9FF3}Rs>K%aQp?AqkHHIv)rOLs-M4yVFQf!u>q4^G&CD$Dd7nj8mYVxJ6 z=GEDQly|j3l!H3;^l$R=n*da=w=pmn`A}c4oyqFcMSi8<7)CkYA_HxcE??ivl7T`b zXbLCm!4Y$tk?y)5exR6S49&a8R3s}YS4}rW#u$TU=6u4QqWuA6rd*&)qf#o~+15w{ z=T@TciD((s)IguwVtA#8l#~P5w9DkpuYG;Tj7&ws$e$}t{j0RW&e+h%YrGym&rY9U z*&1z-UQZYv(y$7?#0L$Zs8c3i{;p4=SI_6 zvOww6Q;*5eMzV5ysgZ;keR|xX-MO(eR+$n!+WT17i)S(E?$105_8`Ra2WY*1(5oKC z4^jM zykKSJvPEI+w2=?pkUXB|W9&Jeq(SOcnY@?Wy6D_`p&>Zj@r5GtzeIeNCCe}B6hAL+ zyk539Y9$6!?aNj2nRJNRk+2k`g3ci=tYkQsoYHH`tUNMfd$I;-t6+5Lw`&*2a>kh# zhcoJ{2lihJBJ80TkBI6LhoSWzPFR$LNwsZy4!fhbY2WyLyNP?>Ir8+qdwmN%r>xmH zXYUQ2;K9x&!`gBVPpz3d5)8$~X^3QvG_JzLo2E}7+yjX0hg!3*J8c?~6$&@Z-jNEC zyO@K(%!4wd*ZN;k76hgPjxb*>$XI`4lp@uZgKeu=UXlx5iGK!U&NJ6Gpno-N1k zGFR*4*U$zvGaw9=b5M{0G_;Z!8y#)v>NTWsUsDhMsj+9Y^O-#w>vxNti;+EKSy}5e z_hsb`*BaAUfAb$ABnw!*RC=u{OAS~3GsA;zcUtDTJ$e6ZpQOFNsh9bnX)!KtzbA@)wLMN!mpz`&;w(DvPRfA=Qf}w``B&*^N>X(5%JmcznAWW8(kF zgEad8LoE@oJVeSxT=`#-mQ0}Z%pCykpj5b&!Z|&6a#aK$$VqcQj&*&Iyl>Q-YAz7q z$Qb>WxCMo!veZ)56QjD^b*xj`;%pLYfJD)>p_i6++-bHI!?e%+KOjynJ==R9guMT* zf~cqVg5s$H&40$=CdFSz7uxuT9e@W&?Q#6=fQ7|4#f#!WJ{328eW9-&?lZmvQc;k~ z0jU7sMNWThN`1Aq^y^nWXbC?w123WrGPLLSll1JmbJ~5$5uY+!bRG#HJvWbum1WWj z3LD@B0p;CaKUk8HKkyzIf51Fqg^ZxisVqnd`mT(ZKg9W^r>9xA%dnggG{S?TVcyeG zd(X&X<*8W%d?&+^n&!{`Jz%EkXG^Am)rblS3dYqO@tDbne$=5MfH}M!h$yF((2>4y znPtw1E)*npKnn2CUhDnTdzP{K6Qh6p@ki9;qGj!OzN^-AgIhgOx5SUv<022zFr>Ol z_?PXA-`MNB7rIpqK#X(Tifyektd6ChJahcBo}P zLmFMB;`Q)QwFNX@!=^XuKo1GR?xCF3Hw-(H=6^DnAG5mWHY3}N>Pxg!B{d8+G*%Im z^y|&fxhX}3&IB6hiB2{f^kp^}MNB`}DfXQw@vMvJ70kCAMlS7WeQA(W3$W`F$QilG z*39ewI|Zd>@tcsn0n8>B2WNJ5BH-`-r%s(hD%`H0{s@MHq9-4;;PH55H=Mb(b^n9E zl}cMylit0vC7ZDC1Uiarm2vdwAMW@S%H$SH;Ck=PFepn+wHyawD&!`2j$M$SB1ltL z&3;$BGUx|1$RcM5`ta9mRm%N5s`Zp7Gc(hn^y4OsKLyhtz(w_W6oK+`^(E0~0#sz%H{=2{47yEVVjh3s|HlLP#5_UnP zUlSwef0w*&u!Z#Kfosv^aLm0rY7KE@R5)!g z!dt~)YUcLqwCy*1!e=)}<#l(i9Vgc8aY-ea9{hzNmiWy^uiPg*YL4O=9nD8gwp30U z8)YqAGO@XbbojBHgGsxC**|y+kXLz?HD?M0!F$BIb7@~94wFjvxad&r{bq(|3_#QR zkUNyETP?o3m{w&E$d}Pwi=D)HlW$GU_7dMWjY@h``=+KF1%&Cddt4w19WDH_534mz z^PtexU@F4PIxO!g4oppU{jp*g_V@)yc+ctjj31=h5GP*M)(~Ng{;+>9ueJtDC2@mP znG^P}k4?5?DrBmtbH=l;mnDSh*@tuYI&Z?<+@Ee3S^-Pq(B?T>NzU;eknQgB6}WW- zUI?iLyEnLw1aA%Ev&-GyF_G;;8XoSrZ@RQ&?^0qqY+4!sJPiS&-f9p?% z7e(+OsH4Dhp*d#R)hr8nhYkf2=%m-rV`D`+rW<6-DU3PZ?y)}J(zUZMv#5DBUJBl{ z2*$<6v_(MkJX{PTk!DNKlewbgx8EU%Am<>6G?ccswx;LhZ3023&2=I(u6^8Qp~AB) zIg#9I%^Ne2u`3tX;>Ue(DOK$^t?~|XN`6id#u0L?p-Opp(M6}9`ElzS&Qc zxnN@>nw^s)sa?4Eop(t#@>Dgetd?8gm8#=jJkD=2#Js7zjKhKD-B9AwYfSqgYjbcp zHN{@}^fYZH@5E*=fn`qu7z=%ncJCyFH&}+rQAcK;_6y=x{b81Kv*bXaYCq_o_P@f(^)&kxEnKH&SAJxtk%lgR+&6@Fi&f*w~?B;@k0Nu;b^Rv_8%R4@(*a)Q*Ee6(?3NQ?*`kzWAx=FtZU!hF2`iR*T z424PEJI<>jyJZb&sr_HN-vGyhkrDFv_G-mwFP1^8q66f*`X{^tu`>`}o^n{H%O$0< z?P&>d#-1TJ@z{eJOB_$%Xb}xvWxcdNe2zb^i^M&SnDg9o&qzU%VXm~*6#nVPFlt80 zzk5>~X>SJNcoj=%rlUUYm$opz60ut*JE3co;mn-#_|CbiW)0}w#43-jwP6g##3)+p zYthNqV?IxhXNh(p|)U z*Y+1&;4F&=7+gIqZh#{wS4v1dicdidX7Q2_zdr9Fkzasg+(Lg|=14BgM&^7m%HLjB zi66~Jo2ZBwrg}gGY(sGIio2h~#VS!38*6{iLsH5i{1KesC z>Q?V{1H!p2YeX-|rzdAPkVVcuW*du%!3%;O;kyn~pM^M!Zn>`6O18Ts=EGe)p4v#G zp3_Ua(b3F7(&Az{e)|%3h))A6I_`BKJperd?QrA3mAd*kLQ&jLz*ayZ5-T8Xa| z<-??|yYdVBS}8Lel5=TDLBHiWX;ha~VU36!8Fb{xtR9U(YZL-tO1nYL=A8Pm<8js?EilngOPvaWaC#G+3@#>x>?>byyGSdiCk# zgXoW+!Bg_^@~l0zbI>T9EkK%4ylZQcqt`@+4`&+HKd1TSL7W&AkN4{e~S_J=&PPeyoL(||Heb8 zn@(4QX{0WCJ>u!_EdgYuaE$S-BYEU)89wRH7}WYy_mE&adgC!Z)MI~55-ZraJvINk zL0AxHGFrHHNVuMrLB&a|cOh8$*znvSTkLQ8B? zRve&G6BzrH|5B5UmZlg+RZOLFxySCW9ODNkPM=s^U{Z*;%6UM3Ed@NDFpXWeFmKDEbV)bdOrTA>s8Rdj zRAZde#cpf@N35HgUzOrFB`yKL6{E>;VvN{K9< z5D%m5J$vOqx?BK1hBXd{M z*}-ei(3XITnnL10j&O<|?p;P{Z}6Pep+XN@Txf4yq{^ICkD{?>!R0VHhxKe}{B5h( zo|^*Rrir4VIi39JUJuiC-4!e%xPc~0ydVnH`EE`2#K`2>Om+2Sam22X3#4;ebX=u~ zIL2fwQ*=cyh%)R{HTbC$^YUF1QX4LJ?(y329 zAB%HP(U6q|Qd8t|QR91s^kKiDX`xbpIRko{?`3Fto3-9@#HqBxo+=^_A7ATG;WnmWy*H)pHQV#l`|;l(L1)XI zYs!ac$7K2sFDMoNYC03Q(^*}Ct6PsPR z@BXJLbwR`6#{a1xsK9mNCK0b2tA z;f`IZGv$Bib0k~wG;8bX7T3L4mnX;w7ciR^HAG!pY@Ju@-e_S?i{b_uJ>7Cjq@ z*~Qc&!3egUxc*8Q7w6q`4Kt#C#H4N0npW3+%qzrGkQ^T%kOpaHqChA+I)H~4aF>JG z-YmkD7p=o?(1*4%Y&g(luK$fHUr?dOLhh*D8*{50gw>QQmU}J?dND6{_0P|Be$N;_ zH#}QDwq7nKGgQ{&!r$)$4_D$dd&77z;oAQ<#7HC<&R8uD&k7f-8^CSJ z3-XEXp3R4^)Yl`af5FioUXa^Tn$=hw-&W#wXe-zCSI_$zS(!@fx$}-kE(CC~pTXc8 z(&HmnACb!M(?+7{TU|5Q+2e?1+S~2;igR0_2_{I*^N5_(5%aFN))9% z9T1Yq0i<^Ltr*6{z|3=U1dHix4Wdi>+^>!KP-)8FY-LUp$bTpTq7|FUc2~AJc<>JK zi6`a(eSi8A9#lQFN{6x7tg%c_5^yMq%*1hMmUKG`0xH>tP~vE|+Zm-$Y}*Ms%!WH= zdN`%iF(~M9v~ywxM76DC ztoYNCkT|9lQ;9#3#-jLsejltG7fEP5pZ*o8-x2l~F6XezZ0U zGRQH7>65Jct=rS$*Ea;G#EA>8(K~K*MLzu&zwc}tclrz;CF!zdZ(JcZBcWWE(Y5mh zKlJ{r>You_vM-Hv;%^?|s|Nx3G|!9P910QtO8Zj6@)0|X;N!85iY_1JF1h&CuRS&H}IUUr$f|vT~ zBHAVnBfs+)(d^L4bsyx)EM(Y$tYJ5lR##J}n&aqIkLOA~zi1E{*p=@_l}6qOjra`> znTr#5G6%Dt&Vqve+`aYlgG7SfHj~RG;u{E^`DJCk#2 zbb&$+xl|K844etJ7tXH7ZjrK;(S>Bqp%TJ^box#p880|(d%YwO)HVL=+;h~T_Lq`>LSY&-wPZzitMc?lbSttAMsz1oR8LZ zbc9kBiKFUa!-eD?AK5EcZplvIShnbF$b^?WIea^Won2XjVWY{f+RcQ>xle1uyglth z%2zVzvSyNe;l-nm(~4AZwp-^s5nxKf(`Zf(b3eG~=4Xz^P9Dy7x;!pW{3mGk%9Do( zi*c3p82jCLub6)elY}c`1aCIBZR%a#nn*bw;hA;)u0F2t1!-z{z4!Zh0`>fWV|a=twzt$wsT^Ihp1xzGP=xf{@9l^4=xX}oF8 z5r?5HN#V&$Tkjkpo%zjnI*T;|Yh5wS`DXGdu=fS=^g`6}GT3+430O`cX77Xw>x(Cz z6LJe-4sA@hxhO`%mh5s5fUC7wrUrA`pIi3~>!mr!uU#Fvnc&xrQNzaeauMk{aRS{z zDYY)CEgQq#?Ivsp<~Mpszz%JDt!#^iQ)_F2N0q$kubiZ+sw0X=Z}HNznzo!%FYY>w zjwJCRRYQ@5<8fi$vjx1nsQHXd>JNDlT?a#^OjQe%wJN7&g`q}+Y38aKd7DUf-?UGK0ZDt7dSL6 ze`CS7HQ(0PAfsXaEEVjS!Xm=W9?8T1tXs&3)$6CQ zt65EBA=!Un{vVUxHSV?4-+*j-tT?xBt@4}M76&0?~2B_Evw92OVrh|bL~YAg#$U1 zq%on6OY{o4JZFSQX!9wdzk!Nyl04atm zeU?{iQ7d@4Sr2N2B>abuj^wC*1$1dc2Nbg{o&cE;_Q?_RilMeB=V5XTg!;cC97N(E z8%6w8m_fv!Lk^(66t6R6*Cbf=Cu2Y>he%Iik#|RL6Ew58mxPv*`!(>^Iw+-J($XC!rv?Nw%k>*#BqBE zOK4Tdm-4Hbo$5^Xe4LC1KMQh^8rIvJP%ePj#i$2lfKesEHEGKS3~7Tbv8Oxdc0cO7Ps zp|Zq;hbiS__gAQ6Rs8&7Z0u5agd3jP5?pJPxtK2bWa7rhd5;ACB*X&Xi1?ipZrKG_s!wU-hH`h z#=eK?ml7tY`Dd^akI30xD_YXxv|P$9FmZJzw8}yMPt4i8p&}*X#_bXcm1X$JHg1QJ zxZEO%LMm`E8sF)EyyqX#03?dRMVbb6%9*qOfa6k-YdGP`216X@J~y~f@UAzl>;YzpZLK_D0ZfeZ;j7y zH3?JniA!H|{Fpb{PXu?5BwsUIlmcF4Iq#UG)%bkb?IRvXiauTu0A|KYaM(W~U`dbC=TwbXi%)s_kqgz7#1(@-M|c)+AoN-ah_1 zsk^Q04z$Rv(rxV+Fq4;RZS()2ZoixExfKpNy>jYvLKPsF4g(b$l*-t3&M;ekd>_B1 z8djxxH21u_818&eLdk*b&jnRXWR*FQ=3JfeCf4CZU%3mW&b7jFZpW3(vwe!e#J(?b zd50c0&8uYd>nW1=obS4%ci~ufv>S=2K%1VbK9e*S)2PgN*3>2@FuXor4=487qadBp zBYD@`n}@4BEiY3mJ~xmJ(*TcxA7+oe<$jePayT&PeEPc$vyZ;nS?*)Xf)By3KcN&Gn)zw za7tU9Tt|nFVLE4A7$UNg#68oU#PN}Y6`tucK|$P|9+DM}0u!=q&lxy5Ro~`Ktqipf zfA3r)L~^1u$x$mpKTCIdOu5J_DSVmAtI^1(UH6&0;^^7e5u_t+HcJaN#UGyy+@v(UOf|(R71`H= z9?UkZkIz0jnpLj!H-uXEQlUaKNvjf{A|Y&tGT;3vYM|fe#^*x63frS)!A+Z5u93H* zmqQyA@KhV81Jsb+XL}F+yoCF#8WMX*Dq2SFCoX9;_;Cv@)w$!fd&9XkI@8qy#q~sC zY~8cLi5c^oTEo@Rr>M`T+P1W1=RZ49woGJOs<_$C`~(m!VtPvwh}|i zea7N;btYSYRKjLMyYh-o%uyJz-kBlw5!{TElU-?0gHegR>_o?OzU|7Aed~S4!xq9P zyYI@@I8K$;U^;hHrU~1n6LMW(&W<^1&mm$8>*tIy-OkM=Su-(ww#ZEq* zq2H^AD{SOgoIz-Q5ZG;i+hVW>F8vG<*rV# zG3}5Q5}1z3>JMI1NlNt0wY%Dl7!^5=u0ugIpV_U3wDr#&PcUY;B%53_|7 z9mEcdG~3YA&NOmp%7W=+8{5ZcBuG(NdGW3lcb|{mXZxSM157WKfZ8pG$Gv~%REd8~ zY1&z~A$dJ!SB1mek%e%u?Auf7{NjW`0)33__Utqi!6_LL!^=&lTRuncLpvnEgN3zu zBo5R#82h%|XFTSZY-8utnXID@95Iac`9iAqbiy%=Y@C;Dp0`(e+GXpZ9+HovM|4}; zaiab!i1Z;wVRX60=V>b2P>J`*0TGxjW{Q7};0_(7G@VKN$q;BFTP!JnkMwW;TE#Fzm%|%|zsK1)yheVhCh0cra_irjD^| z-`Yr8>CCc2`<*qi_C%ZJ7W93QEH(gH49WFkGY*R*-aGU`%B?%4Pj;o;me}$ePLN(G zmR=D9jU!X)rqQ06FVHp=`MIY&k3Q+6L_5zO$jm0GM`%-N#nOFWruhWKHt$B~#g{t- zydsl`QxgwEqtm>l^Sq0ubnj&nTssvjhb}rgNz>17hd6f3F{|y!B3XLrm~ZEKrcn|z z;WAm2(gbagY)gVr zIy(PAH}*m1V2y?omhvJ*Tyoc?Ib#Jj!@4>~r)^h-B$Az8WKg zM8>7ss(O2Ri;69{dN9#=Mknp9~-$xshZkT6WcRE@s^?O;``AbiDs!^ zVwToH24_xsr-w6|etc{49E2_Qfa{!pw~67yxV3sPR*5!lJkaph&@xjHo&p7;C7i$l zNyYKG!2Q^khzXKLu90<6)5t_$Nnp3ANoS%jaX??+xiFOSpghX{klJSQ=>siBnuX`o znrNDA{}bg5(-_PXVZz-Ox)1WBe6=F9o3MVadMV@(T&Hgtn<@2v8|mKSLus#&wJ{Xs zT#=e8A9_PWC;5T5Jax>HK=FX(K340TlSjuA37(l>($v#XnBwIQ4TkAfuionrl}z2R zZawv-#kIyZ5}3JA%NoZS7i_d=XoTtRshuXa9MP=LE;Ks2PgYdlLq2^u(~q?$x)&aI z*%`iQG0boqdiGw#o8pdF6V0y|ZLmc>#r~mcam)mEU`r)_(m(_?rYK_r+@KJ&EgV$m zm~&_3dGpDai7ORBIb=PK1C)KOge$36S^ryinQ~qVHViJ@oyE~x=u5tk{ZSO zuiJCKZLh=w|CuXUL!?FnC&@+!^-#}|y}H<`VI(3I#uaL*Xo*2c5!4z~@s6^@(&ipU zcPpB{>6)r7#Cn#6qiphcEt3-3Z}`npo?4u<^M4+?n#kA4JO4967cj#w=1XykzX19g zn9Q(3R=pVw8IElwMzuJ&pGjCoqYr_G!M#7+H}cWS$#?MlCc{ayU^MzqdvtR_vf}`+Y+UjSQqC| z9f*kk@7qv@7(SLmoSm5+l4N+_sTuAj}IEXl6`wbg-CV%A!m13AH#?dSNBaZ*9 zD9}Ik?bPBNH040V*{fPep_gEfkHlHd-tU(3mFRe!ZnmlMO zd2^CJ3XJO;vVlEg*&3PyV97quD#|q3yoy3u`-}5cJtTuqZ8Vt@NZtqpLq zqr|xbbF*na&!;+@MS!20(}EWf?p0@ic)lex7X+ct4*Jl|sKj)r6s=t9S@}2&BE10S zJf;$F!(m)eh`>U(7ubDk^@PE5jtK8;2f>%VR~&O|pA3$`&Ax%@NiB?ij%h2&=m$o) zx<9wC+UyQy>)?FY7Xhd>NHNGk(`IIJ>dfK@$xNs<{!^(qYQCS;cYRZmAOO5^?|gtp zPfxT3c&qi{`i3uH;OxmS3PD4yAsj|gPv{}dbm(y40H$3zd`~ur>>=$&q=ElH1&S?> zYr;;nwX%O%NUe$XFx6sR`8fSo*SABiI$p|MvAG@QRc z=SOkmBMu`~%waP68hvz}`(J?=*zJd@%}EN|arpZh-(H6<@Tj_(4Hws=!|ZhKrD{MV zoewzHljVTnw&>`W@EpbR?g>~x6$k|`C=Eh&OVccSq9nxb$BZYXu={k4KhyrjE0W{o&{ zYKD+-jvgZvaMlc=`GOA6?-oUR73 zHydrQ%-B19jSOU+O>g*LEX%SFX#;|$O#w`!rFg3#AdF~eVTFf}(3!*vT7>SSGlVJXuU&y7;xboGuX>>8eQwvf$zt90CEjOQ>&i<0-KH@wP7@CYk^y~pyjD3Mv^3Dj_;LEHy*ml-MDU$XGvW+Bb*gQ&}&`ucJHeLwZX{o?$CC~`uQz6 ze;*wBovtq%PTIi!8_sZOY>EVBn)5a}yD$y?Bgvh}d5DYh+8I6M>mBeOE#%cthZios z?56hpZ>MuFiHC9z42%jh4@76Xvvt?&EO_r+eJ^rEE9z<~@Rkq9R;3E&3w0N-wkip} zZe$nDdmVYLH~U@Sp}sg=BU{)0sHnJ;js4nXNy|%B?I=_FdIXy6mYQ7NBwfK^vK8@C zYp2mKtQ~ptnRK4M3N`6&r?B!;$ByFyS0OK6Til?xKXxw;mwbZKveCi}PU$!crfBqeKBfTTi zJ|b$Rcd~;edHmC70tY-=xS2!WpSBN9sJ;LboN0m_E{*Im^?6jDUAof6sC9zMYun0) z38D;M&|pne(K+}c^WaH%)Y}@8Ewq-%t*zPp4%|I`t`&W06!nEKo`EkOKu*vH1KY0> z<}c(x+hlJro~w@Y@j8C@@l5Uf{d4XSn)0rc;B9`s@(W@)pFh%CC4!`7m0e2H;`XLX zOUThIyoOk3Bg9AN%gd)X*8RBR7#dtcVvs6gb~PRJCny;hj(LZUoZ+&BrnJtvv$#)+4%7_-X?~imsDBcjlB9B znFfYL`*>O8mU}95xu>__BVwtKj?W)N`SqsV2{5f5eIoMyH)JM!LWSxaDpF;)_{_fM zZ!8=8nvMGIyO|$L#pa**xr!3yuBh1nsZUBdTihhKyCu1m<*;A<;j-^We=JRY4L#dE z!`Pkh$k!if3YT?cc5Kd6mp&rluf_6L@0G~C$XCSnx1qwh6-+=8PCILIh%SbqbWav@>rzjKT9?d)V<3@tdFLLeeV9qYf#H_Zu!76}80$ z_)Vd?ckzpXo3}%luos#Ku zK0v1Z#Z}~AmKR?j#;}~L&V}1;)Qv{NrSW!Dk^vd+uR9OEvJyIrfaRNHat-?R83+RU zRuFJMsFj}$iQAE6@f`@vtC3v4bKe%BbxIv|^*_+j50EYuNXk_LdC_e+_t7dn!n#+6%QsG_vl0bB_9ma+NGMc>OHTs-1uQ<4|8htEjlcWxEV;#k|*;$ zZ!lGi)levH(cz&=f3lVfIKcX|iV4s#eRwPjxb-2S^1VHk zaxK(n2q*0aqhF~-NWK4+`|allceMXX4s~OJsrOMVJ^s<7csRcodBLzYI6=xl2vUSd z1w$$R0#t;K|C^*f@rp`Ik1IcedNZgl3K%IB2*j5rHVizS=jl+}B^Ny`^PK~N$8!_| z-RJu&mHl0ZL=?l``kW@dR8d!YMXTJxrSAhRILG<~mW1pNV}xTWG}Tf6&*J`Mhz}aP z`aGiw*v9m3{XvLpA5aLk9zV2cOrD6kd<0lsM<2eAb|V65;O|on9GqzXh+q0xpE#kC z9UVu&3F(|mkBsioVwr{#4L77ebH#y_4`#XogBo1D!Rwz=Gx}ZkZGpND zg7r0O{L>h2yzY*j7#!X$pU9k6#T)>-J1a`RYltIjrZdAxT-S(J^M7uqe&(;=)?3BN^sB4{(k9&7E^ zHa3s!YqOrS_0fFa281s$shOjpFrcl(7dJN_Dz-LQPi;pIi^lHU)6yMIw!d2S6VJK5 zAn0Ftj_>saB7YpZqQc3&=QSNma+A=U2;h&G~omJRH4GS%(+d@(5dxhHY#d z0A^@KvvbXNY3Z@YP~}2gAu>GV!6`|ea|-QeS3NBf+HVj4(%4wg(T@9ke=lzJkmeir zpLrt0iJa517oxyvEHT5dOI)i-Jl%u8Is8Loqix{VbA8}|+fU~!*7yv%!v7og+_l8R zfw(2^8TkJtjY=N;0y{yR0^URJ=6++R$fLQ_JI;M5wcz$xqtRSi&hvp29vQQS#$LWs zF^**D?Sc-)3%ajM@)hKk$sw0)Pp^D=Yr#I$r@k{D5Z+|`uQ7!N{PUlE9q-I+LFeqt zPB+nsLm28q3+0vi^_CvxQD&2^0|DPqq^K;Kg+2|bnP*hGWUVsl_wUblNf=o&9c{=f zSBBQInE46dD>ZM-K|o08*}2ySc<9z0CAqI3H3ldz_uc-p0w)8w1sre`|GMQUt_3D9 zgPf>Ka;yETUTgNw_P`bep+nQ$^y}u^fnZzv7F2KAFbL>QlmWW%J#`cZp(NL~JweUe z7(!1-;7TLpr!UZNIDm%-B4$=XyHIwcUkku8x((XP=UsRZBtz8C;GWo4NNqWVQh zLPtk4bYwYa_2c1ymj2d@ePqt9G@7o`e;kd4uK$B*z9n>RA7PV#kvY{v-w*JxR{q21CW!7f+>Ra(u&+s7v}s(;}GfO;7aUEKH*nVyb$+%syNKru{~ zy0(~1&_$`GO6;f5`gl7Yeg1@iw5L=d2(DZ`4aL^r?Jjm5kq0=2jz* z@?I8^zu;8f<8OTH<$?W4HMwt0qdW6EdziHB=~+j8v%^63Pei79^=Wi2)6w>Lc3pL~ zt8tE9LRXhrH|xEia<7?8!C^aHyM?vmxq7x)d5Tl8Yu`i?c{>A}zR#l;I; zng2~jP*O%9+dBVDuf-K25|x`tk#TFkq?2uhv5nOibdZ_~abNgn{tX3TMW?Nwn%z)% z%?x9H867^bmjctW+|6??>tlx^*0}1k;D+anJ@w%;O7x5txv0q21`Yyzo@R!-{~Ef< z6N^gu*~}GE}l|B#kI9I^TRL#^z$Lxju8<}#lc?x z_VWRus*;j^?Qbbs;`lWxulWigG0kKn3Ip*A)y0DOr$8zC5?B3K4ojdRZLF;k+{e!_|>8JhMyetjftB8F+dobc=nVkYNKr51kraQb-9ovbc9{x+CN;>eP< zuC7lzaYEi@&)HD5j*x-wbQg%nFx1glbJTn=EhSv9IJ|0s@rCR)<|l+)rA>uWSF{P8 z6cnrfkJh?_P?+#&Xd%86^G)s#S$GZ}Hhu7vvW zTUV<9tOab)t5`$Sb$-Wew9Po0L)2g|KuYAm%5`BNq0t{gU7Co*2i;~&xj|#_pS|w% z$#aroqp6I*F0X+|A#6phVl;6#{AyLVGMj9yaHRJ*l}E&lH#Z!#Mgpg@`kCkPv6$+q z%FPlX;-%-v^E@1zrub(Dd-oOl+B;U4!r4WR3DJKOL4@`4+|J63tkn>1ZffuGMQUy6 z(Aa?Qa#0B&gD&=qq9pg3a}d0ZHRVr%qJZ0y6lptX6eYiAM%V+4Dt1S^UE}+68$tJj8%W=8)4yI{VuZK&3xY_Q{2xgFi$j!s=v z@zC~5IhyC+nL3El3 zA3X$kNTe6EAfou64egRvA>ICVn@2_ywEd<0+Q(5@k+q`RCF zgjZ8#F^5V>s~PN020yniaXl~|fjW8#&VRLP$Eng7en+LXxUw?$A3-h`0lbm`^|=-I zWC(Fg%}fDDBiIdeXGvZFdCbs(mrIlz_i0Xy+95zq`J)Q~&%DV=?~Vp<=qeLoQ_FStp-dI3~t=4E_NzukZY-rp+k_^QfaG_q3gV&68ZWc$N6sx)86!a2^EU=+Ai ziGC}?aW|Ylq`rshvT{wZYJ`;%xH#MS6ld(wzYjSaa@8b+`0paRzDi~g3BQg3vz99K zz5{Ey`vE`cd_w&xB^5z}z261KO1k#QA`m92kv!hg65OW`5Mmoov;<|<^6weeW$RH2 zaXtZLP*Tn;3?8b5&A!XZ#EfoR$Jeco87x%}b0Q-w3|UX>z2f(^qJk|a@s$1Wdn>{$ zUu>ufF&zHKfy;9AKyFiq55dM`+)vG`tS8tu#hO#v0k}-*c?{!KU-vjq>VaV zh|~(#;RQWHk9uW??)c11E}$8a&$j8CbKZEJiT+aOb6PVX&2!vFfME3vhIsg5!?%^- zJbh7Hy%^4wJUolY?VgATZR2QoY`zToFwpH)JkO#`+cr!)$GXXh#Fd475Q(jSzBG+P zq2Bj!4^iWpY&!C-2bTO=WN8U!M&OQJ8eT36`CKL~={`Fz#-SQu%D9Fl)?VC?5{xA^ zZ%WlGZ&wwtcz?G{6Hd%u>WJ<}h8Sn88|uLQG{LfbWif_T-lClv-jtAV)drRerLAUn z#9x=6XT~-Kj2w=l)M*MX>+HwV@t9;kLy&3Msr%8R@j(RF$kvGsYeN#PH9trEMJrxm zdaY&03O<8}N3G;L(`ldr1CNsgd43sTG%(pI zjc5O%?WSLp-CB^``JdAUU1T;3oOa?MSOm>I6!+8ur`Y~cZjh2d&avp1 z%RH|i*Q;_f3doYaldYA>(&~-Ou~6>vsc7LthYanx*{6~IX{)t8Y4UO(s#*xm%0fedpSfw{{PYsw#Gz{?A>+NZit$${4N`g^NU|EwE^MX#n^hZa_0&AX>P;;= z_U%?7{_rzn+#&R9cU8;GLiOqJxjEU1@jD2FpJ7Lok0+(P=~X+~Q)>-u9cbrn%nCiBjOIke{N$zJEpl7L6u zf2E3&2n`>Vz>dU1_jy!%d$^_zKK3)TPXQ`joHmB=PbtpI+RVfaRc$&EXsDwGwwj@R z(NYHEPY?XP4xR(uyL# zdfMVwT|C}A6B;x3&S7rJ_m!!_1t)Jg&b!{-tucf$Llu1;Ohs*V!5M`tTtMTP8;44v4-c*b=dtwv5E4BZDs31&*M@i1LO29arX~ zABk#cMs2dDPyFoSlM_uXok*PnJ6X#el`eWJ9*@dkYiSlU>fS5oz34;!c?IZ=fQ{oF z!34{E=jGwAi72M@wI?;VmyY2tTKcRec;I?Yo0!;_ttH>VJ~ixcshy6-kBaJ3f==`X zNlM;kt-bA`M0PzysWFR*;d+@2yY;nevy*;mYbkgWKZeZ+uanEG#|4uzhkHKic%Pz$ zjC~Sn5MN3ZhtNC>ZLM+6)h6vb^TPBXWAjoC-u8cK0&p7&j^Ym4D5wQVVLEv zp=(PYvb4eOSKAQmi|J=CJi%7{w37DI!ed#s-w48Dp0ymVy8~V71Un#W*MBLiz@X6d zL`G@xFcMQyXd%}kdu_4FiwHQmF>GUCwda|8;)e(Y+|Qh7oz#D6`lwzAb7aJGYNY>6 z1<>mZE)gBWrj+cI4=fK7=*?N}s~Uo~6j*g9K;A_;85u*cw%2Ic)I}kv*j7}H z!k4%Jphe0k8<$50U&sg=q+6r&5paGNLNdpu)|SX0qGbny7Aphsy9qe*hPMZUD6M@c zQM>bfR|NO+cF0*LLq<>Um6m3_whqaPo{Jd626JLS4oplpxu{gmcUbAN>Q$v0ty@$O z>Jma(0qzX45KG3L^%3aTt74{SHa8LSP)SLFv<1TnfGE*Pi}dIYKh2E(K>5F^;q|no zlK}ocRr)oDcxe+WH1&mu!IoZnA3+zRl28j)TA`b z(I&CIB}1Glzw|hB7oU6D;67DGzjBzm5N8sPC8RwD#3-RnE@kf76nZ`ADH7shhJ&2J zs}F~r|7fBkRTaiQ13z-1?;;X3)~yV+RJA!9iAP>tNcF6^?ohb-1c$H@h$_*h1oAc6 zU7T*Mjg$0E>kWbz%IFcdO&IaE%SjED>vfOIsv{usD}Q;TF$w&eYKg+G^?RhVJU3YD z6q63ErH{(W;B@fPYiC#gxsP%olvv!TgE)5q;d)QTxT1Yp!E`-^>1qTq(yy=qeP-th zkzQxzWGVG0UJQzW1FD$(%K`CbkRjFb3JQAb2=@7Mt@VGt+-Hzn&Y*j*h$bq5 z1K=XUL3hnhAi`E7SzE5JGf3lqITw7*x^*(cOo(5XW(JWfe@cVsB(?=<^u7;y2~P{J z2le*j0QS~e*UR#Bq3?asHq2e< zt=FpFMR!iqUJhDu<4jMlWxN8(jLc=m!}r6b)Ekhj@G}qiU4~lrJ}C@a-P)CIy{6g( z*0RWDR1^)$U6ZXn=Ndwh%t;mi>AEvmrvDtY9qQ z`mMi$$&94IwWtU7mMUG&rT@Onoog+UGXd@y3&xxozA+Re6>|CsXtF61; zO@VPkH8;*uVo>H)&D%KT(|8g??}(vwR$J%0B^OkFd;?u3rWarqLJKTxbDY3?l!5J4U9{I=;9*e9(5 zkqWN{QLx+e4(0bGK2I#u!RTxG^233hXTcEh|G3%R00#ZHvcmS1CNvaZU%2*hS*XQN6>KMiokOOTh7!vf{{xtc#1VwHow z*py{eh>5G%445tWIoHqw<#pye-scX7!<95NM4EwSW@=_;dkxs1jdA8vXqjls*p4y)O&6a zg+iqw5Q)weX$FswmAXC?%oK6`VefX@Z_R)6%9eZ$3tfvUyj;xs=c&~DH;JSw*Y;OiWB%RuI?)WNsg(K7SrfBog_q ziGW)k^OsZ>vK2 z`!N-JU-vrG9^fiw3Pwu=jkdy8?Q&s+L-~FSJB1hh?xrZJx-;P&81TtaNfnO~vAsGB zPcZh?dmx~$9|Ul_M?zaHFVo)!hetVe=LSwD={q<(pS+Y~c4ghLuvegY>W5U>u)pnP z{_b}_g|e0_(K!2U>nyFD-!#rL_e3SXg=^iYuu+j!q1V^h&VH1mzAn~$M>9}01(K>> z|1|!kHuc1u&Kv|r=1XC&uiz#pC)4glR^V@}uTT=nLsbD47Oc-6HAT}_hB7nmI&VhY2dnfK!i7d=c1{}OmtJBAi_P+NL9%L3SKauB zVKCgAaVh7(`Z75d__4p*%TWi)4{r0X0N_hCpw^w?Kj>s{`xI?cEDoIu>drN`59;tQ zKJ%9+n(WQL+hs>ni|Gw!L&^fuqPD9?w@rhMFFZWudA;6vGQ`}KPok3FCUo(=^h9|# zL{l3p>Aa)a)*YRLR0IK_IzLc0^I)TN$865|s6EX|NA<^h%uV8xl9EcaS3n0{Yq{T1 zNn2Z7I@8ze3Zgc}%229mmrP}di|XV4g*P3AKl4W(zefqSLrlx4Rid#&)sOs|9&}IiEi2BqMHSfubY$P$Rr)L8!$#(I zc6Mq(Tpup9DrA2!SXk^oK$Q1#v6bUQOZ?gNwCd#i{QUmX z8|TF|d{3}X5(T-3ZD2=7N2T9?KXCNu(aR@Og8f-7M;sh40+jyANYhx!=7I20&;vx{ zWXar_Tbo$fPOEGDPsXaS*BabLPEHO0sz+!v`eL$FZf@>iO@h@$GrQ*JnVIp~`iU*$ z;|>-lQzqKHfv@<=1_S9Js;0cvRb2b`0pz<{b+Ge`dJ$M(5^yds^3+?M5CFo#Krl8A jtOfS{f*p!-`;Cnq$czP!M@K~vW=0e%h=6o(Y=~6p9TcVa4grGWQAR)*L5h?_ML@br z?l7ngP+)(RBMO-ZE{hUzkteY;vR=@wz^zU(EJfDpC51i zi9-E?Qn>WHrf1v~0Ug)t<}1j=H#FIvEADD!r?v^bmWBWNMd92I#V~?x z7@;eEiE-z}l?%~bQ>SA|l(`RwyOzr2h-9?6yT@4~*+v$3AwxTDWOne%s}D9GmGYmAZR3;&FZA#Z5`hg>gwqNiF5_6$NRU zCsH)o%TZ@7ntF3`emt=mg{ts$WbQgzT~Tq~8;usmFjpVg|FHN|X=$lKSV%|+e3O(D zz}ttlkRE#RzUwPIXU{0;EVix!M0>omeT>J z>yrBguZ2y0S{kYt42hTUbo}Meq3NX&owC*Abhr2ZgUEc|-e+w(({u9jLZ(YM9et>u z5sAfOA74vsh!M4U-m?jX@;_d`Bo?i^Iq;0cPZuf{|Dm>ZV!(~lbbg#n#Fe7y<}9WF;=7 zCgs<<2TEt|3|+xsFtG1z$ANcygQ_0bv%$e6?IjUS2Y)*DZkX@KO+y#Y?|vD8zwKX} zqMwnJoXmgv^l2*x2i^`}q7z9c`*!_ZuSOd`(bK!O{ldX5{#UvFN>`lIvQ^>mAWqJ< z=SFQpSy|amc6M{-s+UU0yPwiCGEVQVQf zoQZ}HUGE_u^6(S&^tN3E6>g+^Uj&$(#p!@iaP?br{E-Z0-2bgWj61 zm;J`YLMKTThXtD{qI1B~SCb#bVOA6_Uc9(e!6qAxVUnc6_@Yew^!jLdM8!fwdrLWu zfz_UO_jYh?H>XjliRI{Z#n;F#OC=pj6w^o23^~k*Ams?k5O}vrl%2hJMm&4f3TKn4GZqg+MzMv^^%mEp?k`Fv>{{)TtT)) zv%Mutb+MOJ{@2N@l0k)fNe>UXu;OxRd=c&S>bxTRj$?UwD$R;nx>y4ijd#9|<$n8G zL>-8;?$21Cu6pfJYF7E^pFQ@4BZ8DrRzcZ}FTt_WVE!)e>eHF!{pE|7mnL*ri6M25 zI^r7gSk%f}U?F zlbNh0kD1zCVkKS;%bc~*uUC!11(?%j2(c0_qwS>_M1h=YyqVx;Z#z1k*>AEMwv$6g z;@bjveWrulQ)*Pc`(#Roea&Y{C`=MVn zhT)uj;G9{Z)fd3a^v#8MBaosTj;kjluI=)@hFI^SYK=29LqB8m zSpZL6fb2qxZC{B*GL9*%5GJ>hO&?ik!yIMfU>}aL(I%}@nz=?Y?;K9iPAi2_A+v)fHX}F58R3@S1&_0hZFl%N!uDNZj3{ znW0_JptI!5mOC&Cx%$3!MK@nZuaH@xaTumo_|1K~{zG~xnktE{ixMA<2n4HmS;kAz zpnazs3Q5eV-T8JUL-nehYD!__Z3e9%z}9}##DPRp|2<&jO&>q1S?9*ExFKYozZ){L zYG7hwVqY|_3Xz%eI+SslHr*4&_e99-N*`lJ?!y)i>FCQr`yM*iRJ82m;DCcq0*zrY z8OQf-e+*)4K3ci3uXp{W{GBzWuq=odt4lb{FLJ8`ktNf1}Y-r*PFlG%QY``5{w;zbb9@3L`>CdKx}@~-x?>LChcV_3{p9EUmW5bSpT zb+*fO_o=aKDe6LZf16#X8>wmQY;0`YLqMP>x6T!Brk$s!xCen6vHDKX5c@>f!W=wJ z#{}m7ar36QCqV+2X?SxPIi?V+iGX@|#4d5rd<$&LN}rbWfP zwM+)1D`&jS)!qGE$tve;fqsU&WfJ*_V&t#~hVJos&`&k8SeIsB`$z$!n7q8shFCF& z=LSCPFPTb4NP(48?lQxM0pD$2niS9}w`y2A>Hi4KU0P z0e&iXUgLXuqM9+x&N%Ohl&)MG9d;h>5BGP$m=?19Mn*;wlj+&>EuntLK)iazw6>)g z4|07oYxVLIaORit*=rJI&@^uS&ZW~1UM_tLNnEX+oiP^R7z&q0IV|v*Gd}a-He2`J z;j4|4aCu|Vj8%#~ce485!^VTLiHJtb2kIC;dHc57;xy{Y4C3+tcyk^&(7-0=>0;gx{Rp!dK=qooF$sV6 z>{*;!XRFUbLO!3IES}IOTX`z^%mu)iUd?ExIM+EJA+j%7d8tmPEDRP!FCnoSu`+0v znnNB*`iE3BG@Ovr(|xA)0no#IS2I(YiDxaBp3-x^*0(y!<=kKKHr>$cw)@m4iI&rw zl{iDQ`db$RU&aURzg^Rm8Q0?19lekX)*9DdD4ytCC;^@m@af_1mH@fc79S=hpU0^u zA(X~#7F%)addkkCPlz)=e5RG+P<2!2vq(8GiwRy;CylXHLHiGRI~b>RAZ|CG;EpzC zE!(J{DnjiX$}kkL7^(X?VDo!rWo56ClbGXhvJh*qW3>K%y>S|nvshk;?Dd|sXl-o` zGb(l;0kCk6xL8dn1ZY8Nu)uoj`le`Jvq|F^zL)@RZhppt^?TXuJ5vhrx{RYWL6s{#EA<8@A zZ1soK{XLaCOcwu;W-T?>|MA0)u)VF|+&xMs59yV7Iw3AbFWX$%HR#L{%@Y^9N|u;A z0h;!ecpZii!1mLtUu#v3Ei!LgS}xYGOazLz?K-o48{0`MyZFA@ zf~KabLULK7+Z5*3$;-CHGGP)H?GC=e>XKj?f^&KNJSYETXXiG7vunWqh^UYVsE|Ty zx1jmuk-B zb0;O4w^{2465>8eoxBJnB-4$0w z#KcHRvCLV8d=r<(iIUY39SAzVz^E{ed|*{F`}`IS12B?cPCF#B$unLVr)a(jKGMNCf(`dfw>1hOF9uAcbv(EKyVA~p^is-Bd{qXpd zVcdmhXIiFV%!EFbg6m?xn=uF5pB+{f8P zCX?wiR>|93;^jgK+h0EW$}SNn;5W!;rGw9Gi0gWkmzQTY$s=yxZk;Q=Y^e%i8DuZ= zWuoD=i9WuBQ5I-4AVCTf&bkb$77vH*zg?S>JRC|~xl^(bI8r$K2W8?Q{h@=O6w7rb zUXL21bLgDQ;GXTd`WZCMyB_4ec<^~iN$TJWk4N#c+S=P)ZRy*h_kuG7-;koYO(R7U zvdza3wr_!S_Ye-k2IKw#=l4M9%$dLX`uZAha+v1^oBS?-dW5}5NC3Eb=lJwMKt74H zS={P*59+8yRy}Hu4IrzCYa?oT7M7L>DtID;?kwPDb(S*%AU)+j-DcpdP8tLzs}9g- zIA4#)6c8jvU1h!&>^#!Zpvt6jMl0kbCi1(E9j*QN@#77TJax{7*;gYL{hm6#SEo3$$;v;FEEld*!JXh1!XSR_MYp`G^7$OCQ|da8Eph3=^&@RK9X z5*Zm8R(5vrV|ihGZ0y`u!9w9!Q#-5y&y{j~wgZ%@;oj}{L_|dsbx(ziN$NkNiRk3P z9Y|urSfM8u7D@o)q*`bQI7K5SCPw|(-YY|XFp<(rz&)C29l&di_P@Og$mqkucpJja z>MCd9v=nT z1Q7WJB(0~GfrX3C!FsB;_w`{RMLLdFS{ugl66o3T@-p_Ef#-Ywo4NXph$X{07rKx_ zR&0NTyTUJnvr<)6g?%9K!JHflsTO3okN9fA6M%|~9IaV9O8=HK($aB2ck$Jhcu_(; z4^1m`232RceyblU+I{b0H)o1ej8=)E%iy>4XwDobu+ZHT}Ud5k|1*Kw`IO7Z@}(=V6$vD7f;tt119Sl z5L6KUB~GlY>5Bhc`kf(Z|(?qTs9a#-9kp#gfU?>)`!DRK6b|aHCEsbM)Ctq^o7-C{k*`{y* zD4L`Ukz5>KF|nx~6E|?HXh}eQ%8H7L1S*<7qijM11jFU4#KpjR-W<4hWpm*}o`jZ~ zFP5ob!a+vaXQe)hgH`6_uKD;t}7 zNMa!Wk3%#Q1Vw7Ag*EK5bZ}?}4Oh?5=HfAcL;{cZu(U>hQM(gBdcAQVmO)J0i!kMg zGUvjPJ>3MU2%zWBXxxkg{5|Ap>M0^eOV_5XxCDs$8h}|~4|q9%rp!}uRfREY;=zUN z{$cOBGdqDEl+<^EoE-wp9s&@z6;6l?yL%V1VJ-lRPpWqYD8;rr=QwWhJwGmQ)Kh{z-Go(Th@Pgp;RONNDy^)EdCW<^xO!OS8)F?qhC?$B{3M} zJcDO4ZJ0xD`5b9-aMxP(0c5wW0g0fF+)Hrh=+CaO_BJo?Xx9^`jw>XqNv77v}CMpBq9Aj@AlaiPv2W>d#0bm%nWBklFVI&Fc))C(jSG5h0NfP2HU&|5m-Gn-ns7hu6qa9j=10R zja^S(^_D>3QuOlejf`@244tZOY^r)F#W5^a-W49tcAq1yID7K^%#`F`s&bO!=u8_~{;Pm)cFLP05Z9gzug(a60FmTzz;3B04^LiZ08LzVF zJGEU1V(7CB6NkoyEEeNB9o_$fV6%e?Myt&4vW2<94CmLSqCyl8vmZM*n8n*0mAR$T zYLXb6B#&`z@4m_Eo02{gSMKF#k|~v7CfyAd@a4MFRiJd;)1$e+Ab5QpsG|W++mEpa z*B|(L7s}N6KopcC9qkOO*MEizuPoTQxA_S{S^%;6wadTunMmuM{9b3p&I|*O_jXWo z3h?!9N_U?5_q`#iq^ENXCz`cP4h*jH;X*^%ayoeNx5xP*&dh-Tp#nGTZi+S$AbqOq#vT|Fa$n zgjgu9e+mr5mQa+NcdIt+!3+qrzhL3xMUIi-a8;FOY6sfBIu_}!JUas=oo|q9k&wwC zWW0?ClVOybrjymwnyAQ8Y)3Zj2>ZA`yki_E#s8*`jt%_TX z3&9T+IMt*r+$rDMLiH7^5_Z@6)A_duMQ-xFoo#I{pYWuH6Qq!Mwu9X)iR`+XcHXZG zMxF7lKK(TM@Ydb9I??1@i^fP_&QzCj;n<+U(HxrDgk6dB>MZU4ME!{Ri3o4r2S8mF z0zl^c-QwF3q@Q|@Cq|ir7ufYsA~EA}ESxP-*TjSofD;o-&Ut9l>3j(i6v`^er2S)b zqGEHyXd@kORPH{_?_7Iif9TUS4~`6ZKqmZL2mOsjjycOAv#tk+zV5v(RX+WRR7Nzt zbTKDgJjJbdWkUkk?iWbzm=-A`#iFKLjE<7&qchmIw%x+fd=eJgE&|a#ag)ts9~wpn zFXeBT+v;P5Lr@TU(pc5&*_6KfVd-?9B>qp?hDI~PwGfUhMFTg^w(es5uZxYFtMx)^ z4>(yvXBu2yjcquiMXPXur=L1HA|S+e zXrZfq*5Tf#25ABm(gaCEysS%k4n!(m29SEw@Fue48tDW~%=b>!71 z^5|_rv>tOTlz9dsn^G9iNn&ISi_L{WEsvm=(UZ~*3kU!FwMr{3vnffL-a#0ui#YiP zNK`Qg&F*fUE*M;*q6y`Ai9Hv+KSuny?d6`Eajl5BF9)*9g@pb4U6+z9+x1O+z!ZN-8%hwM&z$E%So5c zJ5>kg0Y!A1+*eu~y5-OE<+SoJkCGuHg)oG74!H0DO`8H{&!oG%`)JOFp+?t%9Oohp z>}!kMCPNA`l9NfVvPht<;VKgiIMx!Iu(TmU2u2FX2n(C%@GBr+0GY?hlR3&DvrJVa zQ-mp`X5OeTm=#$M|8oT{wT9h){HdAT{N{XTe>?wHg;fWhEotSaIeJy$bq8jM}Yh&nv9LDhm`#7kHza&E-r*9 zbYhfo%xQx>5$TyX^#YA(B3i?~VBoX_V*yv|!02Rs7_15k;BSNuec66Z zIH1NV{SEW3cqug#T}xX(=< znNEV}uDVkueoNu@L6ei9X*N-@#h|sl)$erPaxaZH8Xmb3a8#Eo;9o9Ie=szYnSCm80%ar z@M+-r>Yz1fJ_cVRX@T{+;PlZI60?D`nbs!$Bq`r&-HctVlj+wTti?SImO)-46bO4d^H?tNa96d2bj* zutQD;z{ZE$1Azj~ASv25&;w}!i8t`+Dq%>no8?&*0fZ442mAr9sCpGq@3pH!Q|R{Q zK(D}G1~riKX$&Gp_oM3TWj;6aLzae5l_HL1pe6X7=eO zP-UkV%o>x<&A+R9?#5htsuI0z| zeq?)kOLlCmQ-4xfJ3EynV$ zLTYDo5|HhCi#Mho>iKEE+7$G~fyI z@d=ooDMC*yW+@8OcxMaSyaS6yMJi+=*OS*j=(vg;L5+1sY8tT9^HqX&kV>}9`}mO`1U;ETht?BmREUL!z*EmYFVdlNvA?b_?hG@@ z@Vt;hlN@W+410R+Dny7+;qO9$jc-^OKOI0Yf3Oj9Ra`aTxIzu=3y**+h7=ii>11yD zrA0?5o#0l7lRxhbX$6BKxJQHcH+I?xvTJAqT;62D=;&UZ<1H71DL$~4O;}RUAA@bc z%GhXbAYuQZ4$zdZ38z^%LQI)AO??P5cD>Go&KY~-#drIM@38TFSR&!XtbNz34;6D$ z|JrdZDWy*2TOAnlje69)88?IhVNc&)e_uvKWgSNkqTg z&w2I)eSV~i1?WeIVb#W6(mcf zWtYrLd|>Zr5kjC=onEaAeeQ9 z=Y3&G=t3L8Ok$ZK(JAx=BNM1>96SxsI1#KTcbId?>j1;=%GuFNK0IGHXnOXaYTTb! z(4C8`17Cc*>ka9sf^}}C&GvgWtTHH|XG1TSbIWBx&sL?tG;O1J=v_%$DL@L?P|2@O z_Zx2&Mq1cDqjMPK!;vUMLk|YNoJlU6NX3WzA18)3qn*2UA#;vGQlN{_zL}Ys7k{m~ z@GBA}I4$BHrDgdUL0t9hPJFr^nEO5Xo{Ha>r574d1~@Rouk`jtot6@V5M!cx%i!zQ zP-jL1_Yf*H^Sr64w!Mq05|jqgt+~O=P#<0Kk)6FmS9bmO-Ub*EX0B_<0d(+gDd$)U$q=;B3 z%``*{nSE{yUmMHc>DQ;?fiW?GNRI@F+=beaC1pJg6nv~plZ2GA^3m7pc5OPb8%_-B zIv`yg3s8%Z{4*7Yqho1cDG+(GZ1%3hDJ4 zXrwoEgXGg^>9%Tj=hpzx1oaM(G*l8&p_g`rc4*f_fDkE~A>MUP-2izlQ zfBTz*-mm8KF7W4*Z@j4!hwTl3;5lde$#HBFDR&`8)|RyL29muL?NI5Uo8V;;n?R)e zJji(V#gn}{8AXz@=Lk9;p*DEG-=Ykioe0#2-T4kCSk`LL!Gn+?f5{VdG7TS5C&k*Y zFBME?qRpT~JYyGi{S+&PUEXcmD)HqXFj)8Fmg`cBu0xR3RX9=GJ|7H|K`eKAKMht`0m9@UgjAtF?*lZY0v|?B*r<>pD86I zBhU7jP`?Gi-*D?hPQ?TJx*zs71D=5_9v-P!pHamUqDV9!bQUp%nj_cmM+Nsj-g&HZ z=-YhEqIV;;@=qE5*REru;y?aIqti)Hdxwr%fhZ{5LkBiD_kkN5LB`RQ-|+lgtD;~d z&{hWzwzX?2rD)b6<^tY=aNUMnNa~9NgRrtb!DE(OyG%7{fNo>}+g~#JqDjEtF8_*O zcPJGt@s69S9$DJiHEQXUO2W~e0LSUu`4%xh#NB@O%b4{Yp6UAWSf|y}d_CeAKOoNA zOxJSWr(!qWZ1B9VFAF^MiXKI#~>j03O3}L1PsmH@iZ>-vU_41|)6~gqVXJh!! zUZeNAICN$*GzE&reo&23Z~}}1u*uhr*JG_+efb_bBCN22Pq&X6Z@Nj}sHEDp!!j(#Szg{k(h%;qKmgaFTBFfwDXJmdVwM@2l z)6v~-mw&zY=M&*_=WPuoS`$x|{96PR z&mVtY=q27DUCLvoJ<|xI2XG0~-rlZh1h?70_++V>+cSNTmpALMeA#su7YZ->XQ*;~ zxuhR#4fI{e#xXofmnX`JE`ftEf|eX(y!Q8y4FKVb=Uzaa)XPT~G{vu6wj(SrEiWXq z(*2keRx0!ozkgb@5nRe#{ZE`;btJWZM?mU%q<)=wX~AkGGD)bJ>e=j=e0h2 zze3K$=Bi127CuEIIWpHBn%n7H1A~Hs+?cC^FxVRb6DBd{$&-}S)RvZ(gS;$Tw_-wf zHmT7192s+FWMRRTP*(bCN)MlDWUylg!>~MQ-@chsXhy=++^!`rp4*`gADT6^a;@5~ z;Lm^DI1iltvU&m-bn_YE&>Ad%JmYm9ocedEv?Jbe|k5q+=OD`vp(`eQvk$|3&jV zZgy-71UH`!ofQN+VKS?n`N)FQ%$moFzwWT^piP%c8O@c_1+=s9X@!M_lHLotU<=*F z9;&$V4VlXp&S3Tn(WB$zGiqyV(JCt3pn5|!CZGR_Au!(GtdOQ14 zWqzN#p`@ycAE_tnFqp&d;cn~vo?Jiysj2XVmX@fToJpy1mVk+0IXteG);7M=b;DyG zc>FWxu`-C7bl)_XBc9W__=)xu z4Z5$Gu&_%rv8KA(+Go{8RFv8?LG^Y6-A+w~bXQwTi%{S+G?Sg0Iycwc`RS9c3F(Wz z0~k|%qs4Ws)Az!Axumvn&HSDWL?xhA48-NG*2wBA`J0QG1y1-ARA7vU9Yr}&9nO728 z@G@)n&GHp`Q>_bwHdgniOO?x~)>d^wiC5ab{rkbUz;quzNb)DGkNoPlpZ4C3jEtO^ z>N05uWk@m3qF3a?Ggv@tsjbj4(}y1oel=r^$8>jY?yHZ@R2%CX15I!6I$Cz!IoEyG zJ?X1J7|gz}M2laQ`JxHO!rdl!m7+azdk)j3rM}uFtD4fR+CJW9v7G1Elb7K(H<)-k zD=W3gb^JnxNjdWwZDVcDB5dH7-xL%qzUJp=VoHt4W?6r%7smYgAAQr6_vfB((nqJw z8>z@IDo;Pj$EzgAG!hy6ML3CTcO!y zdarNM^zxo#+eBjFmcspp zrn=ffUrk2HW^I_=hz+~<`nV|5k=_6K1U8WF`=7pPiWI-|+xh_i;Q!Bo8ye!iT>qzI z{yqsJB)~cU?Zw5adav-c7vOKU{#^_qO47}3Mj{0-)9$}@ z^WFR`wkR{}7gqz5r~PQl;!}&;X`EAKPYr%n|3}gep`f20Jdr(ruP>!sNo1*v%4&$K zk1zgl$>~df?fGwG`S7=#{r6uWO8i|Uh!pms!UdFq3@YwmjpsMmtZf@@2QW;Fr8kg)SAwIal ztAF?w5yfR!!blffLaeY!R;Qxs=LRYRoIE`XvcEofC*XB=gMs_&TMAX;8*1+Vt6vnB z2KB-EDsDUb_(-d$s)>H_NG)g*VGxM$=Yrz7|taQOREpvBRI*7vuz`uMkR)N#)zOVg{uVtAt{Y zA;wBV7iDF|?e%-dwqc)Q?! z+M?1Hlq2;=gvOM83kA4p=fd6zoL-xVUFkNIf7;LzMXvfTn_LsN+=bLLH&|7lQD)X7 zN++|MJE%G?NFt#L2|46-QYcfl5)sDvN_KUCr+1uR{3$*+T50ZKPuqG^EfPzpL)|Ux2{Aiv&>{|8FVn?;`mw z5<~)@ukXr$h~c|^d{>6`zJl+{@Ld_cE5mo6_}L2n2LMQo-^*^JQ2&%c{*8ct%YDBm z5TF9z0TN;d|F>e|VsiXSkCnASrTA)N*^9;g!)~(zH1i>^}WgT zixzxu3-}_4@8S2mgG8aecS?TIg6|IUztll;i70FM63O1|kcwEOkXNi@Mip$f-TmFo zh+c30rJiZzU2u_WXF#QOk2{_MtCN

    *;h9_nDXcT8S0xs+5UAvf6%rhV9ca?zP86 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 #*v!A8+UiDq0@RS95qZDGpn!p}o zRwi%Lk)D#aFnmu);n|<$N;41)*G>tvz#fMTbhU_KV3=&a>{5U2ix6Nj!sY(lT0XsVWA(YtWAByh4fCvZ zIx-C1KiCyaf2>QZD5Jcj_cn_~=;6FA%a?OJ1GXJES@mJX-bUHiJb|{me8GFm#arNRnr?8&S#o zBbSBHjcsHG<0`EOvv88qk&;zM6Et}g`Ph5a2O##|0vAx4mExFE^~ReT6w{K1hT?hi z^E=C=WW6>~s@WIDQbT)cp2>e5kQ+q^J~F+=nc#PAAR=&03T#LH zMK&K>*xpfdeN}nkG+~iI6-B3sh8mH*t7Zgms%=Xg+EF@@6rBT+U&)^I@uT!dQli-V zB0FXL{e=pb^PYtn>z5s|?c7k!eej>f>zUHo5^0jt^@_3d*na(p19t&He(42h_?<7G zN5y7s%9YaloE2wRD0qC5dbGdz_=G@WuSdt!N=NtdBx?3em#0_#ujYJfWB56VTO6;{ zlgp5y4|rYar>jlt!-ZCCBBwSyN13M4G03{d~=^e*QWL4gBjrF@aRGFIOMD0sHzmBJ-EE!8n}~ z%HL9Ig1B<6+f$3J^)ihjkElN8cIoM7rXG2^wuHfBVv`%HfdxswlADy-eNU)-@rmE? z@_u4Lue1imchLQ~ZYMj3Bv!kCU- znyeq+FZ$f0%RJn&%D;p(<5Ycj4B=_^hgGGai|31gUdwYOtm#5!vvtD{|F`sc^HsRO z|G7S=E3d6*uulEmadz_5N8V78wKpq2Mm*V2UH+|_1_p25t2M=y9`vo+yQsbM8*YgV zG80`hDWLlkvrm0cm+E^YVbj6wY^bbUdm1eid$Gw**317D3p87~jdyJ%VdonDClN|N z{u+;HtwnnhcJB*JMJw06qT#n4hbHaPA*kdZXb(qFAXVYFx)_<<*0whBz^1h;n2rX* zhWw}69bq95U=G0+m^B%teYw}`j&~K#_7{`%vY2X3vgF>YE)a57k3*Jkl9o+oUyV=U zNamgd3SLDSO}#IXo4kuM6do5bRx1(WiTipoTV-hU%MI0sJsWc@$138N1OH>64DA)s z>t7R!_yAvv?ALF|Q?=Y?GbK>aR&;*;v_1FOx~4^}sG-(V#K6MMQn!ZxUGwFJ7691; zIz8FfN57PIq%|q;I&@J0PUX5Cyk-u5Xz`&R?n3bv(r$I*ygg{2*)M5??98IB0%HPy zy(ixeC>(VF7J7Pm!Ll=j=|-Mc1PcdOcHIkzlXm`BvxuT1kQ}h3WyAGC4j_dzw6$CB zuMb!GG0Jg6b*%upT<)Y^rrc=0PMR+8;I8a_x*58ddVzs=WEQh$?yg?xLELgO84vaB z(8B-?8vEcYdll!u@KG^FjA9kSI!X|0u!qtebwpVb;`KFmF(fL zE2WDQGL!}}@K2VQjw_al85ypnhHL8Or!sMe#Lau#ZKgMjo!3XWg63Tj3ow=6q*NMB z?;c2odNs6ZEOir@3IGp4u-d+4ny)N}!lEgpoHG4(>(1i2#PJ{Q!nQ+#8-)~mpjrxa zdTftF#Ua>EJfu$;`m{SjvBv@*iJSq%6C|A@eUfX6sAdp)?GDjE09bVPas|e`xy;1# z(76y+p`?m)iwfV^d~5jrPA1xBU6me4!Kk2S&vSE6A~>FB>mTI{c@=T)74$Ndhd>1P zv7fmEo2d@XP>_b!p*ya6w5)gu%e7JOpN08@b979v8>XYSJJ%f2f1jPF5QST?BoNm-#4NBfki(nL4kr_9xE$Wy-eZE$EdA4K z6j0@JNvj|3dh$Q_Kzed+3(1`XPT_((t-Q?|1S$Y+SefRK6RaMlfx9Ff`i%@rJ!U;< z@UG+KZm4qwqnL}3W?cMSUW7B1L!tKh)}Z$5x7aHGk(~_p=r43K)6Fo@(VK=S2p;v} zMe;f<3wBk;{u|ExMa!sy8INdIex_5FNA+DJm*(4=h1mblvz#sEsNG-iuEk?*;GGQ@ zdH;`rC6{DxEY#BuL64feJYAb#@_CBYg@?}z3WT7-1`P@tK%PTA(-DG|dAM=hcCMMs zl3MUDmebv?u9tUY`PMzu&T$$k`|Q$SU|N640U+L$_N^P+$0+d))#vW*HixVUT0}@0 z1qws?152?5$mZOKhPJW%o|$(XzMrb($eyZD1zM`}M=F}5e{F3-IQYK@*4APA&rx+n zrx!pRiJH{}B0YdvI0ni2{c%2`yDu^7a2?d(pT>BOM?T)Z7FGSOp0e0@7pY00SW9@Q z|3)Kb&RW3_G#d8LjUTQteaJ(!7 z>)?x>pF->=^l-TG!mM9Snb4iZsWECHV1m$k^nY-23w%mU6VqnexvPJNN@I^F#JL@9~ z6fCKYLNjrlk6st7GJJURF&3K-e zfQql74!N0`5^^0hP8E%2ckSZ!T^#ClAHcGgYdnO4ck|x8#K!1vNn9nzHuhZsBpf3v z&6(QnkdoFhw~l9o#cP3*{wrWjX2RB6qNN-%1x!jkO6l;f^a;DZVu@N_+{%3gHi?*3 z)aED-nyGqsr0?yYCCp_K1sV}(5?-~$_(EFgRH(d>dHE2r$uD=t<%g_q}svcSlF1cqR zuJiqkj&SIaYcod0h$u~`{eqmGFQ|MtH!*hDRO?q2t0%>hU=Dr0S$W-$gOs z{vM>*<1^BM>>`AYx&cNX0jkv)OwHb8-i3&8V>eIG%#s-%y>$J!Je&B^kV6^hZy`Wi zTxRj40KzP6OW|9a{n0ox$tQ(3nxF9-=1<-4u`i=`R0TsRq^`d#c8Q2%h66b?ie^#0 zJ;zQ8?M>8J+uXsAn1)TeLfXJtL;)2H=K0uXa3i@Mnm1}n)}<36{Nt{G7rJRjR6x)A zKlu}g5?M=Bwb*W#!G*&RQAauttj#5`LS?U3DY=}U-B9uw`YH|uU@8)*~4z_ z%fHW!OI3(i#xtHBI<=lzaW@_{R-B!0)kNKpR9d@|>6Ci0-?fJ^PBnX#*2I($(pRV*O_nspP3k!EMHeW`l5 zBM5RCZ#1Nwte8txi|?20w_7{4^6!h>R8R$rK147Rexr8zKE*w9l{WWHZvJ?F=>5y zTj+Te0VrtJvGdF4@H6nphU#DQeHnIF%9bggTThKsF27Fi(^K}H%gTHBUpQh8uc)+uG z|LyLUT{%QP73;iPHb}L}n_!G;LOy}M9me00yM#)n=4?A1-TP{dzpy4!)>PHUF%N^d z$QjVwYo@!J-4v55Xl1y1nCR8E<-JXu_^Nj_u^5rsVanHm*>*ng8~%A8ce(|XA?hE? zqvDzK$vF_zUKJGZ{(OA*7HC~kMfzime3!T&_|P7yo?hGf%H}^6opxcD>d}pS3bS>$ zEG`=5Prd5(p$r6C8m^5XJPEF;@_N4WnE90oCYQ|EBjRp83Z_jOb zB7GMr)ItjubPhtTtg*k0QI<}Ff3n-|r?;9HWze&0T| zYioh2a`X_K3!O%oiNvgW*c(j;hk>g$;c%W{*}SWjy**DZb4>=O=|3L}etA!@_zz+X z#tmw}S4nrPpE({}J0Vo}DrLMeulnAe5O>}~7K~-8%0oE)#^-8t@P=;W+;=xBKhm7E%- zU|DLLvZWz6C#T2z#3yU6$y8JpU`^G<4BcFSkxKpNs1>Jn=KnpY;D1ciB0zFY{-xH4H&IPLRr_*m|W@Zo;rkGSe<_v}WJ}Tr? zRa5J<<_IlE_axZ)k^0M{%dIe&Y z4eLYPmT1E|1RDH=AO%NAe~2xr=N=>~8RT~@7Cio6 z(AC%l&F?(Etht!UyLD$aAO$~Ge3|TW##}jB znkirV3s?L`tKs(sSO1xLmZ%uI!z%TW#r8){mmW~q&x!}`bxln&d3r-nm2mz{sMmw1 zx_3p7Ys-iIoY!~OLDA~(quKo*j$P6k{_$+mpOv@orJvHP>5MRQYd*Sf%aNKTZjG1d ztdo=&GM=dr(^C-lW%7RZ)(c*1JHloU_@*z^~8;}ebAM-d95==n`NvVQf>tJ zt#G6l(r0THGuh_)Xf*GVt+jP(CK|0jH(*raW+%Y!g7H-s;O|}XRhWpx`?|e=!un%5 zl$4ZS1&iTASh&)(cRE&&jm=0(iiMp zXL^^8;Dv|{%?YfF1B*2?NAU47l%DPi7P&Yd@7%P=Ge_qqHYCq_OXGZ>L60u(-zG5W zvYP}>R$yhL|5TfO!!_nDRY^`M&AJaQb0A zGX0_P#Dim=MuSc`MTvc7{p%$7OprvGiD{yZ_&#bCFB8*O=#xgF_Bhr;pqdGcJM!jrU;QJKHv(~g3zSOQ##;xPYNlBB- z)Z0hM#lV>v=zknvi89bH%pP4Di*e#u!al~-$dA%eQlX7Efgt)7PgKUgocy7hBQQ9) zqqDQq4#maGn-$8Z+3#$Jj2q{ZxMROp5@?+LlC86I&QU%-QbQzR^4$ZXjf)G}?ojnc z_8lE>-}b2X&(`rNliuD5RgEy}UxD_F$=)K0Y8<+0FYW$-rHo}SSYK)?g~(?O@!j2Z zEko12r^9s&%sU&nLC+q%36|O(VkC=QmMVCA2Rc3T%xZb#G8da4InPPP?V~`}1Vh z)eW@El4H`6dr=@$m3uW*AoJhlW<9X(Vgs=H}|?xK4NHrKT2pQ6~cksj2z)j5FIg zINV*=+5bgx!@Qf<`i`Dm(FXkm{-HfmEUO*%Mn|U+k0<2fnS)jFD7Xzz3j#h&qvVyu z+Uk6kLB*Y*;ep!kP41%>^_9fGIHVkxr4$gCQdCql>2iwNVYsuP0dCG{dvFL(nCa8} zQEE+D{OI^pkWE^bZO6xt{m?8Up`c*0N3ax(f~=?0{^3Jao-1jOjje6E8`<|+RHH=} z0Sx!c;TQMYvHsf@xmO_7&IG5IWepJoWUs5EQ_`0@G;}pood+**o_ZS<=XbI`U zrk&bfXThfb;K#eCr5yUx^-PvrVe2TcWcQe95-AN!k4r7{uAn~n(`hZX8Gjqw^yhqZ z+LP3|s>9c=mKLEXa>H%G0J+d9>@x1L57IK(ZoR$VdAjoEEeVm?g@?G>P|e_uJ3IMG zBrCA={8JDd9um`1o8seNK+ZVOzLqz$=>{VqLS^@!J*b7cJ1lf^>r$uQHz^O}&u?1t z-fsS;Sx@@rx)1$@PiyL#TZwVwI4|=auh++?%S;+81v)~!{v~cGW~+koGCnG^E*(0A z(+)bHP!9Rpi|p);)Dd2m4H9?=&{?y3DC%WQP=7diF}Ew7L9Z}QNJyZ5ObBVqw?n6r zeQD&h<{NE<3MRpIu#)KoEU)^9c@5j4WK@tWTuQlgoO+3fmifWX781r0Pi#`&>*Iu#d^8BmZ*MrdTkL!JqiZS1G zNdB|)KaSUH$dT$4U7 z4+&u3E&jX3f4BJW7XRN7e1G>{-+kBrSl`7ADU;O?n!LMF+DFjh!?|1cimf?~2zCzy7Z*)A-jjTZ?rL{B*VWm)wZ^5fd9Pe~ewOKO0ImWZ@f%dW-Je z=cTc+jeeWEf1AI4{{S&E#qT0P#PD4i{x2xQf}j^d$Dwl?EyOxV)QBXjg(xTngk%;$ zUy^S8DpeORhR|u1eA2SATu@E#JHc<1p=*|{zhct}Hwbt3P%M#qqTvX?b!fdO&hJ}# z?VXG)REYl&Cq|50Mb$VLaq}wpa0Ubf$o6o3`Rdd|sc#54nQ!>J``y+KU2bI@ADLT3~em3^#iS<+;X5|j2wkO2Yam1pKQ+k ztNuRz0o6-hH?6`FFSOfxWOURejoj(hcrBZgkB^TiUBQsx=Jv^LH>?{d^OowbKt;({ zRIu6$flHrSg5B7`!HSYc3D#lZI~j)P5afwraRb#9$Nq{Vv>~4kBY&I1yLh;_Of6|nsm3XtT$bDi)AqiE#+2>7P?;lI!fzt0Mk=KFpi zmh;~|iZZQ;Ot+}+4&fcR+{6zpIWMC8oPY1f4KrRmS+Pn?G;b>6aQmaHC;hBZmaaY? z)9Dtt6dN3fUS$>7*q~wTziLm>7sm!azxNTXibC;Q%HaRM&1By<9+ANJwyRY=_+FA- z6~uRoUlqjnptUN9?~!p;5Z@!?sv!LS?QVeY;0_VYcRTri)lPb!SVc|JeF+#CRZbN< zpw}v{X&}bAEtOP^mR!9reyXKvf48YLw{A~<336-dV3$=-zJJwFDB&yB?@`Ay)BL$0 zikh(8c#gRG6lRm0T16)uu0k@pF_Q=cn1`EWwE8rejPi`dtUhW%sH;l8+fUhTu3sWiisA|ZG=LcwcCRw->T5{6T zFG@;ECW~jn8&(UiB`q{8Jj|-yLoV}ltGGn0hE2Bql$RhRk(OpfMjdb)lY}~DG*7*? z%~le#<4aw8uo~{HO6juIg?FE%S}Vj8sMNdyg|NGB0YYH#aXY;ac{K ze7l6)FQi^&<|{ixDJdyeA0Hzf>VTq?G2 z$xN-R$esFH=YC&ZeXh|Wx7PdB>#9AJrPA*FjQaX|<0j;b$|c3csrh!S=ANCrax0iA zc&y;fx-Swjbuag27#I`UeH3sjQzBZnQArva8j}kP`S726WLkhPSu_&}uZKr+x_WsT zsJE_+FnF4-g7`ACvJQ!Txo57DoUhLhcZXr!LptWM1GvRcSCgwYustuuvC8{PJ#$GS zetSMnPELwwa0i`lE+do4BzT0g1WyPFZis3w`?B~!z2ef+^q!ucQ}Xf|@Vs2slKrQG zG?*j^h_td&+Cg%K$MRQ?yiHAoPrcy5y=E^wa5!Gv>P{V&@3pg&jP`>6OvByjnoc_{ z9=@v;-8eq0GY`dgxb1viHC~Ey+vMoz^T+k(*psxhp6UGj9y>&{yvj1m$#CBq zh9@Dn{Y9JE{77H zv`JReRbzrqPySaGU)c?6=O~^2+Ego{`9)Hz71#i;35&NL76 zFZdC}!>{-@{qLLDs_FeW&r~pT`-a6#%rl-AZx0*hmD(&-n;5JV_me7LCCD1+&nY8M z={?^!T%lQvhiQ22Mi|*&_nXOrb=zrb`ED4JeTmR2ALtEg}doo|+sd_M5n8n`LeLP}0$ME-{aZr!J_nF79@G6gWb#+s?Xrb!} zga`5dgnMt{ka1Aru-h8DyKLc*?NNu-ZG`*QlnXwhyY<&+H`R`*pjO@Q3)U?Rz9F-n z1vzpfCB>N;8M*_tvv-80htfYjq9)8JD3BuHNPPA{Fl5z^tK5AFK=gb$3RzC&XZ<_MEh$V)C*v2F^KDFJ4@PUTn=TEd@`kDF_P-SIC_EeZ{p_ zBWQXP*&TzykZdwkAg9ylD{e=Ccucg`iU?HyWo|E_){*OWuUypw0|P_4;DjR1QQp-p z&C=46mrjrqEZz+rB8*L4ZxZ&a9khr+K(b3Uq zl56h1H~j?r`uiWI^<*3#9$KeeKy~X&;PVs0Ky_@&^ATQ8|GvvYDfyS?MbzCL&c89W zv9?Z6PiHVFOm-do{3L*TqpY3B&flNQHZp}ZYrFFUO+WVfVLRH6zB3um?+Z&$3~P;1Bw)Ll}u9SRR2);ae|LL$I*bN)7`_M}#% z!+!Ho|8^Gl;_|XA1D>p~Fk?*87lv8eN;zfDr($Aa!yPog(RaHmxK)cD0R-Yh_?Ri! z-fMsVEnFr#XseLztP~TYRO?zZ)8!FRrY}X=qG5Fma_==IceP z?c>X&hDRQaJgw1{Zm*4udcJ>5qA@dG8MfR0`3_6TyL!^wA@cFecg4+%fqF_xN{@X> zY;0_rr`D6Xh|zbrRIGR~!AnKpmzlHj;Np3;AhObtq{PIhL&m<}{yyykrqJ`}&kYTR zQVR<9_KEDArav~>w9=k*nGIELuPx+H@ET+sDb#K}CstxK=vWI^+b2KT%GFrhQ85d% z#YN9!BofIeM%~lhotPH8U!5}8(o#r^Ls?Q>+{`T2%E2BZ{{CqK-sH9SPn$2B8*NK- z^T)bhpQ~KZUH)yhzE$fYO^Mx2@8*zqd^m>_lsr_}(TU~yTjMe2gVYtw_s69-9|+dV zei|AY%HY3yLqI%Yz%JBl?p}}oR|elFT$~G%^L2i6>!cWYLJ_tkkJs_EtJ6LTd-S-t zk9mAsl6n~HDSCK7sr2@1JX!OMrIKmg!JE*%A6y=yRi!O+|6CB6Ik03VkfX#NHggqE zlMzqr>2@H*SZfvdMKEdgw7`ax`g>BqEn0N2zh1T`7SVwPlS7hFu`%^xATb%-Zot>H-ys@nL zvs=Y^E^?c58af=jH|G1_6^a%wIyyNW$f_J%Zi{vpK6lXT@s!k*JK#jpo~NZ~GtjH)#uAU;I~=cP*w;OGAK5a9 z$prB1a8>V)A5={FtI&>d6PxayV}7O{@OYj3)#QXw^Nqj%vK}$9qrBy{xHIB*H?BiJ zgLv(-R{&}5t~@f@Tr- zupwFIu@@Z}%_{H<@A0~e7G?D1tThwUQWZ5dHH`O9EjeQ@`<^6+g~{9OaoLRK_w3+X z_4YonSx}(IHy=w1;7PDs949s(^PLLl;v2~B+gah7#(e+dQ}97DqmJOxC!N$aD`NMr z9ShctTeKI?=Jw^DlRI9|iVS)lj@eCI$jr+dsQ2;|2|C_&TkD5!C~vKxDwU!W!1M5{ z(gnO1WVgC9<>(FSKS&eX^!B>kp^Vg%4B$KdCsm9qlK$vC)h&$oMTUJETWNgN=_;nk z*p1E2U2LvTsTmU|t{KY8B@2sLdA)n=wC(BIGS7EcZFcW@~`GTyVgS~Pr*Jf$FC%=g#_-4|V^ItS)tqC5t4IbPr zEiQS)MxkHJ_&~_Nv&cZ`TG?s?j@yv_n?$mi=~r1PDRS+aoxTo_@DO!AT6kbfZ^5KP z3$#n(_r0Eal2ceHa~1bk)I;labC5<>R+dQ6^t!$ET+B(%_7dCc>F*z}wBvm_{-^HV z^ZPg9$HvaCRj-hWf9UMK%B8V5sSO< z%vdDz!UyZLOLzUiOrky9KPSF@eDN&R;1L1w>wlgj_-Ryg)h>E-T&83_EJ{ti6BcfWp!>^#jH9-MuO+L1owIfCl?pFu#3x+qqURqBpGoIrJhvcoZ7<~U6YCNmyCaz z2j2hqVSj(W$oyAFk?ELI#a4IT;^(^SayHwyT#&67B+kL0xKA@+3VhXEX5ne3lcWJW z1JA}G7JL)?9MLDO<;)V>a@7TK^aOT)LOy<6YR;Z5m!;mVq~9j5t{w|sarIcQ^JqdSI^ zfwH)?bSB5t?AQX1U7*%L z1}!f3FZ!{`rvawr$KbFF@D{xM(EW%}OvcpCw4w+7aGIT7r6+9+m@~7pndRk5Fry); z!3aqNOrrFO3yyhFX8eY0d=Mh#WukTI(to>V49>|V_A zCf|w3%*@o**xGn{Y^-`)j8kr8WMogweFP?crJlK$i(oI{+`it?#0OQLL! ztS`mu%mJ9_>gzWZCmgJ~@k{V*Z@DkoF2Cmb&V23_Mh~WCAsU{!v)7ND=#`Fahvqp8 z!vb?}=R4u{BVe)Y(BA|q5f)~mTw+|FTd{~Sv@(jgBn<{^i%}_0b07R=KA-4A7t%Td z7)9L9@yq9pNgp?Paq*H^*L@4PF>2&17Bh{u_Ls6)oOWo4Ex+%%u7l0X%bo9$egIt2 z9bCpIyEiZI5{#>*}A^o1())8p&@j?RU{9y zY?WW5)7a2ZN@?f?hZ>y#4-XF`#hx(s{qq7*29XfxL`Bd>;U@y;yi(L7-otmi9%fp# z&Q-C|LT$a(B_tBmpRJVC;6vIA(I9E4P@kM#2XUZXI1~~SLtDr2s&Ht=oPEdFzhX(x zD2%Lm!J3kqTEyd*s8!>a-@k`CV$*Mn@A7;sgxs;V?VMWzDy#93I1hd*m23HlQygoWKX+8+=pdexlQ6GP__5x~3u zLQO3uY)T+OQhF1=-Iz5BvrZDM(!sM^WoTqX?y|vaC7U3*H&q*cZS~0o{_}smOSQDJ z(l%9)XMJfj(62J+>df@qcx*V^peGdw9_N(fW(>~(CeSU$+?We^s!tPcBvG74t)Lre z_6HMWu+D`hj(4^*bC3O8k2foKeOqR&Ik(C?Vp1G7Yuf*ooP^C0GM*cZt*27 zbB*H-Q-|vDklD+a3IHk|w*`jLs*IbJ1Jz?DNcny4#SPE8Tq>E=?@QZ;?a>`eA09kx z`DOlkb@b(!{gjwxr4&wLY$0kjg##QEX>S`{(RfLGC`3Y=6Z!g%m&?L zZJ!tgNL`9#q^;vA+df%TJ(P&8KVU|X@l(EPS=eeAHJ$!&s~V{{;l897>*@`E%-6!J ztE&kZ6J^C=?C?B*(;Z9x#Sp)%VetI==88S`WEGU5uLyJ^b?HlMl= zH&Zr{Rmw-RBb>)&3s>5fw%LvoAaaI=VYgDDytAR9A*?%AH=6VFY1P$g>UjZ#B+sc@^d+x5b5}QA0To8e(;0u9jCkgs_I}rjy zjy0{+Nk}E)5a!^>m$=On$bUDUk4__F#PzqDa1ibOxV?lK{dT!n)=a1VN4A+kpbbh8?L@ncq*5wFd+2GGu;gxj%CZu$PwmFA_I1Jdpx{f_><4U3>;9*u$amKJGS+Y;dGw+bF0-l?z? z^#jV3m6Z+ozp+g&+hs{x+x9286fe8~xiV!_UthQNgNfyGbajB&*Mc`R8;f=ThY}`f~DLYa~=Im0+)`=&|eUUNeC20E(fT% z)4H@xW?ac6!KZ{oI_&pd=v!P}^(uF{d!y53moIs8@_vl%qW(dSl`E&c9fg5NE9=Y* za@w{Mi_Qu0P7olbKd}h}Q$at1h(EkP=wHfwBa8p;-P(z~#KgpZe53aanDk>4H`b@N zdMaHr3g@CT@S8|=GRBt74h7s)Yox<9Y=vt--nJ`zp42s8L$C&_3%J2w<}IgM4+oL| zJ1znQ{#RzPi|NZao4e2K|(7cxwyDyb`NGYk<;6b!5{fh*T2dhi}R{d z&vWLT2ppq0ZPER!AJ~{b6FdyyDw5A7=3mY?K*x!>Y@wT=uTjnx-NlW_CYYo(8NT})O6K#?jKYS-Cva*?Qj+Aw)TG-_QhvX zE}d{SYT21uw+CR_J3O5E@qti_USUH~%o}4c1n6l1Ke*;i{xh!^er`MNjtUVnYS+ge zye@goOc0t3Qv#TnVf}}j3+*^?lP?U`iy2JCu16l9hDAS_e^7UIkZalP86JKF;U47E zPbHfM5K;hOh4Fc!Y(6%O-NTDnN7Xax#D3(`M93(nL+mFAPL}prs@?%zctUr#bnE*5 zp7W)5{Z`)3?iY;Y%mD;SUS2kCT?eWQf@A>^>5>k?63e_@!t|W-035e6h2P*G%#=qqLMQmHua% zHZ0X2h75SQ#fq0Ni|lA>N7$~^bMmWX&(Yv8nPTpon+mEvlC6#%T(K=5GX;{E1;n@= zC`xWFogY5a!&E=i4E|z1yX{!)u&IZGja|R>OODj-?}-7*9rz#AC-C+ERu~z6$BSm* z^*-uX`YVWsOR(Uwz2kP@fb~L(Mk!I8cf|c$99d5uY8d77hBcFj()8rUC|-W;GZ)?P zsNcxyGZtR>@{>Jjq~jzkNt-2kxaaqwo}Q%aY#PB8)cxG?ptnGUveMFoOiQ^^O8{*G z%YYx@R+K?eA6r5uy&``Oy?x$+b6zkg{6R$5Jpsc*oLq+G)6&)^W+#q1kzsxsm}^=Z z#jLIK^)qQ59$2#EfH#r{53^;)GKGs2bt0a%DqZ;7ubMwrz(a$Z3JSW7I*k4Vn!kUagb3qvGF)%}tL>Kj9-gSz@g+!$%LHqLcV zBoW#bqK>)WGum}w)(0QarYB;D7E&4JQE|wawPC;f5rJQeX()yu;jhJCa2o@H%PL=_h&qRDK`&-Ggrw{G^ zYwq}fv=j6No}U%OT*K0_SRQn_EQmNkbhvi+EpXh9Qm)=_yH|)d2Q>TruLxzL{_$~= z9!#>2FUT^GKY!{j7Ka%CcGa%fx$uTxdh=Y+`_r(E|8>FlXiE5D>6t@xw~jiaLt_TZ z108OzrKii*)!9LM^NI7NI%sFyamggc{F`vt)LeUxs39+Zfq6JM83ezeV);hHz2dl6 zza6Wo7Jn)+e=jAC(rq=A{v7^m`;%V9Ub{nf!1`}aiqcWbLeuh@S+X@k5r|%CjJI>P+5x0ELkPt&Q_tDE>*ZnO|fRFCU{_Yuk$4PP{T>D$!R^o*J zbN&x1VLv~=h4#~dzDus|u$yF^hWIISysqVWICc+diR3*+gb0R^K~~dIJX#2wc4)H0 zKxr~uB&^fq4-?TRLyVa~%uxNTA21LV4TquA`}>Y^3JNOTIhmQ#kPfQVCI0&1PW9Tr zVoChs@VlVo3?v<~#&q}F2hJ^4LpoyU=e-nTG1b^0+xs7ohxritn2$?YQdIPMp*tl^ zd+tX>Pagkz!z_u~u3%K8)3>8Z`I4>Ix*`E2N)stg`q&FUq&O~^<`oyqeT_HZPynhK z+3aiA!Ylx3A%ojS;_7)qfQ}ev{nBBfkbU)X67YTAkH~JfLvSUnRn+C z!Z3yNyN!>YJQxY3Ga|m8&huOXpd3J0PW-I$MpsUSy6cqxLeoPi@aFU zkehjZw56j&GH8DSxA;8L9G@(g&Qb}z5!;CYO$j;ft-n}SlC%teki zqWeAC)$?*d- z`p7jk!-XrY#PfkVO|wUh!xxARSFbGD5mqpt{H^h*`*emN+_iFwZ7K=aOr_b0fU;2G z{B51J8sq3kO_~HS=TCmn{T>DRMenQ;?YQ$~v8?D`)i149t^pN+F3m&G735Y{R>DfuBm>i8xVUH zhENHu79V!F9T$#+bbO&C4#W@l=j@=j^%&(+iQ>Hug0r^jkkCge`r5<%Q41?-~x8ExSW6&j#ziGxuZ_UQMk(sy@X9)+CS(89y5hL0scCLS zWhHIH%kC=_(eZ6jrJ0}8C5MKT!bVPgspg4vch(rLf9jbTY)JRSTu$P+w!_2Jx1T3k z4w-P~lZo&}s>f3yb6rXf79`fXBUy}SR;Hq@9&LZSS`2HgJx5l|uXqr|qSq_KaDd!k zv6m_{tMCq~Nc+`0s$7~k+fA`}wgQ1JsJ9-u*3LpVI&8PMmx?sM+JsrMLmKQdjpXP` zYLsa=pyNxbb};s@H)q?zc5XxdzYnK#vCnMrJ+5JIS64!FFvY^8Pi?$Zk|2m#&3Yr1 zUy9Sx1~&33z2*!V)HRxaIP_;1Z#eRVP2DCRpR1>MU#A7gg!&e~{i0&!7+qWkMIFPA zGH$Dt5xeT;cPqsf8sC0>md{p1txsCjJ)N29>1DQ9F!WJ1iLAUlEOf&!Hhq14kjRdc zfz&?alwDgP2?O+v)oeW5oV{wm7VuW1KQVPc6VuOw?`tG(s-&)a2`M_rWiN`wwY-|h z--B0fKYV?(zYWG&=n^7^VJ+djBH=U^SQGU(L_3{%CTQmd+}s>AH86$u%sZ(ip+G(U9*rllhr zwzkWI3E*LRK(69EIou2Z0So}QnpGRyb_2cZ6AffbcqpLkFFzQu$tO9w#>R5WtvY0c zJT<;*#wCwk6qCaD5FrUraXZw>f%SFk6UQy8k9mH;775u{GeHwYssDT@<$_FlMD)Pi z;*C8^0o=IMc+zOpR86eC;V&H?+2!>FEMHqTN3sGU2;{}R1y7E2Eu-2Vg684%Y-@`2 z==GOxlV7t73q_z%#F^I&v<SK04=f zSx28Ckx<=8YFwg*`KM!{vv*B+?TbR8nRFV@^H|G|=#a;|W_`8C+w`b7bnP19wD};4 z8-s#gadNC-1UfJ0QZ^G6#?x*{7UZZR^^r%!j8YLBVQ`PT+ud443azrL&p0P z;M5rKh%7I92le(1Jx2o~h$L?Zu~IEmR7TuScvrmZs#>g+CgfsUbE&T+&Qps9fHT5H869?5El;+Q|ZpZj)_P;JdEl=FZ;arh+ z!%HC355_XIKbdn9qhxF?tprd8Kp%i?4lvxibuXI9NWUXMrhp%axyl98=Xid9ap6Qx z2Lt(oOgELRXnt<{mvcIY#KfpP@MMEe@qQayaZWJ{d3lP=94`jj=?LAZ{N&`O-xitT z;Q^%6*NUt7wcy7ZDIMD5;|^?t=qP^!)Ibid#Mt&IkBS>v;O+P4I7u++{ph65I}{5I z)n6LYkLwvN*Iz;O(f;<*_>IG6#Wu52N7tO86t5hu| zaS0mUzeKW~MA@2KDZwKenq(ytdIxnPCKd7Qv5->zZ|%~x$hMz88dZv$b8a#!CB|I~ zX>pkz9^03VuacpJ(%eeZH;^RS-kXw`-sq?wFCF6b=nn7uF46D zP7She6Ef&dAiRRQwJ_)-T+?~ortc|l)o5gmyv;PidKr{DTWRh5QRJ%s?*?WZW^_kz zg=PrDCjIFx$$4-wucORZxmF_tI^gr??_up*ZC6h4BzTg#zECMS6g=4<@PyJ9c?%1v z3Yi9mpVpi<-NJElpn&T0G6_r|+r>c2f-JbACy8S^(RHr((sk}V3%zr^cKxvi(JGMe zOh|Zgy6EpoF@#%|mzOUtEQr|=;CsGB4>`iUUKq*U;y_nv8WBmVFrwQ^(|&WTBay5r z?dii=6sWoz+D^LEk2Nvw)+LzRlS=Qmn@p3IuoxmEE@f-Gqu%P|B%|*FVVP-*rs^eS?CnSh9WIz`J>4vS=p&I<$z2;P|)iOD9a`G$fB+cFZ{i(UR z;v)I5N)jZ$OJ|R)gmuh~%5O`Ee@1IJw4jN=oT zYV_;5h#O5&8kHC?8k#;J2+0JXv@0W}OD)v339$4Q$DP~~fa^RL*KetOymeYrkn5>eLfa_&qc>`Ikbd{n>LIL86u@OI}X4a_Cqw4-FVE|1uFTMFjQ+bC( zC7UoHmgVQZc{BS_N6~rW$zM9-U!gz*e%|q3_N+@dLB^399v?2j+Ku<2+kXqGqOGr& zN$1y_;(E!$ouvx(+D4fS@gGkV570>h+7!v3ihPv{OD zF?loFVY2mL37X^-Yv;b&AK$G>TXR`+x-y~;#c-Kf;q!iMRwp!JjcN>_R{$9(N2699N)p8K ztr!blv4ZWuhD43h?V)L;cbb7Su%JSk#r555vHi zib7Q=pgv9_j#$znBCWh>*vKLdtJy7TN$31>p@HhI)Y;hM7)@#w$D)E1p@8hQ?rJ7) z>)G_^bEN~Ic4>ANMQ3T@J#L$Bs8sa;t&+A01){&C#V7`)?6wmorLG1lJJvmFw|pHv zLe+HcQY`1}rv=Cy6&3{mpqPhjXfd|ad_uoY6Xg6M3oDWzB&*IV{{DUcq)sz3P~dug zv;YkVmNat=THpRjp8jpX8YKo97X4^O8Tiv<$(7clg;Wfww_?G|%lrDtsv!1u+^f=& z&|oI>leRbY8>1~DO(9D^zkvSH&bcHSW78iIHd%gs--`3LOs7HNkoDj%PeT*6>iZvG z)XqRgE|@~X->C977N06fK(RqkYfB3=gx-Ie{3&V2*0#3eKv@7HY`s@6pj*0`Vvn|- z`?GwL(K1G5DA*_>&Q>j#hH|q|5dP%k4 zDxqMD$F|>s_=6Q#0Z9d2N!>B0)ci|e*Wlo%!<*Q4)YQ~HTMIpxRZE?b8?Lpbmmfr) z2u4{R?-W_8yO`FFtZ=MztA$&6smI8qo=G6e;(3QEk{q)^$btG>rv*QTnpsa0+Yd0Qp$Zpm!Y_d#A5m=TEtSC;3quSx%sgf` z*m$%o=2U;c>wa9s&$x3v z&wd!)Ec~_K+R`p9Y#a9SrFYNS%@CJ3oGNbPz0hEf3_4|Qe@;f+<#=4cZ(;a`n%v~y zW9TpZmdVE6bN@O@qcb!oKpp9%J$&5jJQcrj+VL0v{I?>|z&kKuH<7nB9W1d_KIfVT zVD~RQvRKGORtB33~)#*pF(QA^NdcR=_`} z%Jnk))_A!$Sr{V``DXx*AtL<`{ zF274v%^j?fHH-u=w;l0Vo5uqrMI0QQ#*jZs-d$c{ddX-Oqc8#j0&PR4_Lbg5{O9|E ze#LtSd@{)vt0Dc$jpR^%_|I)|?+md&IyBTPVj0c;=$ZO{9c?Kx>HnoJxRhM`t75x} zk8U86W$imu@i298XJyEw&6iF2kFD|Q|6pfKC92&i&YOp-$5LS*iT8?D`+$49SO!#M zdZYi0L**-Dxd{#(%RZN}nTqZC;NE^*e1_Ej0cc`R$^Mt)kkC+r{jG%yxhgfzNY{~y zv2u*RDz*k{YZ5`$t=?#vus%l4J)}CrCqLKV8NAQxsoQq7!C~qV>c7Bco}GHR7J7 z_b_qg%NIGO3`gGLTO@S&&+ z{{C$M7Y{=5af(Q|vUd!VzIZJ<<0Y4MoCvr{QKi&0 z6x0H!orCrS14uyPYPD&^F9iR3c~l*eNpGL@Smr`5k2x5BEyTcsrm3k%kCI5h!r~*8 zlj{thdVq-Z3P<7EjA-%<5Ue>kIF7;?8<@^IqRH^R?0m!6nXmj=0Z#$d@;fRh?ZbG8 zber^KojAs-onyaQ!ZrEukXu;V$;lJ)1?sel=GCheMhUa+IYggdtZ%f=W#pRX%n+fe zyjafr?|YNfj~-?L!<*T&AI5yIW53nq$znCTz_@~5J?^hmP_(S}pP~N#k`CKSA1o-6 zCUIJ}Q?A&;r&Zc;hwMyn81)}}H3#Nj^oI0&B(KZ9`%)OaM$JG0%1VT$d;Snv)SXsr zst;BxkNWLwZ6WnJ-$-aC4Z?+92k!%e^3&xyk9hy#^2VS}ZJ&he1{2hpFU&@nb*b6W zLS5XGr<Tzq@AJ&pZODw<&))9ZW#f4m5UZKx{&nrAoe5G9|h znv$auRb*onjQYy8Rwd@4l^!3@4`;pMzdLpo29|@{^hSXkC*lkwFZ8UWIa+ksFm?e_$grIfZtZLm*bcC%fFt_#? zl*>a2<*uthB7fJEMeEv{tdNlBmc_Zr@S3gX zW40s2LCFBqO(dkWVJaRTi1J&+bIeFGc3kQF!{3X+u z7NrH`gLKCEv!bM=#I-g&B;@th{NtlZ+}%e+{@>Sjvl6unxJmNJGT=9q*M9r;0X5nE zNYqk;f`USb{)E)CHtVDs?@$`LKdpCJM>=O_R;Yqj1u8}Yb?%-A(e=u=UwMVQs~i-l zi2PAn6jXb?yF*){z#B*3JoG>gIBALTkRiu717<|30mt~vV_9Wo0)1O_+hpSC)x8vF zpmT&t?>qzedXlUzW$w$ zGxl}5-+dGI!xUzmpAxX^?EdJ;}yZ|IC`Q$uak% zFG9b4+{oeo?&Tle4$y*$J7iq)>0h9A+H#N)G`uRWq?7@=K8xuCR>To_fuOLhy&%yLosV*n|i=9~Xl#-X`hN3k>)vKwrv{|(*TrwPEq z|I0_4xh!$EMeTyOwJ~V$mUG-}bDK|3N_`nL?vN(lL~NJc&aRWnO@h^6_Q!muzw2Lr z$EIwAY9~tAMFX33DwYfK3^t}8Y~`4ZQ3}IMjavcC0qxus*PMczQjX83@0r;@S z`}gQQ8v8wQ>LCM5J^Fl3Z^;%=BswO>6~%=>cj`1qiwRq`KAlCfGMlPIId{l8cyTufgL#>G8ozhy7AlRsui`o$YHKiYC zY0jo)a$UP^t>MXD5UZI1Xc{KNT_sFoRM&*n15`j+==@Z0lXE2mpYyPD!#eFWSLOZ} zY9xJd>HE7=L@uiiK!hGB009GPabA!?DTpMbb3xlA%K&|3F3v4ilnKz(Lr}(}+QPPU z&Wsu8nwO`Zq`|k9e142)L0tFy(lW+;_3pqD{4tsl$unAw?y*_F7#FUE8Ify*zQ|q6 zpx5)lbZZhlOL?FicYPfZ~Oe_rie>-wqVjMnxG zNE3Ua^=8@jz*XlkM$PdzTkXJ7*1&Qx9eqdEP4eeqy8{EbvhrcAj?SI3VXdEuYO};7 zm2wq#Zt6H=`2Tu`#kPv%xaBpE91eBd%qiaQKWvrd&80~_tG&6qiMfBiL8(wLBO&45 ztgX>NO%`Zq&-U$^8=$ahz7C6TbhDC-2R5eN#20~DqqE{L12(g9x&1l5UApMu@KfI# zRkY{r-JF@Hq5q#}vRPV$qAJ>^+M^wU9M>ta)^!l;42=%HTUPyg{HjsXnOYdC_`Yg( zS{_zW(}g!p4Vj6Gv|g`XpXIucTlq73X#X%GO>uleh_pECGsA?Xb0_o6V{PiytCz&e zwJHBLK1f%4&Nv<7t+Tf=U^d!ATB#yqm36!`tnw$jjCt-|4L_s$#Nn(nK*F39#Z4SJpWW@}L}a8&Pt189i}UE2V=RpW4sliI0SmSghvGTr{6`Y3+qvRxK>Ve{;PWulW$9h)$9-Flk}=R z@=^UyOuL8n+_|kH9p!OrR(umyCw9&;2hb(WFND^1lByNf28XS+ha$u1{I>hKS558u zJ-J_QDl4m^IG_6))9+(X^2^IPpmI8la%6B24>Y7a`$N9tsgq|iJuQ2AC;PU(1T2}j zDrl2I0kFEbj*Rm|6Zp16F7+|;n(&#$aJz&bfT;u9_^DG}t=crnTn z)h3uA+3qZdjS=Iu$)hA=nD+63kz-o%(v&?asmOT7V~sGOpWxni;JO znnuQtw#T^2i$*Dvs+6q0sKmG_B`1e(m0QNVLV$Xn=w$DrtC+Ij)4T)R4&55b!&Qk+ z4m;w!7z*sYqQpY-PnYkJjsn9h9#sZ1i&L~_HIGkwvGw)| z^1~eLczgu=4Xk<(tmfKzGCE9*oi(0CzeX_LUUNG+(C()RAVs-u_cwa$+h#rraV~<+ zNF%$ZahHRhT&83wajgG_ES!olt8I)y`}j*=yOG#3Sy;+pL0zhdt95qG7Sv*X)Sm%_EHW?e)mm?0nDhwVq&>sm8wN zuq*rR^cs#&!~EdbM|KS*Ih=;}?j6a+Na@W7LVn(=bWWq9@E~g^uT8S|ennE=@$n>X z)ytan%?Q2~x29QhqmP1pqRVJQDyB7*-i?8@uP?>f6}kI+i>a1t*{u3_U2HvHg2r!` z9=T~h){sZFFpBDB$V4EaWHbm0+(%nI6x;YtyQ_X(NkR>T6ZT5k8YlKu$J>S4z)4^@ zNznU1LOO!T*&6q^32)8e(y87M6QgboGkg7sq^&LL)|^v8BZ*_JghW4$hO3jR!_0C$ zvZQ2Zub*vAJi24HK#EdpkM;ij@Yd(B$t^lBD~o#Ja;sHd&7)KazPYl93zs+YXKOtD z3B-Lr*!STFPxZv@n@?`eTz&stSA=l2b?zz!Q6jgjijz>UpV;w(CD17GRG!w*@0f2k z@e<~A5W5oZu8xrMsUPvHZVYc~xSmJrTt@=Whc8}AL~WMl8eiY}1lv-hEnBG80SUF4 z-$xk%lTo95imR(@U3-}2!v_kt1JOhCnQDUp)c^hb`x5Bh0k!pQuUt>iq?5tgy6U&| zA5R#0K=QH@?Q@0jECcLU#n>he6)XV0hO*Zh%E@50TZ%+%x+L(~qMc~0(Gb#j7>E6- z)4|pJ(-rY>XaZEhd{Ha^Cl)4U*w?S`E+=JWEtN$;4mmwHceU`ezUQ49U6j~q&pa982U}f{SsD#I zSqeh>`Szo#a=N;zJZ9=uJBdF2oFy>o^RVULxgDrL!7S*}N%n7#qL(9KCI|s6i0+u% zT>o~JJ|qW*w(NTKL>h&W$0S$7^ZILAk;O4Xct(RSlfcG8D)ZpiS#DhI2{&GtwZ>i!%Rg_1+q7_8kI zMvDqVn;8KS`m;b{q$J( zC5>7I^Yz(H3TJF|lC$$fcFuA=btt^?q?#UyMM{-du292!8c~V9x@+T)xt$!XACVsZ z{JabKs~>w?6DKZ)F>pJC`?y72v6-LH0GrUkDsFe~#F zN+Vd-%iRu2KXK~5^d;tEJzgh0zGr&;+p{MZO-Z-jMn*2aR^9S1GQxCVVd=Bbnc_NY zfe}xVCJD;H@Su+Pl~p-Zy<041q%}f>`EzZM4}IiKk&|^DMvHHIMOm1_xY2w(ytP}m z8Et>e7iFRPX^u&$d_?iDl9H`@Gay`tj*c9RovGwC+vT3PT+z%l2k=y0IAz?Cp zXT)yVd*X1H$zo-)R=9FFKDbqH%GV%RySu(;^6h3C${mZIhRG(a(>)G9$#e_l*84A7 zosI_L$XkdzT{PQv$j9EMJ-UlJIa^)IdCiZH>aw0eqvnxsvlV_cVq{UUr1{!xX(#N7Cq* zONzY#ikW^Mp|FS@x!XpD8#+8F)0P$%0x*nc2P* zyxX!cFScfOD^Gr}39QBKjikkT^Knf1!pgiY0{y)kK`vtI3;UPI+UZrx?nXw+KWv|{ z?zub_9Cv6xc^J#%G}$deFA^Q_;q@OMDKaLIfs{Vjdex>mShq1#+7znLE*@=WWE5cL zvbkE1G^Qhbf6K${!F|{p1;zgLNZ6DFuf?Fg$HxjIetT}^o+{6k@;l5*flo#Njwv% z+nQhG+)=}(e)LFts*yq)`Z86}sz+=?(a_)%UJvJxt(G|>S1e{i3vbVf6zg}ymTh&n zzEtk%WZ;R6Vk7@|hP*f)7h`i_;6*kEg!ld{_qZSHf4@#C9?i}O?#|(dPL@I*@3Kw) zAPy+ZUC;z1MStvV=S2mSuZ~)|xs}4}WZG}@VxUlKeC@*WvM=m;B5R-9yxe*!=exf# zf%bNuDJUo~vzd8A#m+Asl8#r8rIeKLBScd>Dp9^MIy)>ZEGV|5vy-7Z`}EBtc!LmB z?!pEhF}5S!qS8{*%{}ldQ~fHncu41A8TSop}JJ91#hBRhkfegEj8OYW`4%3 zgg0-(7MzbA6eri?d)F{ub|^eg=!{^W2xi&oJaBO=&>JnQNYBU+j;6ok)0JQOz@nxg z^O1K<%1S~n%MtAaDc4Zlmmj;Y#N=2B)zliM<201;8(@~WSop_I3;7X*vXkCipY);M zspP@*SklD0KtF*y2l3kfSDj~gufgu>82L<-FTRX4355UA|AETLb275CKfsK)U(Ual z|El@GKgtEZG3qorz*t%Yi9LvnbR~i?O8PQdqs;sXGfR$WG(fWPIz4z!elx{lL%C7g z5fiTh$ac%2yypG;VKn88{dp6Cd)z6m`kldRc<2eb`^t|89afcU4tL5nT86wfO-xqS zbIitL0LAJiNq+ln^6VL1xDV|3VAp_&)r}RtwAd)9qT)1J#Y4983X7r}*Xa|pgLc*L zryKVsp^G8RgEEWpHWK|I!x_EKaOqNBEw2Ud{YfFdeJSCAgi$9v%z>{YEjSuxh~mFIM%}d~FiCm2K^wmpMqkTxorwKd?J{H~ z>ETGiw1yFCTm=S3V1F|E!E#}M!!o=Z;AO2F#;ICGK*#IQ%70k3T;=N2!n%)nj;1ML-l(rg%U1G5t_(HDTSG-{0T= zeeSAPM?~Ad%wTG5?$v-Vp#m;!&hgs3e4XgST$~xT3cwu;Vl=wmYFd)i;A4c)DQt9h zbA)C*Q~aRM4!G6U@CkfEHr|^|`ZW*l->;~|>NvCzT*z-?tw;GX-S9TfMRAm9=jBHj z_riJn{Z(9)f>1C+NRTRIwV8^dCI1=!rT!zZx1+?+{?;qMCGS?cPr5+RH*zd0b})_r~`J>+o`kWR&l?6oT^Ir&Gw7Riz)A{L%$}O-g5K z(!Pmn{0_W|O+Xky#o^7GUE6#wzP2b__$BZ2GXLD%v7iJ9U*z=5_+fTrBA7;q+6POw7TuP z7oG54HwN&rm>z%k1Sr&*1_`eHB5JstzgFs_?Z0jkq50e5asw}Dr^GP+ADffMP}6tb zEHWxeXQ)8es{r;Nbai(AMu#UM1qH^6N(~1wUESxfG^*G#(Nu(A7@ie{u_WB~*Afd0 znV_zvCl_VyEv8D_6$q>HWG(G+d?z#K8lZ-p&$RZ)9|!>VY9zRsvg3WbCdfvS+GMBb z>IxC(W-HVbR)8NUH*b3`v9-k8-S^-eA3wiH8GF-8m_m^h$l7`}4+B1gB~C7ZE+GTIp}0C$ z-V7GA664r^=`bf4ijYtB#(V;^Z`LFhc)4x~EFm{z;l%t(z+KVu%v1I)=IIH#BXYK+ zSFhfoUS+KadA?)3go`{u+>jSYb03K15jjT?uF^xBxz2v|mWq!T*Kp{hSPfwY(3q6( z-~vUNdq;OrKFUpTs0_=&sR#9(yz-}0*7n#f^)LI!%InjB`FT`B(b=Fi6TK5RZ5_%# z2y21mlD0t#NxgvBsI4m zvN@k%V`gS{_^OMq0oiW@hd-U6`fAx^r#AUdZ@e8$D&`p#{RJ&U{#7 zjCO+0E|d4`_l>n?iU76!&OUkK(n8VdEqS@QG$_>a1K3v*s=0(HCr=XyozW(lbu{~q=f7gIt$3_t2D+sYB;bTIf`z=ASiXWM7irs|Di^^hfKigs9p5)`&#Wy97phn&cf+F0pcEaLKI@k zFBDlVM1GG9i;wq(ze96F1+Wy$$Cus3P;(-~Z13taq*DuRgJJ3+I=*meIHVMmq-k|b zi+LyVdg9G{cvKa#P72Yq;^$O*8SePUsB}Lt=6o;%lqcn1aHvFWZ|M1ijxNhYb6wBH$p=fG{j-2|B|ZNZ7NDsr*5E zPjtGrkH9>q085%LJUm>uWef5exZ`HZ64$^+xlNWW2hSEQIy7mHX&!c!jLd0@C?j8 zi*xr)3PjE}4IoeSaasqe1K6j<^_qCY$y^ZS5U59Tq*IBDbuw2!Dnq;77U)5~=1}%b zLxim|&dXg)3Q-q>f9EmZJJj{rLqeY_4!|}ILT5CBYB8wuh5AKK}SEor_XtKpr>3QFHt(u5`ioM+3NhI z!**(~-g4rX)2BJXw+%ia>V5?hA*G=Eb_*tCxu`<#cACY0IT;DG%_v{FawX&@=LxTc zn(>Y^{RHEezDsWbtYaS^a?knV&j&c=RL3>6oMG%Qs#bcccx}1=pN*k)(0PrYUp~UGM-p8RhShvLy)8Ee>LVim$p| zUDc*FLjsb)=h?;_x!vjzBoiV8EoLrz0K52)MO=}6?z zBlZtpX(t()h(AwB2}0BoI1NyDCA2h@Y8#+$w`iJ?nVDpW%tP+KfEQDHT{}BWwu@_y z%6|^Ei%Xflaog8`?$Gt(k3G#qx3C7Y4rH@55?d0n4N+AL4W*7f0m9hf6I&1 z2gq38JlwS*{0EpPh|xW$`*LSBo_OqJ{L&B@e%o6RUbG|h@R-tRYWA>rXq3w-q*>fk zMg&XE_PIX0(m9HBlA-xems?tP9Fo`X;VL93j1ece?CXQZgC&h2KZ2V6N5v35Y-kJ$ zV$|UA{O-MX{QTS&hb>A#fF>#^HHz80hK7dD*dUr}-M8$K$K2Px$}b+Niap0}^`_Fn zy2KMh4KoD&pIPP4p6zoH>Qc#JG#+gPd+qtIy(q-SFSV22;YLqVROgeQue9{9;o`Ix zj}I9#AQ4#CSx-r#eT=n`FaUXfs^!n(laCJqkGXIm*WAK-p~Hf_aqU1&uZN1C! zLlg8Ah;uOuc&NqkLKvVJ3wfAKTO%J`w?aU9OlEK&S7|*=lHUFW#QZ;w`2L!yK{&PiBD|* zWkd}^QGvsxJjhbOgtt$Jce3wrrj|~07tKB8L*9QKpY@p6J}H}pQ%J5r(UVycL7p3( zCE`8ITD6fA2F*YWPXqRbYB+xp(rfU*@-%Lz_<@_RCKUQ9-5WVc{OpU|fomBeSN*0# z>;eYj>_W6CL8tOi=-~ApFlEKX!+>`uLg#L2Kfmwsa_HV+RP&mc3_@lxHZKm6jp{Jb ztk4*%iC^+hdB|HG3O`1JGd@a}u=p;wQzv1% z&r;{(#t7q?RtThGp`8aIY?ZJ&mTD{~Y2?}MZb{uKSQ@;YFOW1}pMg5AxBs#V5@X<- zJ;>-4TRLcE^{k#G(R)_ypBl}Lph${&-#`9Y&m4!tTr~B?yol7!AB6U7t zHXXS~3G!$}VVy@rRj#;bwDX15qZ;KkO^Q2)1-iDh>Bj}#^On2V@+$o(WHC#{yjgDT z&aPUm&K||L_rg7t$LUq*Kr7>CXeT^rO=3jJCOmon=mC{?4^{3l@w0)iKb5*tqEaWf zAVcI6CythiiT{*|okvC_pX^mKRxJj__{=e9vX7%5SW96w zVye!f(K20$8hiU)M+j1YJC-Mh@5QFjUE^6l9*n`ucTQU{5}_*K5g8hYQ^6Fz&kt6A zF7!B^p&g!si;%hjX2Jh3(O>7h)e>6*^W)`zB;D9#T_=M%^|-l*kPW%*^6iE+B&piY zC>y_v&J9e)e7v6^If*e3(a{~e4?&T(ZbkZN^%iWZ;}$Ec4QtdOVh$4ZE_fUE*CcF+ zak%dwV2!aGxPQU?I&j%HYv7N<@MKtD{moKqxSoXEPy7KpNHu5yaiEiN3cKKOf}v%_ z4P~3LEYa_0`2Ir){rv$dsfA9L@@L*LK9GJ;y~QUfx6P3G1QTQKtDjq;bz+HD1JMsT zNCFu3B)F=M`gQ-^IcAhw!OOGRnkC;3Xlmw_-#!A_r`gIbuRWsV%f~SNxcbq*BceXu z{T9RgLDM|M&5-8_;5(E8_DeJG!vo~bk!Oh>F)U#%)1}4;bt(OD7eu^3=7*b7x}(uv zf1tBC^C`uCc~zkwV%+%TQ~Eo)(l^xDPY#6Nj;Dub=%h zRK4r8NyKL^0E)29z`sTeA0MBXYMLaA|G@KSbJ|LR3AP3u-%09cXBMYqcWi~9yv{b| zkG?ytr4>6%Si@j}#=bj%iYr*Tjg2`rG(w16xI2ef{_Girw$_=+;ez=Y$|2*qV+%GN ziT3sLU3`hhnuL}PB9mty7rU7aY=HfbllhO^JtHN0@^v$x?MFhk`dzv5lWQ3M3?ONO z>A$y=MOkPDFHDo2+rN5Lkk%hU82l{?jGA2kRa4dCC(AQM5(M2-G)88ot7=EH)~12B zHhEKCIgSgleZOV`=3`7+DY&z272L_Nd zMSj7pvuX3DZt7xnYJ$ZQAbfh>6%1CGoiSifR^frTOnhKHxYKNve-DBMEur#$Ud1;r?aBbzKkw3Ti)xg1IlgYI%l6>tKSR=<;Ll$>=lj zF5d=!ypLS{X5BtYx)hRZ@NvlSfD{q98Qq^q=JVD z34%)V%;nvkxh5KC&(5}{r3P^;9klgWc21j}%T6*xVS&*-h!31#LJeE}7~o&=ov@HE z2t*t&IeLf6M5fHHQU8^?!bFZaHSRWwKS*ow76N;bY_UGKi)G` zs=8QQZ#wztyR?t@MNBLACw?HICQ_^|*V+1Pk|ENUIBtV#kH!X>VeP*8(@qa-w?7|q z-x=4Me<*9bc`E?s3K!DS2rH|DPG}ozeo2?E%NQaXEiV{I@q`Wm(P*x|=hyA2!4;Pb zn}-LG+nHRI#7d~waU)_<*flr3OFpbQV)Dk1Hl42&rR-YxIhIBu=pR)I132=ThGXa| zF3P6t&}=e0^3H&@ioU<$(EmK)m%)=U<7M|9#&<fFKz-=B6i{MHSXQ?-E8(E3rs*n-=t}8twKy3YhREuTr%G>G!A7BffZY{^zE9#= z9T$kh2m%c8GPTSnmc>(sMZHh`Jb*aLCYKMh&HkbD4rVWm3wPOjVx z^oqC=gyrOnPQo0g_u9q#3y|`qvB>#4u#<=<=Hs2xb0fmEqX?|s+g(lV%wI4W<;JmR z_@Z6~#*l1nGxl4Y=fDKO$GaL6@7mPS%a*`?Q6B`XZxL_J=H@NNuyOG5dli>3JF1Mg z!0_cD6+^%30AVG%r?fC5`t{c*<2FW}6aq7A3iJ{Znz$7{8;(Wpxqr&C>$>A|W7iY8 zh(PHo@{y%+ui+1*cLJ3KlWeM_3D|5j#r_?TyuPG{3v9e@-sK^ASu5m{Wm{bfZv(Kk z>$l!P3y?O7!4U9jT!m)h*;W#iU7DI*_@G(b zERk4GLIm**?#{m@_xb=c5qHJSijmb!Hq*%%u|X_oSjDA8@=`|R5qie!j|-pdTVAZK zN2UG^?iDPD=88oGJ~kibCe1_+S+P1D?((`>R1 zR7c9~r?WQnuRZPcD}%2yzbql>!XbbOdtW8L^G;f()zrH>(#~or>noa9&D*h=g4ov4) zw75XXJr%Rq3=hZl%4@4wx{h5c>g$D%spb#eDx-hW^pc^oK+*NSN?OnCW8B!h;WYoV zl!DzurEzy=H+%^m~*VeH8z`0BS zZ{Q~W6(UOX5yvZRH!+^A#Ffh&TG)noaNx6$w`L@R@O=Dhj)9a=jJFkLE5G_WtZXwt z-baSlRZd1J)Ez}8*~i~LU##aW%4K)o%M#%$w~N4*E2zy|jbo#`LRW;Pm1cJAiQ#p> zNY?$EuW3PCPcYy1%R7%ZHk?%lu=~i+?EUlPtR zuDNk1bGH%yLOv}hqWFBO!z!d3O(rnwgA*@STzG#ISp8$c04Sdrn%8=Q)t{{jjqZ`w zv<>zo&Rs-`>t!pw^H~I-{9Lx}4Evn{@)$pMq5g4@ghTK9VitwJZDYs+ zEdqhVW{D{&ifsG(4eg74^)B<|Lfme9NV+Nt6wdbbP!winvJJLUE4|DB5@)*>H>W)T z($4P;*E=E?cD_Ue`S@T1m!})kQ)vgVWqb>$5KZu&VW_W1bA8vV=|rWq@CFb$ahfnu zvSm$52k*GIn-4!n_d-nS&nOpNIrZ}({>S1_nlU9k1*GmH2Lz;gI_HU4e8tDe9J7BW zf3-rU+PA?ki%>yY4T)6b2{@J7;Mf`jDraQ87D68R(Gx#(mqp~ncp756}gtrxg|1sHs9SBdwdXU`7z8`y)qB2V=QXS>t8 zp2FXkCJU&?)NZ8u&tG>XFW#3~%&^Dw$DlUZ9RrsMV7^1#bqc@_R_O$aEd8FeF(#`% zMmlUOjr))e=(prKRQr+_GV{#F$%~fM?PrkCeD^{Ny*k^tM*~R^zj+Y$?^sCj;(sJ+ z2r}Mnt*#1Udm7)J5$VO+Yv1&ofJaEg>olNb+j$M@NSK)H-y&z$sK`;Q6`fr&!T!2!hb52_=Ej>dqEcbE4!u!*SV5s<|wSY@IkJsZ7@qR4?k1~b)Ntf+P(^bN_A)F{qe?2iVBOB;~VDnQ;7sE!pPGpKo$!X6_NyE!nDJ&p6I#1c*LsIR3M9pHt(ay_Lsz$q%Ma z^FG_;AmPAo_2b>gWj9WU@5?f zj_KOJXuh!KhjB=uJ)msI)<;mhvN(G~P3Pm@XN|`VCWdsjVz!pw0z<`98O~;0s>x>$ zb0p0UwtO?jQ?6O z1$+}p7T#X0h~gpC=u^OkEz+qk2o}8E@r++m|*OZEWjwH-91L zs#X_{Ji+58_O5Smu;B+#(AziXG26Kq42BwYyPNtB3hk#JU8sF2ETNK@VrNG=h&wx% znxwZGA_nJyFgH4y>z=~$dY7g2qZr}G_v)qC_E*$dWl9ckIhOK$V4kmxvh8}Pmr@L* zmk3z_P6=t|S*O;Pad87t=2-}BDe2+OFImm~LKwPN7?S)+Ma&a+AX%Gmj;CzFLpZvM zJNaDtfTon$#XaiemVi4}dmX(`$L11zp9JIid@XpymKH|*2WY8EUY>;Ewyuz9rOCIt zX@v9r1BfBuR$YyntyM$0!!E@t9E;+P-t#k8(ma`ph83D8Z4hViVzpTRE%`^|>5-Bh z6Pii*kt}?-zwB<_XeyepwHl%sxM|C2pOMie~jT z!)p+|M=9oN*<1Ve+;u&1G4<2_lOA?b0AJM00%hhy{ChQCQJV$g3$KEA~ zOl;~z7}FnZ*wQMFE2XCF&;5&7ns+;j24wQSJhV!OENhi{2PE}Zop}6?)UKrk8i z`@@aAmY&n3@e`y3>y4Z$Dk}Cp>GV<#ZFiakXExi71DG6O0?PK_rxW|`g@|X!nSko?Mj>lJdEqKksEsaXbHQ5ULX+i z2a$xmm!*e?9PmmL&K_`{UUzk-InUKDqiwVqVpVn8K1zt7&CW>|@@VqP@k&bi_I$F4 zJCyrDc}GfWz*=gIfSI+J-<9$F!{=i25-^!nykKQ@pj-_CyYSgr5NIUL&s9JwB+4${ zxvpj3B~9j$)SMZ6KM8`xYsnk9MqnN+PTY%VNoD~^kn@drN@ss3P#eL;qCOU>|qSY+DMr_(yNNYx7@mO zhnICp#S-+?D)UM!IlZVBy>pLJ}t8q1V@#l}wsP#UrZXV-ogK zs~eoDqkg{pa~Jv-fS+p09P`Y*7a!TYah@sgKE}9myX#L~77`Zi-3_7zQ+I*Y=s;_2=QJHivmfS2KQa>(20+hB~A?*yr{kdI`VW%FV8-y=#;1Z+(%vJH{jcsed-Dc%L!*NDdPX|#@iQC92u{is1*0+Y3Jh&tOV?B|P2u`tE#ItbgsLK=NoaT1=Y$tO$b8rWoqAb7`tp~!q9u8T9-{%)shWZAg8JsBz zOp(A$sI_jX)69?)B5ZZCL)?f=-E@_eVoDaQ+c_D(zY{39Bel(?M|h?=RUCt5aA- z{hsNQqTji#(1C7^DWoac&krlDt^H+z6~AO}kbcE+-FlX0vqkHNy#vLk1XwAr$5h5e za*?#BIPQ38Xz1FWo*p$O91fnSudkPolG>JZCi%IAPdcTuz%#MKmI9Svfuz6u@>+d^ zMhUf$)!{~~?T(C+<%L)bVn9D!_R=}H# z9L)O{-o5*=vXZwvX4&$ILx$ccFN@&%KE8$u({*+ChQ!3_r;S!o3=rA=;41TKj);mn z%Yi(VPRW9M<0Tqnwec*Y5htOsmxPjlr{_eX81RTVCGUJ|uWgQxsgniGWqcmO#Ic-~ zWj+Z(Q`@oRxV)mB`5cShzIR%G0%qSqM}8Z1Q4C#(3PdYt> zc+hbv$|4T<+^O%uh(&%Dtr}0?d{#a@?9#@umyQEh(k$z>qZmP@b1E5lv)!*oK@$bz>cI5 zvg2OwTg&(~%r}nx!k1hM3nbnKGY?en*gAz4c~|b=m=`vVi7SysJLk#Fi?E=3Z8YJ_ zQc}P3>589G~AcC;+`9fS$Vs; z$;icO^e>oJPto|G9N!DJHHS|v7p9}~>6g?Npa!4^jeb(a@@y!7Z?Al-SGR=C_}Tnfy?*m*64YxKLNsXlDHTqfm}f1`rBb%qd07*NwBiGH2OT3!B?<&N>W~iRA`v0r zH{|FBS)rQ;kzJ7c6Y!S)@VSAM4#>64co=`XeTBDyL@s_4eCDN@MhQ; zsdUnVU5i0&96We%3zlWWX<$=OIppW*pZ(E?{IUntnLbKR6^F8s5uFYQIl3e0WXYMl#0~BsivHhH^cgv`y?hD7S}4o3KfKegaDl^Mf8KcFui!O_trFOFHNpu zH;mb<;p#Tq2h60SC)j^3{gf;Hs3=5I4A zC%1|~KlXYA;blXENDRB zipkR+`g%vo7XFF8T^;&G-!Ak&ZSvpsnF~;*Q?fULtVFf$rMH83Gt=hUCl|`xFzunZ zBWPsRyXj#{&wZwCO$>gs>-%{ng@r`l9$5Y#UcRL8M1h-cJ~3iwy0PvuZ&i$dfHBv& zSC{AKH%Y~kM`$PCWy6vGrUMZ!YyelcY}TyYV)$?XRuQ?(Yk3hfh1rq=`m(Q(M=8r; zlc#ns*h(qed_igyqJ)R*pKsuuJ-xtyO-{l5kTJs(Ze@O_3c1RszFQ;?GvmlnFE)pe zZ{XmcfC%&qD9Sl`>J(<+u|MooWCIoCaA%G~9fG%TgX`1N)9Y-q4iAWgAJ5S1sEkN# zw6XvPv2tho1*Z)DOua*n~<>Gaa1PHx`JW4gSwDvA*(oBk*Ado2Eo{QeDI zvY>52I(Glf68VQN z{TB~JPHAX}-UhX;tQ$%rynSL))M9AHdCpa`U4 z@Uo&+rd~hcNxgrLnPU{AsL#Qvl{I#oc`~)nGc8o!N%(i&9ke^hfMqm4&>A>?U4E+6 zI>ukVL47!9vPQ{MFb=RZ$yrXn%hzbQcf(>7zz*%_IwiHYYjA(Ty)QyV1gr}%S8g_E zkH4*C!9wdLV;ulcp=5u&1U6$%t7KWkxeFm0%27$s^s}B<8t0qrXUt%&{WIC^`Wx9D zNlf+d!d%vlUDi+1$2Sa9LnuebJK|)Q*&5!w+LyV@tds8*_iys;SBrvWEXrh~7@o_Y zIsrD7$1s&H_G~ymId)sEQ+{MNb{MJV$uU|5L6`xmJUR}@e}AJF|1dEBl>_!*ejKT_ z&F=9RzI1pXx+)aG%eSepp?6QQ|K=zN6|O}QbnP(q1ex6%_~f?mNE_Xe#Y?0;eC~zA zP0lS0ENdQ#uBv2t6m&K!K}!p&b+Gl<(6*Pc<3-rPKZ~iNXDH)grH;w(u#^ zp!L24B<6st<%31$O%$N0DC!l}!12`C1L0rr1k3rrA5}a%2Kb-&an~Ju9cv7u*l|n} zb)U`w34B*srzHZZ$NFlDtq%$nnwEfL;pf*w31PPLt?u@^>bq1C?@t8~@4xrNz1|_G zk>)f5miF^=edQoz7I7$Sd*jmzHC*iu6^Ei;!2;6$;UYx2td`HyGd107KC8K4K91BU zEF@LDw7BN*@A1`GdAq<<(WLSiyCcD+B>AyQkU5dMatU&f-_vu?>ujVX2ZpCTj_e5H zWnrkm)%QhguBY$NPe)-x>zhbh4fDos^_Pvf>dI#c!Aeu}IM>E!+Br8B-POwjWka*I zItiJ2K~P?y5(Vr;;{_U*MIz4)Rl>&TM5Qs*9-+w(~BbkSA`4eU55u zRl(E>dNP!wpl4$T|EkaU*)w#aLUmjegqCVVlxAQ($auOE?)n4!N2i^>^@+;@lfp(eB0UKtkY2 z$dvan#hSkEDeS`}m1Wy;e}5jReG(JHz$2!piy;1>iDbwFJoH1km|?U?{?Oao3p`o3 zIz@QBxerrQPPc-B)RNB*4Y5u9ps<#fmc&^nG$n#|!Do*K>yJOm(jNqC z$~;)<15g$#^I)Y95S#HoU><}AB82|hnr+**(Eve&oJkI2Rl=To#`Mbf?|&kp^=@EP zjnM4J)g2HR?SV49oSQe)gL(arCr!SR{upccufXX4$~74D=H4T$8F$Mi&#Sx=N<;+! zY+JlQ{VQ0m$r8o9-|@*h?9qA*$%^E&a=T-(w}0^0e-aTuJ0|8Pg#I7`STXHfm2_r5 z^E0@R#sY8HZT=5O4`!D~TGNmxz1c||{(0nJF!ogV-{n`qFTcP1dMskG>=*jw2%50L z&NC6lcqQnOJQ_R1zG(i+OL(L4Rls585jfmRN8x-{W)yBkE`UL?qCjvfnie(`i%;DZdCSn!q;DQ=o7<9KSUiv0f8@%K-Z8Clfu|2tJ-Bn( zBBJ(Hllfi8e7lfpE=W&5+Wb{y?bCmJm2;Q-Iti=sRbX!A60BeV(O4@zhV%mZQC^ua zpSuEgdqrNp^u>z0SWy@3$?*T7wiF3W@FS0NC<1TzO?m^ua9~8)C@0;A4rpsZ{nU=Tpu}@P`QG+bZzO z`(o+P3DeQ>x^lW3Z*-N=92q}#5^2J*E@oPb4gc1C`~m_Lm%Jd-aNI>HY!qd}$m3>t z9i^9#1iac85P4E4P50miMaWvdNl!Bn?dk2^6OiCG(VDO?fn+@ZnONjw6w}t$_HjPK^w!xVX*5~t$1M2a|Y*;0k1`mAp%wvjw-m%$6>O?G7qk-GdH#Br$D3@HQ zF2XcE`K11Gn-nQEl|vRPh2Gd*QHob@%UT{D_4k}7274{e9ldZEZ6{79#;%L3Ms=2m z)fmU;acqIngQTo($~ojEkM2e;w$3pqb;!9D7#O%OfJPk8#`|88ihiAw^K%qZ(f}Xt z%o0=1;psVF&y0le`6b{9uHoB&+gahuAwUBfsxSX4w`=_jmRF1n?*=U<>}nMVI9aMT?+)!x}zdMVxilhY1o!{q_HZvh{^5l9`* zy?kHDCC~84sm;UFa=D~HsOx*3pMUGsg0onB>ad(p=+Bh{jM)X2;}$i}#JYXKAt7cm zyroxVZasVE-GWg9aSJ){E*-X9ut#uK+Z7wB=)rlVq1>fptk*0AvW!xD;04m!MiZ{I z4d#mSzvM-R{OlIBFmu?PqQpepuk7L`VPRokei54Sz)R9_!WI3`6VBTo<{vDRTygkj k(S?&jq1+)9e8G~~mfDwVb}~iKrMZ4q(@-V-X!7g-0z>8ieEm3%I$2!r9#!(jh> zzJvolv0#)R06)$-C`vqq6?Rc9fnWY{cq;kw5_oxDGJFez-GNDpK6&Yyu!?l^d^taQ zy0Ok=647e-z~j8$<+OX^3bv^%PUm8XZw^;GDcsh|mA5KTIodC?wz4uSH^<~yrM4^^ zAnl|AO~09273h=vI`M{=Hf^v{T8M8DaO`NxK&<0nQ&MxXeZ zLC;|@af-t!pMla*%ZRiwuXP@um!+c>m~M-kFrV#N2QpY+`}AjTjqcfqcB3Clj%|;E zBNuwAb7bPV%5$o!oW>iXRU{P;78M?{Qh(aq>?K!LNh>MoLs}y$YR)$oXjVQXXDtK~*=;-KZaB{Nn_}FuP zZjNTp6lNF_U;1Zm??_oiqF%DjvW zQ4HpZlamvzWsOvHeQIH$wYJ>>EgK2li->XbP?V~tHl-&2_Lzk?)yJ(}>cgWWmx-#Y zFaksccNw$hSbrk4X<)F%^B9}okG+xl<;!y~FR$hG^{EvruZb_>At4ryL$O)tor*4@ z8VzdrcCkv4*;sK$6(#^IKnOV}-&#mOqaG($;n2y^I$eB7O@r_B9Y#he|K7Z{HS76> zh0H(8Q&zX+9VDJ^ZgVQ?D^f|*I@_wOpl}ysd)D^XOUf@_W(*CND6rU`n*x|BLOpS?}iF%WL%l&jM;~L z2L@qbU1sJ2`x>M@4@Gn(A$Axi_a{#((N9y~!w=ezwh_WC;WUY!o05m$2v1b~^_t2O zr+ZFSR8)wS^o&(iW6t}E;PV>kOesGQB8+v$_t(Q8?Uf98Mr|z+c53S?+*XFVdo%3r zkOg_HA&oZfh&4|wwb9Jh`*+^dv{H{qBWbF%SlX@j1wP+Mc0;^>H>`4y^w}imSSwUK z9q-N4n$B+E1C|^$+$a4TQJc0r0sBes^Ar3}*bHY--)&u~@;xg?(a!Vp2W3txDz}J; zn#wTfB=*;qW9retu;&HB+}E>xe?xJTQ3kQ|=tA`A9>iEPME zXZ!fXz~*r3UijOg0?jO3s{L|ua&iu{zLSUy-QyW+nYgls!^1eKQH>%Lp6TA7z`KK$Z;k>)v=DG7-HK7Ne3soE#d$F_OW%y}i9-2b%;V zKfmVGe#`t=wNsw7L&)x^$!RJ#$kGH8>qFmMQ3%_IxX^BVxm^XqGo z;}KeTXsf${zMo?UZR0IrF_hoSSX7%kZgUzA-^rVLv`qd;n$$mNm>p|8c5f?BWg?PX zXCyEBWy1Fx$6u>_HAE7IY%q>V3+jXft@kBsp zX#&7<;usVyNjm%LyB*MjX=pQx+dzIxOiV2BSgVrCG&A2>9>l|usXIM+=ylLe0@-0U zU6QM`Y}Q>I%?tjxjUy^nX#1+Z-(mRKi&~5gh*Cv$yVbISJBIV~^9-c;4{sdEv5D#E zB!vp@lGYtA=T)zkjMgNW6N}8ed3qP=xmDo4Ge~>*tC0}+z!Y1aw7p5q)Wbuu>h<~> z2Kaf!A7CMNM`kwS>v_HIL=vFmh0(=CoVq`AM)?hyHL~BJ44jDSy>XjrZ1V9nd8_|=7J~tAHZ74 zXtiKh9rpFo4ZJtNy72JuKFP5z5Z$_!o1JZo5K9Ds7Z?Hv(Q&00#fckj&Bw~jAY{1R z^UM)=)#VX`Fco$69I(Y+zj*P&rB?PFP4d*#r>tbS_{|5>J()7`181H(yQoO6prC+n zF~yI=`=n_5r{AgE)X8q;_M`{ntxNy(C2~D7baHfDBx(2}LG3+}eT9Wb7YbRE@FOb_ zWRc#detdfqSIXSBq8+m?-+4wvOx$K&3GH-F&X~ow_X*@&Uch{a9IUBtF(>ioqn&G7 zLMhXa)@mfw)z$f<_jY%ecgMXmoK}XG4p$n|S65g6$+~)HP`W=7@!`W72X-1r?SVgF z$A8Al%L~>9?Dg>er2(Uu&S)9{bH(mmFE1^(^Y)(q@IB1Ck$OV zRgV|YXwQ?tx026Jgx?}$e$Hnf;CWdH_%{e=gMR3O;N`y2%;$w!A%Xlvir>SX72WO_ zA@s_wy93!g(OV^eN8p_vT<}AuY-S@!c|gcHu4bjnIq7to2^b`>xtC%FTIo{;GVls3|w|KW|w;D0Hqt*Y22T!kiNZEXOCk~nf{L~`#_8e1hXZon?g0t10br_1O0*8wT#EXghLP{rh|awl zc_gF6qPof{I6t30FfoyP;Q_i@WFty7W?8PNfp@W55ScOxKHl6^u&>tgclVf04s`QC zWg)FqWo1JNc;~JGpK=7n7x4ZS9+9u!R}L9qB$=PiL34G7z@z`v`TJ$M#dYt~fWn$J zcWvjv27@Q8E&io*k6bl8Hz)oW&FcJ8T?>miS8mC9t_?9bz3dW7e z?fEF%+S(%YdV~owzOx}H3erOl6JAJ3(T;-YbR4&;G~Hh8ZEJ5=g2Um!(fVKP$InUC zivoFuvX&N8R)5a@FoCB|PCFW<#swghDp^?M!MEZsYJC354d&{82VJsf+S(dR`$nof zea=C!Ay>SNzaBkf`zH`h6?S%ZB2JF@9A2i%@Ao&vTrGTZLFD{Dewp_66Ks`?tkeZj zjJKIAh3jMQaamjT4&>mrFFEqv+?-x<9IRZb`J0P-5O+}jpwX= zl~y5AR(r|5YP(%`lDTL&zVFy4JQrZAOtQW-u^?Qgy(0{W?LUHt;`C;~|o7yX`qyd+A1>O@@39J79UA`%i35 zl1nB@K)pXpZukuCF}>)|qRzQMn9zaZfYFH18@4TNH&0l3GlPbw!Sv^rxQKCx6U=4~EThFqH2as$b$OYj8F9nMwfn!uo-JyH`=93{>3 z437KL0fc;M0pn;D4n8%7e|%iOXt97WjF4?-tt%5ZNpkal{S6M1zc$ns`r{kIuRjb* zM^x705_6_O3E8wu@bELMN8?}Ge_C{?r{CQnB=B= z9kAfBTDQ`B;XicNuYK(qKq3n&Dmnob#2nul{fExr0(8dN)2|hQB(5`_n~{-GQ^&^o zdjHe3GOxrm89?K|!)CYha;Kp76I19akFKsuRTk4&fVg-f}5fK3htDg<~7`S9a zH%iLo;n&X85nX0RW&o-7wc+`%fuW>%$F&=KK*Rm@4bBTReby)a5r?qm^A zf*d7R64C&UoFmh-jK&Ng;JA3rayx?{kmo?~l{L}fkfpMG9IOIxJ{JgvIQ;MeV&OQX z%a&Z|FN=Dl{#q=min)1M*Zp;^_Y@~1snhra(cqc~;#@{tX9e0@CmsgNpiXXwz1JZK z08=?;r&J2q!AH(`@Hdp5y229dLb3)Qj;i1On)9b>c8Kb z+LG4(`THC8&DUSg09E#1ujf2?MA#1f{Z!<;LJHPz{`~}YBlNu3e}04By|*R$AMN@4 zn=W$wzb~Sp04&*mz3xoY%m0r)T}B1degU9SP*4yoB0$A}!2xus+bGm45xfygE)ZzJ zeg}C|LIMS#1vB`WB^7OKiq8A`fYk?y5)Z|K2kGBt6u%pn0x$f-x)R|;*-4CSj4A;3 z-PI+#v%URe-o6#>-2Mn3JP&-0T2_cs;6it1DAN-`X%`^nbaj(KSetjQiAqjptr0Bu z>-OIDPy2GOmo?4`e6Hh4g)ylK|QbAth(Bk^2TU{5JMdGh3; z1LVAXf}@j@i)w2H%FD|cCP0z z2k60Ceym{sc;?5X+}zwe>duIC=>9vDwL0seE2e;7=PyhjO#=x^1W2g|hljIDN=h72 z5Ig$nACNVYfmB>Z+UkMqgajZDG}`w1hlU=+w0}B2KK@v-r4Db~~+EV*AG7_5nUl0Sb)Guu`)da-pN6 zqtUbcp!LB)D_)@?1jmrWOux0?M?8B2q(pvL?_}T(Zy1J6c6WvTpnLiw+dNw{!hO*-uoL{P{+VH|bqIQT9K8-Cy%YBqjEw_kg zLdeD1eLV;f?^ZRPl{c7FsT$`%H z)Tq_tr#S%ZVBA#p3YTf)Q{7itL%gx5akk(+!DglBiFfedt%-h5yOMpsl z;$kQ??cnv94&<2bhf5~R%__=?6-vEo4{^!^orrx6yFF2ACFoI?#=cx2fCqiWBOiQifpqj^3;!5M#tp_kKTdi5VH!PIY52P2aBgKudNLM zS;b%s>(_z}b&6D1hKp3e29ws+*;$JDr5&Pw28RGRa6VibtUlh9!qw*XKC#*9lky{M ziwt~Hpr0sqXSCFS#=|EI@Qv{R?X5)5DzPbv-ZSC+G3UTMgm^sa_s(dn>gEc}YD2)J zIB;izV);S~t;e-F}28 z8gjyzj+B)OOEWn)A<}xDVVEcJSqOdHR${bnK3d`u&R4PZs-b5nb#AB$Yz1J~W`m`uwk2^e47h zBSE&RQB%=sfBf&|Ti~t@GCc5{1BCEN4%qcW_MT2o%8Fa(BHrX#LiaxY-uJ19AP+<1 z2SS4>I*Iv&^7%-mo1uD)sJG8E#~Dymd8OEA|ihGadx4(!VE} zW|-;bHf#YWfBS zXv~FSFu+jfNbWk){arlh9vIA@`u_&kbjALGNQ&qrlhNRvs+q3)yu9^il950E|D*_;|Lt18uHMIKf;X8rEz zoo@*d0|Nt*YXWB-Q=IAC6P9$rg9**9Q@gZH-Hc!jILbNez0Y)0g)@506l4L_ThQe` zcg>L1PUPIy36@-%(pDgFDQ^7-=JhczXhz&7Cx5A_X~9sDnJErZ!VA$(IQOehpEX36 z zMO|KXR+ZzHOIKGWhR3%%E`RbPX3(*3wFGo!pMB`ypmJ_rUgb41T~DKVUqJdBooPuN zCSA(aOPRL~+AjZYsbajk{F(2X&v{>}i{}OLaQv2J8T0_>f%pJq=|ZaYJ~Y@o*jfOI zH*YR3$)4T!N-d~Hq`0wtjAl&20>%pd7{Al~rd9tc0cfHDSwBVt%Ho9KK zrt_idxqiXlODytYdv9lDHcS-+MSf%sO^8|C^5Wu435hI7`s{@t$wiI}?&k}g^>2jV zj)cBtX3wH}aO`$8T@M2ydZ#9&9G7pf@AlBFMKvc1ru(q(k0-reP+(OWH&m#^Ljlxx zhFh1mO`AQglIyamq>D#=`YpKn=+V($3~V1WNIp-K#D#69X=SZuUB$s+i)t3|HcsgB z;Rmz<)zy4;CxiNRV}a)IlvUDg!vf z7c0XyFZC2sf!xnjdA3Gh*FI&a)(BI`NMg}6>6*}H{NYJM#j;$1*K(NXe95?@qh$2j zN0k)6E$tf1z0zc4&U|}}<``lrOLgf}%rd|bs;W7KT^g%EJIs$_RMh}&F(?rX1>VBW z&e}vC4)gcXwbTGAfU?KUs;1V5S4T@-MhgK2x6oBLrbrM#<-V8#_7&2$@oJoq*I~*^ zVco7qfo{WO9~{U>)ioD1Dps}YwiOcr>~;F-`@spY%6%YDpSQ0vEJbVm92*}uIZ%si zLYdPi>9%&bEp$YI4a|(7dr@2T?v$7yV6eA0^||4%90S03dkQ7vH;$NTGZhtt+fw0| z@3m-O4rtUUG0Xv&lhbBWZqB*J<#xB*qn@=%!ra{4mr6?Pi`8Re8iT`x9XZ8zAx~3# ze2f4H2XYz&Ye30}89x9O0DLN0Td$=g-wzYs_*dv;-#`js-_a|vQe;yX^=kwuU69Zc ztxpTYFRJjyY57@1o>R{^Tn+0p-|T~wlJuR4JRcKXw%u|T>V8po7hG8k6wV*mJ*uLJ z_#QE786#^tkzHdV+t++kNw=0`LOPL88RQH6%2{aRvS)F;(*zutO!tr&7&UwT>yxyM5m!xPy}FZZr&HA3RglUpVE5GGwP~1J3F6eN7zQb9To+mRBm4POOq_! zZ?76M&=+MC$o!?Ms;KIY?dt%Pyz!Cu21EFI2pGG?Fc(Cja#@-8H=LAf0pgD#pfNnf zQlesWb5k4c&!ki9`gPq`B#e*G8BWkR{duiwPsa*btqh=7p!lf+dlldg%;Ew??;W;M zy5MW52}FYWkoNU;U?Vc1P6zvHd^&M4a0}HvH6M8wB!L&;$q_b9Iw>E8Yxydm3trh+ zUKMvlPiaK$^JPqOK_d}s{Hkb-A2Qoj(X2wvEjI2 zB}+=^&!0-^)+Cq2cIL*uUAg*bGarawfNLNZhSvhrO69e!SGPaoz=ujG1sX{Gelx3S zYs4qOpGj3KHD8)`Xy*~%EZ}0_{wd~cmA|SE| zr*wOtr~y_Nph>)2O8GU6pAn?qCRva$?tS73NKb7ma|!pG6pzktgOVq@&FgX>= zZjxJE%$CVDD=3Q;u6sU}T}piV6BWoY`3!;8j4bzb0?e4L^U8Vfz4KJOQkMF&Ryw&) z({gkBw~x12v#Sp|>NZ-E%ctN+=9_aDwuc+)KQU`om=0u@IA#Uuu>hdDyV^cDRxJrB za~x*gl6~LbbX$CTJ(UX*`YXi8;@D7lOA=@&+sk?01IvSXxJepqbcpmTtOB~$ zmHaYfp#ty*?=ZHTbh0nu@Om&X$G(nO@Vtn)xH!cK-D<}JhTjCw^TCAt(s$;O11Ty_6H;tA;F zo22wNrq>y;v+E-&x%B7_iS)Rtu7D{u@-$Vqeaugz_j)9aOsmV%k9#o-R6m2v9-2ZI zlQIyrax*nks?WV}XCWnjASWaOidKpM#Sj>X=QN~lvbcdr9%v*K&bWFTp5=XdWB^J8 z9MptrjF-*fmg?Vy62 zmKJfDWOxPzL4fEttu_#hvnwlEk!FSzc$sHl@CM!d7CowJwc6|jT+51txr9ez8@5Ns zD|G8I8y(c)9LFJ^F!+8qlEi9`$Ew=)sdbw@c_EOwc>oWvURGPg>U5C;(mruJpF{u$ z&ulgO{#hoZxCKNG}h-0|_>`Pf$bx?@2sGY)%CzkLYJ(bsG8AB~1<8-tvXsqDDg)GTC0 z)N;%{LRFrf#xf%<970~C={dB}$Yl{wJ^D3c#%ha{-IGJr(?f<()<-nc8F z*kItXVSQdKxkCb zm>uuifpR5p3(VnFXv}-|)Xy_T8@NGH;Yy^EY@enLM#j2QlPjKCZ`^-Jf0sh8E2aHv z<9j_)_qkq)sI3n6z!y+HDGB`CG9eCdL0W~=y!NGZCchA8gM}4K9Y*E(`vdWQNF%Ty zCr81^Xx_&t@!KV(rw{<~$=IS>Fq?Rd>$suIl~=%8Yv5MjUWl7TlH<-q(!VF}RadTG zXm~ieSDyt6dOR+V>qttzg9;pgW~QvI4FLj9w@pLL0(XO=+rgrqrrPVK=W`a{=k3iV zYk|ChK2is1FA%pck5k{EBU=vvzukQBGP`6`1XO)#C}mN-D0V#Gk-)12v@N#s*7hyn zFba~ACeO7~5(Ly^3T(_UhdaR1_{&Sj(IAzX_)M|$7?cfOe6!IBJ4@ny5^3vjbIQw| zVw3_sLE=%0LquOc)|ZzzWu_{%{#Ew#r-C|-v9UY}6_=IzB{4puGLIfK#4VC?Fr&;# z{iWI6HvSN9(9Za!E)iq6O&d3J964}{30G2Ah3|7@kE#FtOpEODKVnSUD0`gQluXF+r8w0OrG>E#x zD}$1Boju^+=ZUT*M>Qd0+6@SJ4$F7&ssp$L)a!X?!b$H^y5ic3$MbCS0we68o=Qnh zPz;o~1b%Yu^7BpTY9ewR1HwS%X}v~O+LQ3-hF>=UXGQ7y)7Q?*rSIg3k$ZTIqZLG) zI6f!y?*{EJq+IyDFeZRn01*Z)Y^FPko*+8o9NyDclv@moGd_G6QQ`MVDrR}JomEv? zISL>ZoRFM?0%b3+x`poKqFDAy8P$r6PpYWeNnJ5wnL;Dc=OcQfDW5^8ae<$E%)AyZ-Z+9oveHFxCcWU)l0)|DF9f>rURUhmmKM!l1KOctLoPE1iSOEu0`LlXl@_ znB8(KUxy#j1H}uObM{DlDKhnxFZqHWBhJz%=sqAdeIQK8IH`vp)Kt%{uSPWFNnyM& zOR~&*K<3{(tlf001K;gyO8XOUU?21Kb95@`nTu<4{~w~|k-Um?^ox?xmx_uBYcJ0l zd(<@ApZN9FVPkJ(*_p3D`y7044G+Hu!{PUNH`$kFv-O0kbS4dbW9JM_> zj(n!F=5A~B_1*5@1#di}sIixd+~eTj$gZduQnZwj2?4B~OVx=lF8mWPJaN|AU-G*z_HP?P`oJ5dj4q)~AyE@Cm<#1>!uj7ZK9zG>xAp1p%O# zbJPeU#F44eDn`CEk9$JqzZ3gdU(g>Ypa34WL}H0R@XR|xlC1IxybhVy4v?&bU?4l7zma_jpM3)!e;DaWl;L~fn%V^e8`Xl)njhUDCq zxeNh7MuC?Pl7W?VxXi2{N4wH>V+L8V<7!WI$#JFI8?J;zBHgz-8y53RyPhj%VlM~Z zXe3&Q>0k6+?B5+EAsmy~^IjY-*-cS#{D)RjX;Yi8Xj!%4 zUTfx?E6M$}ZZ6p=DR+6J_i$!~oxmO2f~5m`t)}Z*q?F# zEPY%kQe0lH3{1L=h#yo8p1T+b_*zgFM<=-5(>V6UF1=Q#2+Cipt2vB2NCyYB(mu$> zG1MT17I%T}Lxdj}?ZAouEHk#lHA|Y^5F&&cr%8bT5Sf@r*?-2j{17cKzk(w@&m;+? z8<4$Sh-PbsXj$m>ivGu!^Udi0PEm&m)gZdVw731R%cXF5DJ!`!`D7caH;|0rEPu11#SHd@%RsRSjvrwJxG^o}b3MQj# zDLZr65mqP12Q{^qOF{Y)gRUT<_HWdKD(E!6{Ne?Ln-;f7Na&bV&pHXzn!5&9h}zrR zIjzRZo(waC#4yVUnj~!x^bU|}4#%e^hmO`8gkO27s#ZcktY!@d0Ln!`@xIVlJA2C5 zv%51%0=pyYJN?NgTEGyiH(KJcW004B-*fz@sppx&%<{ovph65V3VO=QiJ3<2(K&!& zb#h`g{r)eWWZzi1Om3l&(yd#wPIKWBxfQ!EfN-ex6tbySI?KWvJ33<7L9O=})$vRJ zxX*3OEq|F6Dl%%H97G9w=ab)7U4g3T)RO)*Ni*KHMM3xk7)-fdBMul7Cjk2@;0OnR zm>1mysKA%t>G2g%CS6)za>? zzp~|{IsBmW%_1q9Ktlmq2FMyJr{F=+EM79Vxw(MeWz4L77ze6wiGjcj@S$6s&c*Y- zj#*ev3-(!xE8glzZfxWJpWZ(E@%iHnFF9si)??{&W2PBYJihdaPZIq6;5ee!@0?%R zn|HRz{yw}8g#!t^sv4o*sKiSBv3fIq$4*XF%}~NO`axKSC?3pv(TKE=bjF~a0Ysxr z&p*v<+y=xy;0+Ei+RLk}kwVNOwZFb^IkhuaN=8`Mpra|p-ceE}ZXVUlZMgQuo!K)f zSu~S+8mOUW^_;#UIi(8FT*ms}Fp~GULc|VOoyHg2>68_K?s1QG6cy9h4BDK!1@{;z zLVv99=rs=%`Gj1tB?S) z4J5jBLFIWVk{@=5Ifp%!(j~$oXh2afcBpZjc{`=ao&BwJ-O^7Np2t*I3oo`YqBKH5 zL6D-hcHR6RXk=%MwRVx24lu%#ouc{ZSpy6Kg~k6)PT$`kUFfKK!HslGpWg>X2nZ^V z@AkFOSq@Mb*1iE){%D&Alf=5&ySs8sh}$gBjPaW*XGob^!fFk&vq_8CyZMmzzh#36 z##ua~S)cz&N$$=w<#^c8AO&s6Q_S8H*z^%dYdM$d|6VM7i^fb5 zg=AueBrbmcp!*PS^smdc=cV~l##Kq+&5Q9Gy)TWafF_4 zR@KF%>$ta$MRsK+>l7$~(=BshQ;DEi&L#=)?1oKx@nzo6=ZwaTypTx`aR zzyjhy&9}j<^Ak7T9PPjFvVOf_i^u z_070Ruf27?x%Uha8Bh*>Ka@v{E|KFIpw5UI{>0R?Il7jvr<6j<2+{`VFdU%1XM!3s zFAxfdOdSq6MPzua*GWlGxzY6F{P*auWnI@y*>9!OEQe#udw=Q zgyTwq@PHk{ONZU03v#9{A-4gy_1ZD(znA{&dp7+mM5u1v6i~PMB9lxJ2-AQI1y~^_ zA|okD2dW=$IK|w2jGx8w<)KC%nf-tcH3ljrtdlD-@b56y@ zm!W?TRHRni(sw39^2nku149c64D5?feg%jfw(Fiel;oQYHir&BgpeyoFEIU{(Tv6+ zf`(;Xxb_NnnW@3n11qzsxV1=sTAM-%aKgaM(k)h&$GUoVs`B0+6m`efU&eRl_+Sgj z4Bwv&mseJHnu`Nw5I&;`3#vJXUkN5BmI;CKek4gygak|>4$SjE!b zZpr*%=QBBmp8oi?m;QByYd%8zw&l>j==zh2T$9A?t*(Oagn0$WP zr0oVMq%y}P3#bynqNuJAgeJf&NxX=dgnPuw@-1D7W1Ia4lwF!Hbdd3Fh-SK-wYmgY z0^m5yC~TmtICeue*7%3Lr+^iYe-rAyBp5Ej@tHLc?9U_5wQmq)DNVoMNze}o%aVDb z=ez2BWNmP)jXXrJCk>9bN3WN$uy*H_MBHmXT3IK2$k=WqC}jGu-AFBTYUn{WlPc5E zTQ;GKh+n-33zuVXYGhjoEcT?ivp}+#b90hrEag8SJ+P%9?O;@_?Mep3?4-CzA6>z7bcIpZ? zX{jz#*PhP95t?{A8zP295o78-ml;-lkJDHrk|<+*uBZg&^v#7pw} z2Wwc9yEW7^%)L*`8%|eUnu~TrGc&Kg+d`@v5DHGw-P3RM-(mCI|J8Jmm85Z7PT-`y z>7cs0w|8tTnkTu_C|&;hFDp?|mY5)*nD8|0`vs*{RP26?rR3KMMtE1PWg`mVh+B4p z36&3obTu_Sf~mX|XFTiW-)dEqP1k$YU#q%-b6#_NEWPkw*}CF@J@23WxbR~RBE%^9aot}739EYq^u`x;T!4FH1W?qw- zAk<9~qMdI+TU7RIakAOtuSSn!MZKZleSFcXau_}xQ!|+woFX9Q1bVD{bD*(#eL~6; z58URY&-O+J+$u<|1y38&OCH#pPV?M6q{eRXbZ`wrWKPP|ZCe+4trA1Y<5}SogE3C* zMR3FMU6Q`SuX=Iu+EBXZb7I|td{Uf~!w}7)9Y;Uj({l|tt0K2!-P0X!34__d{XOr~ zC&8p_X}FqLw}5Xws>Owd>a<{>E8Hnx3=pAe^`35NtF>-hIu0Vmd3h^?rzg{LHvqpK z-c54D1swiUppRtNz4hj)#EhrQP~@1|{;x4oUVB5yMCdU;MP(8N?ozo~%8YUH{1|Ax z*;fdC{Pi-q%|IFt;wTAY#PfjvU?Emsj78O)WjqRCIAgMajf6GPiG_YDzN)WVt8zd-sn~!kUWM zV92AOltt>lVv#9LmF$cq`(%4kDCH@DG~e-&Z8jURR)4f+P)NyTsaCt)*S-N1(&ouJ zk6BRB|IVduCDF(nJ0Fqbqy1fPbCe!5Wpve~@JUfwWX2aNt z`sbjcKvY{>yLWI9GnvWpJ4$%TlnBW{ayGzADBr+(z^pOt`G zOleSe1arM(l0-bUzpGvB(LGtVg8vY-UHob?-*tUZwdw;zVSI(L{lp>a7C!ZKVS@&O zlhM*b?P4(4Y1FlcyjhPQ&V-M?XwyZ& z8-I6^5{UaG)!^3jYj(2kNdL$CxM!2?hK~i|*5FE5%3d&^nW&a`C;tu9l{cYkZrv9) zR$G{hoyJ2=Cnpt$;1`-1Yn%}_Nu#6{>gv zJU(Hq1<8H~m*~TnogqzwgUxvf!J)CS!?=|b9#1tU;#vNws{8QW(x{E{A|wTn0gYC$ zrm?LZU&(=JnAoIz_O9-ZE`3vrjHbbCX2HhKXAQx))F;ZGbAIbV3UndQYp}aqg3T0{ zXqLzCEyCdl-9D3ivXpGFK3TU>)r~P?Qr{$GGarx?9D}l(pRa!JGZgqQ3W)ILJ5uv> z07=*fSw4os`a`7uO~_1Ny+2q$3kUD+#`G6H5f#`PN6pePt^v0W{ss$ROBs>zKBl#P zuoZyitiJy2J?UfI_+entSNQFT3UbeO3>zSLI#N8E9OOWCO&CIk+e^R>KHt`2oiM-f z80GOycNOb9ki)f@H)V{rA1f+i^w%f7*bJY`j44CSxJI38rrKV-FPEVWy2SH@q;Bao zIP6#I2KzZu!C9H1?c3<+?A&st!6qc<16_tTf>*Fh_e5CMGC0cCh0Ww6&2I zSceV6sn+6(KXa4>`Xa>vm`&A&K##S0e!jqFgN59OjI(W34znR(XEqfl^1FzG(zqE1 z6_5yU>Z+@gHP5c1M2CYZcprn+ngIbhEJnvY#}e3Ti__wP5K^6;v_r7sUm0=C`{(MZGuS$?5}LNSO4456)O(0vbQAle4q9L@}vJ z0^Hqmw=_9~MAwrIuwn$Qpxmr!uJwaKYXohvaI)}PdJ1F{KJ{6AF+r7`)jTKNUaj8y z&)qt!jyuh;EYr_NI7IDGb{Z zftM1E-}f@K4SMo&azbyDPsX1;A@sYCJ{bV7Euif6etf$aSA56^IU!#0Fsj7g_XcRW ze%n^ttW18lG24=w8A6mi5 ze`vhem-`!j`rX%roJ!7UHMjXD7a)fu0DD_C~-Aa z;9&Z`IDnnZIS|(RDxwFB1suB(RW>p@2Iu1-yTF}Xci(Biof6)t>=wH1Z9itFpfLR) z8eA^&IEZBG8X#k35_CVmf^%>cK2K=aXbEcpMc$)L2ii5x&CMjb5j@n_6?BD}7{oTOdLK zjI8k#?pRh)LEAO{tWVa@hR~s~_Fkq8e_nyPj*-rmtsw+=19AWn<^xd4X4bRp2lHq9^K)Ujta zmA9IV-MFdY^jCn{FzL3|-^Kb_j{oIcGst=$16Qu!mB3pEUkftP8CgMLw*mAtpL)}; zSLvzbfXc4X!u)NUV^hzQt>iPK!*&Da z)%}0q*=IT=L5aP+z1Mek`e%aKWy5q&tCzA@x`d7hT{Kr07kPertHU^OYH_66NfWs0 zhK77E>;o64aL^#v0bxU2so&of{AV7a?gAfLMZvia;3;+1q3~v#78f5c^AK4VP3616!M+YkxcopYg(q?y2}kxxcpX>ho>e3xTL)Z@8nA(ddgs5m)S(&I% z@-e@UVgoz9;NNU$Wn8>OvuyAjg{B011<;Dw#;~f zBu7$Mt1$02C8)Z6x3&Ae?1LbMoXx72Y z+)~|i@b)cGiLz+51MJuJ?r7n9(92~3ZwP7@TR^UJ1GR@9ClNmE4ZDH5e-D&Ry=Vhi zBLGS@k!+5OJ!)Tm9jaBVhK^LOkGN1KfTR-oB*MD@0!8>bs=8iI32qCq5`w#(Ht^DJ z;frU66WZdV|I}fjmYJo>(3mJF5zztkH&R*1K3{C^RyGJ4cPDub7zm$igk3$8^LkhT z!20%%fT~bybR@^lTLLa`8 zXHOYvR4LG)Y>!4>2d8U5tN&lV3)S&A1OHyU=a2>teE#-jUPrslL97+g1#&J!UkC)J zviL0yXPiDh((?qnIARED1bT^hn}EQD9xbJdX0EwEROHQP+~N96RMgRlGVWkDxKBy0 zAO!MdQY^7|QWh=}+V=JlhBLu27au-55Z~YK8?^Q2X01I7A-u#Uo^3jBExiw`azuPK-IYxe=k1 z`~>(6#*eRqBDJ8>EDk{Lgk5*v>pt!C-sk=yA4Mmb znO~XH&-a`;J<^`T%Eh*6c`?+HZ_c>hUzH@l?4){=5JpZ=8H9)m@Psf?kop54&Q$9_ zDjjy|oTAd~SkqaD#uDXB%H3$bf*p~jh_#du=GGS=0)OI;Aa?ttC?dNB7X~#zp;~7n z647THJj|q686=5jY43)j|>oe-Qcz~!s6Tm1sB^yYY3&cGLe}?vM!CYV|oIH6FG&AhKag5`K_phxG9`hs& z&BxFQDoGwA);?}7IPf(J??XldWgdpuKoC*_pD^Hr@Tf3+rfSp(B?reN_MN}#ZfIPE)~s9}KQQtZ=ppike)-|!>w#Z{AE2 z(93tU0C;KNn_+~)T?ig#FZ6Phi7Ko@fB$V`i8B=<2VNKy?1TKB0_}c|{#qa(h3yUv z>XOGlyFw3+a(-4ZUtgV{d1Y(UW%Wuz?bU~<_Mg5L4DA-i@!R8 zwZHZvGELm7>)=E5sIB1CNwXd)e;!>OL)F_y@YJ^M%-=P-NuyVOa<%WUJe;^k-_@Xy z9=o!Sz+$jOvhD0b)4fLT%gug*fDxp;7!ucHIxz0ABW4gs$acRMq0Y;!{g)Yu0mx@VsY`JKf`6TjT?;Z z3@g%@zyH%z{tXa33;|C`fQpdlq@A5ddwXI^ifH~C??o()vFbZSTLGhIc+O6!wYt#< z_$3lrT3a_Vx>>4-*%#+FkOL;{CN3_p%j_Wqpmylcp_(YCp)*wfpST)6d{{f{xz(Oz zEwlO8g9qs6&+K&E4z6E_(xhkn*ozFmIO;ks@yqXK-d~Z}kqZ01JUK33O9)-Vq{u(F z-L_J}-$NpiWUcr)N02tuTP9GT(9qGr2QH?rCjikyXXzAvrz7?aiDeny3ylE^`*ioK zK*D|d5oa-@C1d?hv>yGRLdz>3Y-(MmMZZg-XFFmFM&1uzu}R`y3S>nmbX@jbVCOQB*!jya;zVL&4hYy%Gio$96&@5lsvQ}U6AFi zlB!(J6}B%tVCEf(kEg7j7@tiwvg`cpF0pWY*H7e z#Ko0i*Ild&Os4PHusI3pU9*UAOI6l>kc_U7ojP_=3mknw$3ep>5ffS;C%&fL!7Q@xN-L#C9Pes50Kb#l>V$!(b7} zDey3jQONmD#1hXP%eP88y|c8~iy0OPeaSM(`NLiK9wsL22KRDYSEW@#cbU&jhk=@* zX3A(=mcm87b|Im@k<4N8aicjS@hk6dJ&>Pz4GW_asijCnSBy20Zqk`Q1r)UbW~_XJ zAK5FucBt~`>kH~$4%pA z{K#+LcryM-40Ukl-uOBmp@{1HA1xptcV_~*Ep9SynQQ{@Ro=5NfEApal9KY=Jm%*} zC+%ycNfj?Im-G=82LyJ zKvqb|8A3)qMgIPvMYjQrTd#Q$y$|xMK4LYHn_ShFJ}ZDQhJb{1{dBv+xVzX32m#Mp zoT(e!OF1_8=H|(NJmoTyvpiwhCuI>i(HGar+c`4LhEVt@(= zmF?j6tuvafiZE$@aoppjIC3fDuj7YRMSeq#bpg=CW*yjm8!#)yAp4XrO}-Eixgh|= zW*v_~UC*jU9PgYk`Gw2*d_Yqu9)7pF~pokA?7&Rbk zcm_KCA5e{ea2v`YunoXa{9IgFStZ7xBn7@m@u!14TMZD}&P|8+Owm;E*Vv(w4dbj zG~K)jiajN^8~Dhz#u{8SeSr3e+jX7SShXt~@k)%2cy|3kKx(L+c(A`~90~2CKX0~} zVg{h>SRtKh&srcHDI9oJy)Wo;$xVTYE@;MMvM`st4qyI{@99Yy_Uf$@;8Z3)vp9tK zB{x?Oo6L;&qT&_1-KCzVM+)Aket_sehk}T}3*9{ej5GD@v0&nY8^7pH;U2S0{kN|Y zD*o`5{`t1=m%jpfLns-EVM4E{KC&P|+%~V@3V1lm88IL({RB>oJv&=AsOO=Z_bOv^ z%3QNRzS))$RG`XnfyTT7QQV9xmE9GZ-XC}w9htk8r!&G1A1X;io;109vkI3OVg7m> zH*&?Lde_0*A||!@t244@e>JzY4Op1Rt8yqN(QA`N2YKT$d(XhW zTDF+Ss@dj9K~+M1VbPALoSafJL7#`AGUM9eTEZkxl1?5i*nn)&F0jm&gB&4)XBPsP zdLbd9uK9sT+F()`znu4U>(m*5lNldE=D*+E!Xm)4_!eYGO+kv974QD>*U-}0u@@VI zJ$RK1We$h(T{xTE%%gX_N=N&=dd9X{fvVW_v}d8P+2jEM4`Un8;c1qCgi)(gX@;a` zeAJ95$ZGoRQ(}KrM0b1`v^-EI{M3|Z-RGGjfA2we_QJ0%MIO`}Bq#{zOD~>m(%o;T zT}aiWr~^G7^+J|A$U^89*aoV~gQ303%w#gFLOgSJei8WqJ~tdjcyrahKZnJ3>LDJf zl=MAko`SQaRpm+@u4D}|J)Q-Fo0*w;G77piW5WEAn4nni?e}QRE6VfluhML>sF!A> z#DT7(epbzgyc_h2=Mh>>%c3WmOEWg-^F$ zZ~XvdQ{-pYxk%0U+~vpVmY$g@Iab7Kc;M3iSp4%Nt{qc|+nB%tKMk=P*OCl9PO7Pa z*xap+z|%O7a-OlAfm^0$Zrjp@{Lvt$Vr!8BKa)~ot`Z~GydI#mJK3MD2nBo z-ETuA?|$VKc}{wIXXnPsIuxItJv-`uROYm?}?j75XyBvKR;P=LzOI; zq1_rFb|6bzlRa?%wJ0(iGAC4-pLTA2v0@JSXq5~Wob_3Dwd0wHhSRdvR7?-ivuTxeXBUglkh%GdUkl(F*l8i;P?_PmY#E;Tf ztM0x=B=h8Py=-fkzOcG*_^#nim&SFA+@YPJV`)d8Lu1-^994(H6gOHmvxKv4+PT`J z^o;S!@y?HzSj1@evLJCT%R z1M)A5lkdYbOgnG3w9OxsVl-^62G~IZNCE*?e||1Kt^D<{W6;*)aG6gWIhq@}-bZ<) zU&py@Z}*Jh3rNn5?)H86_R#$=B!=6Mh_#~Xf^8CS!o`ahh2q7w6QS|!&h=H1>466y zZu>pucJf*5P0sX?+uJnme|$Do)_iB;-ud%qMvfHwU8kg2JqH7DIybK(PIq&6{(?#$ zjLdI8Qq!0WSPHe$MbAHG4b`0XMay-kp4u^xV}sucR)eLAnT|gbU5SR-{KnNm^vugzc^mTN2Qd2AawhVthtYKxP*EfH6S2)>#>Rn;) zz*y|dNLnKTS*r5x`MT(}@nS--BWh{C+<4QRJ^geu0ti8nA^Wz*i>()m*lVMj(cv-E zJjxPC8S|RC#Q;T2?qUjtAkQ@E)TT4+`KK+h51&O-5obl)6ya#Wa;^+3M%>I?j`uAz z7U|<%fvys#D)@RLZUvw-er|rz{u2Q&K5HO>NJh-z$JJAS;mfA^36RS7v*_x&gQnno zyvvrZ&h)CFCV~3|9BitWi81h5HXr!>?N#e@i~}b{+1Zo12lmNvd`-}$3|JZ<0~qk4 zKAnBZpb6-u6H!w8;C|b~D@*SlB{!xa^ZES@=+@c)7!fuRh7;vr(qS=*K^?YGnEctU z*!6HBZQkJnWIuxiq$M^OGSe{bn^ahu#nV4>=-v&2SxZ=eFSzxK^C8VtPFSS#^c6ZJ zKZg9%CKX$2&!KeXjXZ|?l}2~N3~>u*O`&~&f!31~M+-n}s1jZSeENZu#aWOvuhNz+ z4{J)%fwZJXO{{|K=x$X(di^%d@~A07fK9t|DM+^#0MZ&*s3La;7=UHWqDZ(&*S(0t zGJ5x%5wpn0+k!q&+l#SVg2uvhUadWgBdj8ORID`HMywP71?cr!vb%+YRdxuUe2Ya^5p8utNEe_T`Lj90@PHegD$q7vBwHvZUvQNfxBWv}d$oKWA z!SHXGoQzvvE(C;5c@~2ibB=PolFp<{MMa7+Lpk6kk!yRdND(Q$oa+S?T8Yyuy_eS*Xe%(0b80LGbX zGHsYEv79b$>6=!tqU*$^kT9C6(Iu>U`jQW%kub)?vDMx>Nr3D?CZ89@arqQ4jeQWq zCxI>v#1!BMGwdF6TQkKxv>>CKY~ZUC>t6Lh&ZBMPpJsJn3W_c3x+KL$H>s%s;Ca5x zuS*b8@)kM>NB=g(0!yNvqINFl1CKJjKEVC3vnBp)5j6P=*kO<;U$mnUXET!$-;qL# zY+CBK+LQg#L)1w{3K;iYQ~mF7U%d^%%hqAO?`?&N6@6ufP5Vk(Ra&Qo&Zb-CA439v zAZrF3T~|>ypRx}F$eK(ngQDXGKQAF%f5WLijg!3noGNjuBupIf84q= zdmEU`cSrTTT7yy*$Yss38O{rKiT3?oN{h3QT^2qiw?p`ZoHQ|daW41Dz^sxt634_X zmtpfJA;ays!+iDL?v1Yjx3lXjxE+V&!^l-@u~^xDRp=Uw_*7V4=u6<62WOtX3^>=( za)ONszboH&lBQ<)3KugbX2MC9F@PD|K#KRIM+4^7YImd0jNkr#elyW|7v$& zS>M(Q5aV(-Ri&krb|CO6d!oyyD1>GEtEqJwPENbxjTV&@8S~UNvpI&Dwud|i9FF&u z1hMvXIreToCNGOj)Hj?hJ}hZ{n~iIuvI6M;EKsjCrgS3S`_v14i0%n;W&Fm^U(G9@ z_;X%4N>1f}hQJA5OKERwGjaT3wyUM&Wc+M_`Ru|&l0C>BT4sTue^8gJEs~%hA^@m2 zJpg$?Y1oJS7g(DGOlIN|G_CMM_gp_^NL!G4wg4tb4g)hzaG>7$I< zHn{ralW|h}K-D7f$4^JeC@vEhnz9?q|J27r+;;EikG`jz_VL(7JK4|2GX;(o{Fol) zFdNMtNrf#;*6!XA^m}5sb#9d~$%syLy?#>b^{D4AFax`SWj|J2wJX|>;Uy+H1ZXJY ze9}!?x~bvixDt|ux3qjtzIl`J1e>P!J52P|i~Sd1AKpTl7L8BRc4<9%)Cpcif>GP6 ztH;5F*ageGK*IS}KsSRVi1iN;W22q92Q$Ix{1Y7S4j9S1B5KQj`60Qql$KoTMmZI9 z+%zs8)w;O3+t63Az!$LzaX5{L0RQnMM4ICApRsofchsiq10U;pwM&O|2G6IJzqaIB zSXp^Pp`d?*an=td&Q`x>4TIoUl<`fQEn`_;G7qeJ=L<6Il;7M&%F?25M}cJ`3SW&|%2EC+(M5 z)<(|(K|Y@VZ@+My+04HEQmiQ93W$0(m;Zjr=es{3T#iWOSoiB}&y&nHT)okxv9NF_P;5Lo(ZCD)e z*zH>FG6hQAse*E!%*=&;T^ik}l$vcDW>YIxim2DwlX~diw|;nTqlGqp3mv|nZj#n0 z?4NOK)e{SpG^8v?LIrQ$TxFX+w>(AyvS=Z8-P{F?k&^{gJ`B+Nv}iM#as-Qucw}gl zi19f^D0<3C39j8gK2wem*d-t6*Z)uBS4c_+(#c--oa=;x5uBbJ0df^BMOH3-o>$MG zU$1b-Ww$gSDUuF{fhiMcVruApRR@h_fdlJNnsIxZU&SsF(hlYB#f90YX~Z3Ml$B>< ztA&ZI%LxAUaZFOFr`Sj@A+FQ0hYByApoMcY%EjV6<(1vY@c_3YAD`O;6Z9$mljnN- zkVg8|ucKN|8g)RF84Z*M&^48^Wa3=sBM^L6Qc_mdUN$c;>-&wDy=g0W)NO1=#U&M- z3wgs>*E`RI87zc~_B}sfcha*MJaS&8xksh5o)3S@v$iPlf+X1W9jpG94FFezA7b52 zIH{~R$>1vv-(nyE#Y17r7U)Cay%xGazW@tBK->#Vx;fFpXcIuTIH@KqUrBa zxG=$XVsoFfv+K9w5cAg%KVb1YK@$_86)@Mzf!aWZq1Qcy3&`R*{#%aen=Sv0(;CyH zwygetknyop3hb)S4a6}W!x~3ViUDfzOL(P}9n=JT@VQ%UYSQ0w_e z*o{lFXUX&xzuU5M;@5+S4wbQO+r+6nS?xOBYgDG8JX6f;^uhl%+D5xx^FIqEEq^EQ z8}8&^jYNN2iBjU%!$_D{y7BKGfc?qNou9Z6KnLIvZGqZ(k6l01WBFVCkP#Y2N)4d1 zagxIiBE6Us8KAeqc)>Mw?X(E*3o@Ef>!bIt{Pq3S^q5dH)mic0 zi{$bht7fcbq&zIc?5IC^YSZaN_oLT8C0zQue~X;-rF8<2QbO0>Ew?!x_5AhPd-V^G zrT%R&s_{Id;@RYub3aTy7XNwm!xppeC_f$CdY7+s>qlDwK4;krE9{hpLt^D(G%14+9XF$YM$)Kf` z22m{kJCSGFqV`=WM&}(-@KAot4I$*T`ljYp@jQ>uJ{#Or_&%!ld=~=8#ht2Lx|pNM zvT%4}N}bfBp4Kv+ors3EU*dSN@eHWXS)Ny4=w}oTf(`SSby=!wHne+BK9b_Zt@L3J zF|~ZfioU2Y@27*C%nIMWy^%W|#X5&gW5eIEbzk~F1~i5Bz(3d*M;=D{;ge0NCETRBcgcK(Ft} zJ$SL!RMZ(yk8_>O2yiuqB;R=DvqaIUN0yJ*0u<8rg`tyeVecI$`&K=cNdp>W)>SR9 zs7TUxM35>tAI07GuIuMrHEEE}@7lJaoIK{?%^R*M5Lj7x$bMwV?0T%7R5UF!L!{5l zM6=X|z)G5lXAR?BUJM_UIj6@(Ntc(ssT0qm*R?>@wV!^Kh}PveuEy5tBk;jChg{8i zso)HS0j6eVL1~TjHKef8-nrYZJ#X5>)kA%w;Gy|f|^JRb=^Qj%dkbf=~cq2T%;jKbYNHtE;} z!8>s*2Ik>~2*wm5IOt)aX+ePNG5d0!C4kUgU*JNmfhbo?207b2#{3GAWSRApG`#T+ zp(Z`p-Amq~_-v}0WQC8MP#+mT@0VONvQW7g!7p-HZN4mi;mjU+tNrxhrew3k?1_<@ z*`c9G-N1Kv6&{_a0D69W!AKd{_ zwUdd(iD-NdH(qs8(R+XKM3dcm17C{Qq8))xQ^f%&8_vT0DuE?U2A6er(2LBo+JGb6 zG)zOw!@TFkFfQDA7o&GoPPv&+=MWzL6z&&@I=rWME>FKMx=~_!x|lMPf?um++sfV*3NHA9 zL3z6I732nvf$S$>@EG1Z8^OBlG6Ep}8X|FnK{BPt^~&rhb$*LCBS|pOrEnC2c!*$i z$E2ES7(hCpD_Z0Mqi5$5TSu-G^MS~5@K!eK*y!2ncz|++sG(LU`?rc;p{gBj=x6}2ER{dZvj7^{88gOWBk5dR3eFuHLe_=U z%wA00Fy*dvXd+_v-kEewGosG(d*%bYKWnIY&WEwa??x7>w6b22p=69Olc^G@ZnoOg zyJ&9m#7FJ8*aIp`O6x=&K5ecwJtsQ5JTT<2Um*9spkR#dcuo8gHC={c z$F;t`9EglaS9aNHNErJ^q7__>Tlrw=oZi3W#g{&8jb1O^+GOQD-X!+G3~jQ2NaGej3WuO^@3 z`tWeSzLv(i^#;#GRyS#v&ZZDUVD@GAT?mreF-0#1kHPIhG6@QXU2oWdjD_pz*B{Tn zo!jH&{Z;@DFFl-C_`QL;>UHIxQAC&q#CX+{8fs$F&+TroHmwsg$ls1&WDlsw%JPJV zuaKnR8=fI-rJ>x-KS7~SMb*z^xobP>Jm$kY&@JmEl6=h@?YBLjYi-uM&;$3xcJ|%2Sm! zv+#01`Q~)O9z@$N@s=``e`0_>jZJoXRJP*g>IgF;X}B?i+}tif5p6mqhLs@!V41VUJ9~lt*#2AM1mC;XYl0U3; zdAjBtp!(8kf770WaSD^~nDr}NcsE{H2QDmA0(_pqQ^kE7(II&y(GULj2Wk3_ zsIR)=iFOLNrlNS{fo}7dL36|`hOlE0M(FhG<2`R7+x4nuwxPj^AM22z>O$kLLr+6~ zsa|KR73|<~Mn*>7?c28#5iG%;BkR_!6IWE^0}D0D%tx{!PRRpUz6<~XL8y+w;pj5T z$^!j~sEt^Efi>^T;&E_rz*Mr2&ZoW53=<^#4RKUY>Z(pdkppzQ(Rwl>P10Wn5m&K! zPk@j=h>cyyG6R6O@uf>W+zhOI1|xy*KS5a;QcXS@`HJdR=V8dZ6JAKNkip#C?XR6O zWmR{V$uxnKDh=9G&h7}~KXCoiT?)QGuc|+E0A9L~)M<+tJ||?mE}NUb7eUQ^+{%BT z+w4*9Q7gmg40sCx0xq3;R~K@4TQPv1%5HG1=zF(vpFf^j9e13IHh6=B7NS56 zKE5w+J8%HLpT?Stz;6swn${f%weuR*BSR;oQC)AqbBfEz+&`caFWKqpM__)4Fm6ax z&m$uHi(CH|6?K=EUCgpPuMd5p#F#D6W^-0lrH)8EoYEOeDxS`wRcd-me4cXuI6P%k zxoXv#^7m2Fv~Jet^gbwk%u{JXvJ1aynrk;_iAs#ZPgaRge6=}#b~1S-R*|Vn#Wr28 z#CkEcJFvQII(w#rqRitrJT+4)qReF`W@PAylo5bd4Mz7vH6o9-$V^I4r|!TPL%4i< z9Rd2&=@z=$pIfm!QGZ_rG#ND>`tbN@+-CGLZ_H0g2r3*lph7RIya&xE&unS1E5$7`D`rNJ)gb4Krb2^HusFJ0vq zTJ%tMZ#v&#nT70Or94XUZ^SU^yl2a1S=(Ta6>C1pH-a_Qzqsf+*y~5Wx!KmWw~i9W z>gK_F_a&`ZQ#w9=ZIZzdu|zWpZz8MEN03l)KBXzQFHkhG$+jZkFqvd(l<90^-S&DH zJX}pZwCow@9*z;p#-0zy#X_K3043DC;^M03s^GU^eF2Jjd3oh*iqNSK8eq#d^VgAA zoVOF3b4NP|Yk_0i__c1Ynjy5T| zSuIH!o*HVgAGV34-?Q8ibzpfo7Z*J3O(BN|=F3AOD%5!h$|S2#v=N#aaf8YG=)BWWL{@?QRI;@>di1|PxEF*NOgLQ8NPviNP+I*ItmPvoNs_{> z?l;f57)h_?Lj#pt_%XL*@RoA{|1inu{%{TKTjgEpkVAk0XpC*k1<&Nzj;PvG1Jw=I*%B0r!xNsd{Zi+G z-oAZXGYhkp)G(F6mNn72l^SVV?P8LA@f&&sG-2!L+Q3yMaV;X+uQjkqUH7AAkRr?9sNC0>+J+S$HRK zDKWM{{=Oi;0T1BU>tf>TB1hZpLRW9z2XskFHmOL>xytrDybi0KOKCEf+7wAgdDA^~ z9%DPr3Vs>eLdAXgGgFatPL;`P9nd&0lHTQKoxRZ21gPaZ`st|9CWIRKVagX-_Z_wu zf&Bmf=-{v7S?IKID=TMaay2mrAN}ORA7(AegZfK8WBaA0p?SF^giD^OWkxCy9Ea{8 zjfV#2p;_~ZQvx+HEcN8;Qqie=vz{*RuM$+p9@G`b}S2YGaT?HiuI=2RaH<3lM4a(dQd+z{& z!s_BSF(IS0)3Nn9T>aj|&xYXQwCBRB?IdvDVut43(HaQ!S^QBj{y|FqPY#v@W6Z{j zsoILP(kla=N%o0JUO3!@y!)g%bX-z&@OE}iLq5UfvqMM8Wp8~~K!HKE1VuxGqq|;^1K`x|NR90=FOjs+|x1K2vS{0=*g2O@H!|{@7Ov3O#SpTY3Gccvtx_2@c7s5vDNXRqz9Vbt*@>kaSM$w zfzf=#0qR+^QVcI|XmaV&7ARx6o6-o--0S^1FLZBo*W`;T4f9N z)_pNnS&QkC`XCVhB5?UN6;k{)6;g1h`BZGtA*X~*U^mzdK-EVme~vm?ZCc@lfFZZ0 z(mgMq0^_nk{gSxCZT+(`mF>IiiZ7;?L)GK$8bBx_?N{;^_c_h2DH>PKJ!B?7^^PB2 z+sm(`Z?8Tu4{f4(TsrK5pw&vjoeBTL8pnJE=P&8I_WlYMJ`Z80On)1qvvIihOXg=0 zqlg+3vRSrx#Kef%Mp}xQ`2Wc!{8C%|7gf}fQjs5CX*6>XEHma+L63P_g{Fs~kKt(* zeaJ_s>O@CJ2SIu76=KfC)KH`gLLeq8>d8y4-7~m=`j5CPgPb6u_-K zXjBw}s^|V|#!ON=JHm+EZpo)XZ~cFyIR2mnz8!pf3P6ni2KLN1O8oW|zEL8o82+uf z5px?ZZAJ7i^dH;@VXpy6kyA0Qt&$uZ9C>kU6E{B+@!Q{s?pILQ?6-!$N_vl?=ghTp zyYEHB9AM4Ulk}(YjhGf3T>TeLv5OyQ_U(83t)h-UK8wT(3OYk8D=QnDQ5XUQ5k=xr z2LZd)c6L?+J^Gg&=dL-xog_KVFM`I|cO8TxZ+>DI`R0-A5ZzG(RYO9mrH z--dwP)VGboeWNHG?i*j=aNh(74);yce$yAA8ow#lZ{`7FB7HLtaNo=Wpo4#F^I%Y^ z4_vXesYlg*Mql6fO^<)mWg4p=?`B->Ew`5D*NXrkuTzUeSiBs8mAibMW*%JAm6s@8+9%5 z4DK7Bu(#rySYdC(Hv#!gK>n40Tpjh~Suxc`39^}QGCwlBq)*ZxN&CJ{$WLQlmBbQo zZ}us5JX{U0HP5ms7)DUrak1GpR&spGZn11l>=QB4D{vCg>f__3 zdRN>_QLk=NXQx3(1$mRyNv+1A*BgS$(kK9_c9pqbeU)E8K)X>&)39CYWUZ+rWj}V2 zVGN{tqiRi?q)x7W{(OM$W?*FG;el)n=U{$XT6+30prTZYDrhwOy&Hlo+hydj>I&S* zvG!~y2M4W+ii-2+S*zFkm0X5bR_5pCwoD;!0mm28>2!HT#TUKTW*R*dV@im1bxE1* zy-m~C*Z*iO<58%wSo?lql(T`sEIwd8=vVB^xNQw5gM5UtGb9U_m6nhSS zJ7t)Z-sEIZOQBcP32>A>vH1My(<56uJF5)c5ld(%=A+VlJ?};T^$W?#$xTwVDqYlG zzHGzv;kh|^iEY?|=WT<^617vBTo~pjyBQ09oPy5sd^puA=$Jl?bV(B6aJ>QDp9RRJ z4d&}RnTw0X%J@ZnGA-AT;LYF3UcC2Xc%6NIQBi7RVQHR^qVWf1g#VWNKjjL9*TwtlX=)}#@9#JKC!j6wS?h3mD5|T z;gu=ei2ccOHy|~^{YRbk;0*1Q^G*gx+eT=>ukHJm>M=WSEt4|jcoDkNP7O6CTSh$r zTIA>B`)DrpyutijN$+@0Ek?|52s-WAS)I041)a@6S*fJq&&*=e%vR3MBx$d1hRWQ_ zCd>2C(L4o4vT4^QIZgf24|BsmdSYR@pZDW6xfex6MNy}com^dWhclipQu&&l46F~B|E#mVZ++{mGfM@Aci#7jJFe@x??*prN#RQuNiQN0h)bd(k7N*ti}VP@ zpC8Ykg?CJEOZUN-KWt@$A0qNP$rs>^gJjmF>q;)~rZ`qy7`lOMm> zu{rbUVz|;D426Eu^kQNcMJl^*8uxtDyBVQ3uz8SLEEAhPC(b5zGkYj(1d+>*Zulk_lL>#FM<*X+&?(urtK=H9jc~nRt}=! zwNMOWM<7TX%8$;zPwFs;&@=jxJ%#A$Fc{g@)QCeM^eB_s5TVL=zUVO*%Cb?5=y=Ht zHD*N>TcfeD^s%auzR}UjHBGT>+RSv9S0*M;KBT9sT+g~CCoj+a!^P}0A^qxDm13BP z9CP%h;2#lfGvN&rB!`rLh*TM|XBln%Afrx8)BoC)A^kUI7+!WiP-LN3C#;m73knhv z62?fLsdxSJ)E}bZ$h9uJTY{1!6}Hh&f=FW)*b#c%{Lz0<7fr73J+Dl3Ki09SQoqH( zAlkNbY=u01@y{2x=;@uxNUUF(WC@Fe$EuDqDVbS3)6`V*sFR|qn?G#G%SN7RwBpJM z4#p!SCT^Qre_whJQRt&hvN%5<+PffUZEc<2`v+!J)P~mROD&8S37#)My7p%%B?0{@ z)|XxSh!*}7>5$6GN;w6E*g|C)q{(m=61_^9;5bg>{_|B#`f!ft#Et%Yyzj(V_TM*! zP`S2j2wfz2`6(HN`h4s5?T9f8vg+kOaIdCFi@d=UR$?U2VHYC)^Y%UJO?v4+ z3$J+pCFmlZe7+tRGvE6+E?=;>v!fRf(Bx0DlpaKXucYhmE0#|}FK4{5EI<^Nl_}P# zyXW7Oh)>=(bem7sKPOLl=H-LOG=Iy>y|J|>AZe=B$iHd4}<5}ry+=7f|$o5 z5Q2rv4pp~q-6FsfCcr&=&b%fh*Hz||R$1-GWtp}{zi>He>Es#By?CBohsE{gBp$9g z^zjuuU;INGG6Z?ByQPuqj-4J4A@*K2rv{POZx9GvpN);X+uPd=FK$Z zKMrk!UDT=2^Ex%_v#P^|_6N_K;}4EAQd5PlKaq>m7)qDOU$|FS(JQyCAI;Riwa}Y0 zi$mS8v9U32vz=8{rRweN{d>W#bu4a|?cT)|qM%r#Cs>T4b*}M-MUL!fq7OV7M7cfzF>n(v_> zBCB@DdX7#t*0}Cwm6w0-DZZPVn_Ib7D-i3So6FZM_gqI<*cV)EfgD^zr{Jx(Q?yP& zU#>t!d`_cljfU8!FPTruSe0X3u++^AweR>hZru1<#L8>TMLsZI<0=~^b=O?Ro)K&? zJ1tHA%$YMbT;%D4_}DQYF~uxdt`P<_ZUtzLX4Ror?uhn$_BLFsLZVC6n4{CSr$29( zWo6wG^N#tXC7mMO@=$Wfape}-u2AXrrx}||L*1gb6QmY*yF8hzsq{xYTAKKkYBItk ze0trz&^8ljdbpC)L*Qwo2rZ4MP1RWX$WLdjoBRi;(4bufZYi!pI}c_Uyb>d)mWO19 ztYk)SpGTW_*NhsM50{jPyrfVa{?J}UD9*vBcEh+a3&m$)ny$O6@}i=CY1?bNz6X@w zoadN$^i<|bOC54OwO?l1$Cp?gJvie}DfPTl*)D4Jcq+-hySX!hjWmdXH0Wl+bj2L= zK%sv0c9mIw7IHqtcTpmLDJwf~AkMPZnCGatSF%4sieI1RZpEH%2%mz4ghcvOgt0D1 z#_?WAmr2T*|vBPiQ6Ded%63nVSJtw?=@HwwoWb~2uOa99&*NYY)Sl3 zD?i$4x$Y^ioib>5xY+Nw47dyXVn@aCLeV&Y)F<^N}rV#K?{i=gy}^zMxdt3xbeldqAL zK7Lr4=(fRdELpSMR)g%4SG8 zxK=1kb#S1KLvSNAnOZY9*WBg_&9gSyPY4nX@Ky*7xD7wru3=4$h@xY=OpEmcndPA$ z{BE^;YH)FNHHwyyh-lG=>_|+t)U5yY-`CG_>mpA3HS0d5y$pXA7Z$=g3}hcXcn(Gi zrhDjd{QTMI*~)7;T2_rZcXBn{%Mv|M#z9m98qw;dk1Wbm*PYbhPS2?S`o=xS*hArX z_yjVPqnvbT(!!hP*I2?t=t*!F4FwLo$6c~T;a6q$n;m6F8`GjOl9vR}UiC>aVt4tn z_8Hc{+epr*8+kqefw(=o>VC%mj4(Z?TixueLVw@;)#1sOSd$eKi!eUYAV^g|UaK+R zOQk=BnQ7>&)QTeq*sEKY{T2_9bsA}DH&6{!tG!f5R!LxrTMbl4(NBVNp1Hd>B+ub$ zY58b>$j_I$H|`WM?zXA9xU?iIB^7cs=jo9N@5vS@@%A#DYWR9IIPG(Z%x>5?V{zPd zO_r794Xt;>-{`Fjfx*lS4-wdn{JLYbXh~VwGu%JO(;m^JK&r{5rSF@PhO zDS2JHF|=d}ON+6|PJY)Ee}8`hzejIG4y)e2`|v>|Bi^Qv(tYch`_ZNt{{4PNuTR7Q zjdm*~$llZt{&bjy5UhcJ^A(rv{vZ=0rEFEp8t+Lu>LAD=tF;Ha8wY6AXW}U1{SCt5 zT6bSqqyC z5><|63yyW!se*rd(PkDG%Yh4jZENez5I{4SkCuye3DoiT8vlXlX{qp(V`tVnMIypZ z8acSsYDbEl94>dOhNo?X+J+OaiLvoBnlONQeRBeJa^cfyKV3}XMIAtL6M^9&Z zi07d$;K_maq7m%cp9}n(r);?5D}TJ$B=A$BDnSTtI4pmMtUdxj$!;n4w!D(k2Z7@X zjiiH7L&(?c=EHL6MaAs*j`{WnZr*`57ik&5(|iRE3or{2XHoe~ig*1Lc)rJ8!?A*) zVKk+yS;A$%a&kP^blEeZ+MIC`^74_DyW_|uRV1pkDe!7;z9;(D_Rfy+`s5~nx9|mm zKd23t<32T_0zYu{U+;sx6s^6$&}yn^8}MX6u5H1lf-vYwWKvR6pT9-biXtGEg9G(a zL#gIx=@+O~AEo|n;c&9&uk`ZkAjr9+dXsw0%g|4W)vRi>vW3aH?%l%`g5X)=u+pGX zx_ozNWfXC?r(?zjhA@2k%ojXgA!2pAlu?T^odT!y-qSvj!c^$Eix)TSkI}mrgj(ge z2Fbi_d(?KR#A@PH5ZS$*WT%W?h7ez>>C*}jvBs<#JQtpyJ7SFMNdNo#lX-7q4LN7$ z3b^A%oElWCl!ct3VFsYly9vx*xJ4r?sNump8D-^6kF8XymIb>OgCYi&F6_dn+xPd! zNdAqmc>-HLVqTM;k#6uRHcpkpcya=VfXdk};ppf~FPiy&4?cTboT|Jm+e68+k+kt~ zjkXK5#NMw3EdrjT+VCWZi=DnEbC2lG+lIC%tYYx ziHYe5sh(fF}r2cQ;s26H>V=gu7tUK1RRF$8*gm_7P+3)KV!^hD)U}|xk9I;BCHf)cVhx^~f zuw}F@*zrW5eyW%M6ki#wV9E?SO`@VxK$1##63gF%rHF<%%O)QmcIAJ_TP>^HpH;;R z{5osLvo(RAl$$0d(0pE6kQA&*-DCf5#n|c}8F_Y9W2iw4)znj#HU_B2^ zI9{@D#sP@w)@PgvkLV78DLME%&(CszLIGE0$N*;AHX}pd*FgLjfnHo*cH524z`93$ zR%*?W0=PHf?Wm=2G5%CRE#zxzV3GVuYxOPWh@J+Evh3>W!`If#(E*uE&)In-K(Ja9?VNz|5~%T#*PWp$reUPa~ISAQFB zY@{m)I`3qMse9U6b z{`?Q>gA8YbD1L-UE+j}n>g2`6#rK2j>j9mE_Jha|3%xh9lj~9J-RKM64^c}EOLk+9 zb^YPq21iJdS4!Ai2TJd}EP z_#%~A^3D78sb-U&FBc%RErz(Ld#Y`Qrc1=RC38JnW0HPDo76=Iz;9>A0f1iWIJH+w zCXh-)4$gocgTReWQQ`QqbhFSKl*_t7FAVs%>K~Al0WEbH*}ihE+{mKd=xen@mYD4 zVGDLAa}fP!4qEc`1TxfrNh>Q4B?rdud2G%lW!=#gUc%7PIYu5a+qrhm{?&>(%|1;k zjSMk?gVvW%BuBdpNPMizn=lLvf?&hMn~|09wvx4^h6%39aYV~SfN+q;yNw>fHvpK^ z($Zj*ZFVNur{m(l)9+r#ZY!j5n%+!=QwX@HD8LcGJuSxf9anokJiE@8aMp{ldG0Pk z57><&J1L*^$d!ObP?Y3lWa6V%kjKperfcJpGsM%TdJ-id2pPc_T4P8`5RFSr6$4P< zaA3M2>Q1ZLgB)7V-_bVe6ujgi3wlBj!iL6W?He-VvFZgd*1F=5@xJm`>JD786hsY~ zafwX^9y2R-Kb|SMfDoKrufRpb%vgP&v8lj6{4lg&*E++aS2+E~#1ff0Fi`4A zOv_m&(o=^+B&?7PeiTVKb2@MC^%;NctpD?m!Vp`+e}2M#*TM%%&wst=^+5PJ&40av zAhG+ue39hsPkelQKn0$$lgh&u0F2Ql$!x>J46CQ!ps3ZNtZl-o1=eqBy=7`$kB3QA z#?mtXVM-|Ay32mACfB*~Yqw?yCaWS65fZaE*}_1>hP0 zQXqi9A2ZGotu3sV-MvK=zyRdovL6Pk13L!U0_b$qSmOAnIix3LR8kU4*+_>o$;orP zJj{``>bgyV7$oLJu1DfCxn7PD?hcF~u2Y5xKYsjJxH^PW>$wgqi5&G`p~$sp$QF-} zFdq*s*-5&x@5aB6K8hc^`Rj%$L8l%g1S`*+`s2*YPuB;Cc2tw!iqIAtc2Rie=EFFhvTngN>Mk6vR3WCh9;Dgae=@}TpkZXf*3jnNmDzl@<0zjB@b0sK44C}d5 zu(udwy20I+x# z?f-cQBId{DKHjJ>cngmeRR;u>YoZu~044?+Wx6ef1F_;JI1Ia)4;A*y#6gH%Xr-f) zI&c^s9>xR$H8nG1zBS_WfA)=xn4);wS#ei}`^}8Wn4@L8=TjOMsQAbAjY&-#L;%0V zy%z66jafv4R438AG={$F_qGcxtHt78lB~0H%*N)XM6;v4Jp;)yCxzuUcZrL5wd+v5 z%!9msb0zoS;HZ9g3pBUn_7eT}fz@;iso1(g$cUNi+DBCU&0e3~;Oj*$qu7ZZnIG(| zkg^$wLjpnw!YX|2>WT(4+X+b~327$8JqvikR^+sW7lktCI6}-m$-VaB6DRnn;8VbF z#>2(Nr<HCeWI*#74tk?L;fTw%Q|!^uvf-} z>cz2$pAA7eCrT;;@p5In$X3eJ2HIry+vI| zvLFs{_pUFzWzbN>OTbT{D&c4piVBx`DFqDHJKF$E~>%S)~Fm_L^9 zvR})JgCP%A!6dN(>O>Rvdd30bDh!38^}_F~5iP~l)x1y!7@At=>h;GAQSdSZb;t-a z4iF^qe6Qc&#tt0&iI`a{E|4Mh=bErFoYwHzFH(NpDSngnpBql+pm)3DeYC-g^?yGe z;tKr9NmRV*gGnhpqoI6|cpO$o^?CTo@iN#?bXK^9mmJVJQ0v=QaN#HFY_rkwXO3gr zRo9zvBUcdH+n(JUGm3A6lQ>Kjo^GBDtNy3$hA{ROB^gd;^6NT;!#8%f1g&-prnU zfAItg6u#&+MsLx^jr^LQU^m0774(AkB^Z&d53z;W2c@7y&glvQS$0;!bR2`LT7azV;jF(*Y!t1WD~8w z&@uvX_UbQmrKMDHykLOdJ1V=Ia26q|p7P-cr4u(?_1R_KmCk^N;`d|Q8AM0QEW7L| zPu?(I-!fg(<2i#^+niKYzqs{fdiSU62}(s!M}IFhA2A5L%67BY8FP7kXt8cH9))fD zox&lrs9_SHu%7B)_XR5xFFK5vZfbhc59)xwdZC_Qx@3aOH(m9xR|>U%e?tYo=5%;M zE6V0S7AreDKp1g&%Vs1u9lI(*o%7wPOoSZ&0f0iSJ1Zl(#Pp@5r6wJ*9O*j5Oe%KL z&nHuvYET=S6ebHnR0L&tC5lTbuG>{iW0m$6F`Ze=^N#MAwEpN_x~+YMn*S5ot7~%X zq-+#P;$+#}`)=Nld<)-To&29sBVKmcJfHL^DJfAY)Dx|116J1e?VHs%-H?*4#dmbW zXVnbFEY*nly3-G&@|Vj*)_cUFO+XP$w^geySJ>XZbdx3`Ac@D`pOow#6rIw8`r{RT zh4Ltyllj#Dz}fZgA0m{NqJJ;_0R)5;@eKB5=W0sO3n9W167I`mHR6*odBsQBJ=c+t z2m;}+f347$%409N?*8=)xlXl0XSzo7Ul>x6Th-LiCFHXZyUBDhXFa>n%XdP@w9cED z59LzaceoWM0(HS^VW|(od?}PArXdg~g1HUeXPG|11`v*uM^V$=P){~$JT_lZFtt=0 zmyRZP9j9a+pj?!JDc2!~b77MfM1I9|5&{Tw5|-xjii*^|nLo}0s|u#LU*c$)aZ{Wm zzxuFRJmZ&zPsbM%(C4kaexG(y=WMN&FxEhY%D3rjFHBz#$1{C`GZ%ac(rfs zpqBEZo2NvbB}r<--36dpkZ*Yu?c(Ah6MyZjEbI5&L5-1|so*5$3^t}{v6JxRrF~uE zjQ>P&G3H0F37UA;Etkkkk03Lh^a3c#T|qMwas~4;&A>C#Iy)t0mzWtCdd6$i({%y@ z0wnSW=QcqkjP;MCtwUxA)~i)V#)t4ZRHsWNIkZf9g66RW!=frcPq#)e5z}+-e(8^9 zWv~6&k}-i1+60dGt24LLH@Fk-S>|PBWr^n>7?}?ji<%DP+#x(jSaYM(cmASthl4$b zgCZ$w%8tIaR3^sOeC1s+QSglekDoguRcA}M))Q)6ODYPw<#L**3X08duaAFz=v`SQ z(MUu@lr^GfRywUFE1POP)nt57T4ule$~yg5bVgX|8CMjN1(O*YV|Tt{wL?%2>Fk_; zG(MbR^*MCJqF0pA8TBdWvIL6*Rq0rWr&|O@Ns}Gn+8tHl+me2n`5lXtESVipTMGcV zA~KakWAErza$2wxTi%$vowuh`cgFu<%y}*WIH@l$<@rC0?G|KYM?&Afy@u{u`U5?i zo9ysPC;UBWh)@!R=7)SqCYi*Vyr&Uh+v&0QQxs}x0pS||f6x>Tu)4gQ2Ght+{ z@OFN+3N11ln2xM{;Q~hYI zd7Q=mP?z`&kH?`CfagZJoc_HCDIU>dr=6h(Astci0xqAESl=otdB4? z=#0;N_f9B4wz9H4h=xuy>{W`l=TS6g$#UfQm|}RbYyMV*dQVd9t!<|jCFcZTO0-S+ ze*HQAWaT1*?W*>r?O2VjL_XJIoyKSY|Cu<ik-INvXN3Z;+yGaSLLLs3VGx=UqrCbAAtm*6Sw*H1>^H(3hAqY@!O~;}gZbM7jl-tKcS?{Ravye00cY3!wCL>jp z)RSXR3D?~bNs1$@+EPHT$)n1uQ0leYn*#m2Aq+hs2GQw!WfRntAxrm>6$;0w!8%N? z;NUQiY|vKZB3Ce7vKVt1$(L7G&n@cW7sET3PmCM9s`UZc%tsmG;n2pki08f4Co7c+ zMGNK(*`s$f2_D17V0<=J`zaQs^Q)_#0>5@gBp7W(>S$-Tb+87t&>ym4BZuk!qYmnv zpB&jUF%dyfa=$k?l;=8H3cpg5-e7**e9XA*g0JJ8s_;0zBZvKM?e{klv<)GQ1M}{N z+%sdxQ{u9%j@nE*eviX)_yK4*|3(=8QbF@TW{ta4y6ofN^S%xKPg2p$Y`8)WRqEav z`G@>TfsY=7ItJgn@l!o6RK5u;onY~I1q313`H}a<U*ijl-dhBOcGU zlWPhWbomd-$<(>~I$BR&>>6N4fzbN+-u~@psZJgRsu)hm+sN}q?!u4A?q3gof3?w~ zgTZ#mU(`cP_5mge)>~Pt6;wRinSE0sn}~B(A#zPxzg8&a`WHejvsjJxqo>}j5p)Yt zsvdbtjOkDlP`CQzj6$!i^{YFMWhUJB%=SbtF%c3>gTBnzn@J<=be6=tYr@J1%0ZxL zfV}PR;XDGGfllS&MjMCCv&dTMvJTP1s1DsR039zr%`3 zgzY0LJ$?VF-fLvo@DeIXOg`1Wt4X?dPMtDCB8gP&Sz|ZPcAqSik33tZfTg7m7T7&Z zvEX~yp3y{@RUcOKSQJz!D5KpWT(aYVikEm(rQEY;9^Yq<_mhr?);3v0VQbS%t)X83 zCVFllJKv(Ok@(mbgdboWwOeWVMi5uR%_@&jrt;68X`8sWR6{40y(5(e>CA4S4X;a$ z1}Hua%=ZpFq@_byKy-N|aD5H<3*YuuuZg8;FIyLH>Xo^Uhz5&6iF?SL3ftKaSy_u8 zM;;gu5V`z&>Ke)CF&ptHfH2HEKiZQa`a`MWV zWsa+Is;*T~FU5};J}YDCS-@~&m0q91Hts711qDGliH)#Iul2G-0?&4Gb0y7%^jFv@ zDw;&1`CfN*FOB~|ylNOVd5)6BVZ?r9^ez*n{T{;;YrRXCW-rFJTaB2zERrP+C=Pfk z?ONO~*D_wG4^il3ifE3hNu@LRe6Ma_!hJIiNnX5-agV%JJig;YoUHtOP(Y$@N+sq% zdCH-`Pp)mnz{Q+gOMqU(wwb55q;PBh?w5~| zJONRN76t|uX)|;4{#XuE@kVBq;`!uLjl!xf+cR_b`+CR(=q=Pu^9M?H79CY9?UzRH zCdjLQTSI~H1O<4BxkZ}_f}nKf@fC;6!onUqUd+-|BLR1~pbwv!tomh^u;gv<`aW?@ z;OPV)Rhs#W(ciiSvllZ zm5Zr<`I(t_5_}`So3&O{R;sw{qRX=UO&w1*y-6>>w@ki~YyHyo_KrGG z)VN>_cMe7Whf?l${|pC6*Wv*pL4I|i=tQkmy6p4EP-JZGiocc-k%>InIM=N2mo6}s3)>uuK!`jqCZtzc_f)OwA0~^w z*LR~ivFu!6iEkxX#^73+gJ~n}rtIgFr2!H(V`H-M#&5WHJOvi%Hc@~f&kb@Ps58#r zX=cr3JGm_Mp|WyvdF}P^C@gb_Jbmkp;+xFkoJV7yETD_w%!{!_JcrvD@=~JRW>MCv zszhJcMORlR?Opqjn>;WU8(R>F_cBpL^gg{kztkBK!m2T5&oIp+8UysN@v!njg+b8s zv-NeR-yHqdZv;*BX3qPwJsow)NgISdO3cg0f9`1i1@23#kzbC12n}?m>u9yR$a>BE zjDNO5ZVz|}N`2tJ@RD%kiNMloVrB-AH6io+4Y4Sr#lB32u7B7+b#D*Pi^&6=zwze^ zFYxyR@-VQed2CSysO5gvXpcS=>Y^sqnKRx!E9!bBr=gL4cz8&A7mMj>p?hQdqrg|! zy2k-T6!g-gAGKd%8jfUFW;^0CDs1N{H})ta=7tY$Oj-|7;PtMrD~aP}?6;i*;aL)A zJ)9um$&6jh@q{+#PD;yKblby!oS=`&(&h@0sm+jwGN+pEQ*@W(cKO+o+{o5@)~e_R9wJDBO3c`c_997S>D@e z#jugY1$L~li1t8Le=n%q9#F-!k*2Y@i}t2VMq-MavA^$+5N%zA z`-Apj-w`}y{(SiWf(pZBzxlLi&4D(Sx}0I#&M@drIL_0^ zHSWz=dPx^g4TV%Fi$Km6&%j7}*q4^d0P(Lju{riW?N*>t)u_(swzD!wsXE)?| zf|ZNjmHH$y+9}atH?fy1&%KF|!qluPUp~n7oHzset0|Dl!Vxo<+=6G&B5OO_jwzq4 zH&a9}*!}h_1Y>LEDbS}Ca-AKEUtd>-4g_dXg>Z*yDFnKyK3rlN?Z%%3O?Rv$eJx?v zOY~aPcsAS5K)*IR&k|Xz@~pR_QjPg>YG$D0Ez+PE&|D;#w^FLB#eo+^m13VWq&3|V zM#^pTo_66n)&A>5*H!MCO6ydREUK?a^@-9YyzlAh5zqL?O+(-0+?F2AFD+GoDK9uG zgEy0slH$2AhKU%h4A(7YYocR2`F7RN^TGnski}@BZAuI@fLvg@`Sa;<7JUF!&_oOx zE(tFIVfCecVfMFJ%YskyA$^-~F@- zYy`j<0d6`BqL>D{t)O5bW4^+zQs+?vT4){$b&kVfnMAY)1jG`j^?j%Y70gh>qV>f6g;rm(t617uScSF?W$MbU>@D3Q{!q?k%@5Gq* zf#Z+-QegG^oaYj=ZHZYp2~CTJWD7+uSCm4G*&Jy-}-#fm~O$ zDhH61^9*uTcgroxCwQRD82RQ+3rI)=7xj5gGK^l)kU09Eg&{Gq(fRXn1D6x6-%ydE zF|;YW%%`}B_I&ZX!r{7;bGogf0DElU<`6A znt5q{o@;&$VoVUZaw?p6P-vXG00m%xxsScQ`9*smED)UklOTj{YcmO%6?WYe_()ik z$M3tHd}SrqH-G*P#qfxiybhUvLyWnfP|@u%bh1UOJ5-S4Rndffq%~gX(Z{rB9;}p= z*e@yMsySyLir2hh`(4QxhelD-px9u?D)p?K9Pzu@8Zs9TR_1L_YEa^vTi?G3*jSHe z{G{~Byyxq{Z{>ysaXNHIp17N($oE*QMf$D%2%wD8X-RoUOaQICeFsFc-h# zBb7}GKDn3>3qP6dJA5HF`0}-B_eSleelzF1kb~KEVvXJgdx7_r`22O6P`K;i4CO1# z6SV&H;*5!jN#W>fI~y@Ja>y&H=VIEh^WA2|ph4xDDD=X1cX@hbLlfFNki(up+Z*+n znCr5OOULhK+VWW`>YS`|7njJyn}5Mbx)`h{ktd{yMK8=mYum`a)rKzIu~5E_iKap&#mwx;z@o z=OWhOoC3Mn?6-4lumL|hZB6$#^wXzqEF`)fC5v#mqTm3-HDXkKfgUFv%8GXDlbPh! z#Or;%iG$0?{q_`mgGpaas={>+KJr~59@IyzPgi64bz{@asa^HdpX*=_%n-5UMK(`8 zQy;S|v0J#ikLHKYX+i1_Kp#wJzN$j+V+{6a&#xxiUls|fI@=k4mogFSiO+2IlYX}S z0|R-|A5?v=5fZroC;n92`QNttUQ`l}Q_Vrqd2^q!Ow5858OabVbq@94SCOc3D>LU!+hxN&vEgfuVZJ*aWSnJo)Jof&{v+An2k_cl00^)9!?$Jtk3r+2!LSx)T?9K#Ei4AG6-6lDJjE71kBKgN+wG3+ zz72M)P-o}>cBb_K4*2!#-WEM)pabQN)~lsw`~liv!w=0cKyr<-@@I2Nj)}AjdB`J$ z=8m^15bxVo9I`=S;!k4fW%ws0U^jzR4|n8LqwnHU2@uG}DQkO2M+`RJ9rLWCh4Wgb zZBb095#11Imob7!f!b;$HssOAe)6Axd;+yqlbsebGobSjN*E?+)b@r8Z!D*KCGA3q zL>$55LU%m3EtoAk05I_k9Lxtv(ifMg#NYLQC1}n#?M`9>9Uxng$BvJ|N`2m+lKKPA z^FP&3i_~Er*8brck3k>3Xpb=ep*DK6Vy@VD>WOGi zYexJ#XS&1>0H$ya{{d6jf!2R}1OE1J=G4751t}^6#ZPEpwohG2!nS;PK;1jJOV<{D);j*s}pgZ+=7a7=SyrTo7UBvkF(Y9GQO zNae4Yx*_|f7s98lcnCvc)`UtM4Rs|U_%oM@tvih#a*_w<_;)qM&kOB*IY4{#0?#`C zXJH;DALQ($ynp{i#tlwT0R36mgAM=yO=2V8s~q#w_RL&0Y$uf9*w=Qy`SNa+6oa5MMdj;H731yLDM>pLeUUatoQASdRklzf$2{_Kr|PcX`) zUMbE}cj&*c!U)~FD3s5eMk&b9K|yg6&2+s@CXyh;KEu?#d)Hy@9g*%K3r;nz5&W0^ z-UhSWzFoBS@++9ByXp2DZ%|t*=Ihr7N_99 zOu`(W8#@Q=qswiU4HMNj(qF{KzH!yAlY0*1G-zhmpP$Y#{HNY7H2#rUnpZ`jcD+eF z18Y{8e|{bhRUOQ8t!+r|4F<9oYB1fu$o$>;xrG1VQ(VFe*FF)D(^**EARTTP`pBLa z)}R`H^Ub+Lp+Vomu_E)zWo1egnJXVuzf98pNvXi7nwclHNPbFRXo^WPi~62BE7#3} zl3sD0b2Z=DNEi06-w4oAt}x_H9qgJTm&~fD8*JYtMt3XK+96>etSn5GXBws47iI5o zb6>4HsH$@vXzw4awpO_R&rIuOisp$3G&_I%(AwJCqW$XN=qT*!dZ3)|xl`mx>h6wS z-v-eyibYf7Q`A2*{P>Zn;!I;oO3M7oio}~SI2@o%Oh89RcRZ8Ca>(Lm#!0sCcFlTF z{N@$!ha8(F&*%f`I-}WSO){dQW{u3vnKJ*Apfy0dk1a&R=ZMszhh)^3iG zkdXx(?+Z``!wI93TO82Bp>+pUBydm!jy=1LI2QN?1Y%jMq247%-qSmB#N$yqv` z!7E+O&(-+PN={#=(LwuHI_avakCr+(7Z0Rm_nhc#$pm5!5AJ9f{JlPNICxx1ceLqw z#Bzs|ljwLA=}yDHohjfSd0SDg7_)f+z2CllQ}#4oO#|R@SO3BK^C?~HgX;78GkQ5TO)~G#PLpoj zY@O2k{D1!qWqRfXhRbwPiGfK+c3jrAX=&Uls;Xj(*bavJ!@_AIf_vt}1ituG{299> zSFidF49u*z)m2{u#foaO!?N}!=2T20p<;E44j-(g(jm|N`>_13!=_NF=|&<2W=hb_ z&6Dc*`i5>@Q@V{#gF-{)yG;47^KeMJ%4^L>c1TE^c&(fB@;c|2mZU-%S&-wk%xBNx z-vAe!!i`+J^0)Q;H^JiKV%pBN;qCps(YaO0cx1uU!1s#HsT=m#Vw0AKvJH-Zg_(~yNyTCnbd<%e<_c|o#LdJ^Af`bd`vPk2LGqDEL)$0&zH z;yPXGY)n%7TZxePK$zR!*AQRbW|cZ=jGB!=v|j?3`w@KK<31d;EW0wdySj3FO4dQ1 zTYzj<7x<=^_lzL3=0-cxK&m;oL_YHbApI<4#E4gdgyg(VtUU{CRQYb`?ZN164`gfN zE$3OmRXgRRlWr~P3q%CjT6T8q{*8WD**G{BjLgj9OE8U7?TJfyRm|YLx;8e2I&03A zN)@{&Rk^p9hzM>kKR>tAoXEHPWp8gUumZ{$-z&FgzgO>9vgHBxZJERI6JU#IeUu{I z;bu;7ku7OX&9GCTjtLy=${eIs!Yl75Co9{TFb z0{jXaCu&^18m!%e)YQ}h!!ABd0JO8K=BJ_2a48CuTlDs%)GT44-Q)!JtOf9qXeB-#TK|vf45e_pdSQ z?jPJ>C{dFTc)Yw#cUQ-{M@H_il&D!OvYgJ<3}bMAVEuSD9(Cg9@i;jCgmR3MFmvos zpeQB~0w;7E!N&r`{4?bq$;!&+s8?~8T6${6^Vp;Gsm?%Yx_)w}=kb@KikY6Md2U{E z(Y1~-mFQqqW^?Wg3)TovI42q$L6;;I&q5?tMaGBSe4L~+jki$4gSC`!B5|L=@!9hH zUfSNG;#ypr3TB52B;q(5CmMXkVk-y? z_2|OFS_`t2k;1WdKYU)Tmum@)9T>tR5k_WWZXPt#7A*`#*1rD!##j#GFaCtNzx-r5 zJy>jVCA#LO1K+wEdCQFMk4La+1Nk2U?v?g8nwv%oo2t9ynVwjb5(Zy*d8d~!Q`{fS zr#FR@m#?~BC+a9hZWevII_tat9SexPOsvID%oa0>FiI-p zqn9sVcK7y1(2tCbQLL=2$ZFh=N%|>bgdMlmfUq1-J(sCgy@uCK2fSy&`4@nAkD zC?q5VyBV$F@h-Z!yv< zNbBnAnvJ>GV*Cg!)}?6~wH@6&kb6&9cPhqn9}`r1mH!PQWNZ1ul3r7UOuw6`(hTwO zt>d0L2v)b%b<3GZ|Nb$HU%_RR4ZGsf*C1AyZO$&~H29e6z^h4(C!sVRYEOdwTa*-j zDFr(0LGgjHh8}lyIr(hv28R$%-4>t>rZA1}QV~AcH0z>dr89GtPUVi4nkUIyGq1)$ zmv_4_tRnBuC8Y1Zwy`^;IW3-ZHv8d*N1U!a4mr6`u{sVy>w=11mpSTaw~h+_y8}-F zEHu%QbfwmA)HrtwuapLufWI#)rSK6rH%sUO?yMN-#Hb^&ZU^+C-E%( z)6;sq=&gcqgS#f++!p2UrIJQSx-hhSs1&!xe5 zYq~~I8k+0tr~K}(4sE8D?+gd|ZKjb@QU+(|k4yK6yB<`Mkn_IbLiYDx1u%ReoaOt! zGo{ik@J{yu&C0eJ8`)ZoIvQEji%I`>?(LJ*v*!%3#QMLJWTjI4YmBo2SgqR&h;G97 zVC7mF)sL>RDrMPYW4Q3 zkbOkN9Q$`pBDgg7(QL|}P-z3v&3AIhFezaN1-*I1a0GfTRhqutchSjyso3pkq$kIDhKj<@@tiH{hUF{e;jHAnlbMXS+;gJ1IK5<^Z`xZ%dP2tWFQBD7y`Dy=LxU)eCq z73;E>z|L0dZxuTne@mwZG94Qmn>1k>cQ_|$UEZjE|_Sze-O@UL>?-gGXvJu6WRJb?p4K`+ly z1+0u9@9FOR_|&X}Mzy7;-*gX_xQ;>{-GcU#k;`)@sb9dl7Mvia18$_m2+7!!7d5X7 zrVgWx7s$rLqkJ0AVwm11`70puT6^f|(5%+%9({o^!2gZ}B?-Sx5T|aSC-qfFoWt7q z;<%DB+a9I7YV5c2dF5;<^7(4`biy@1lcb5re3UoI)qUehw@jRknRehrccD;Lku}rC zE#&CvDC!J@(6Yw3?F=BSz+6?!V2q>6W*F2i{rD%?>Q3eSawE(h>;rpx73(|;+aSAtCLq0FOL5WuEEBJ8rOrbZ-?b)4$a<%B>es@;zRnD+P`#LA}UAe zoEP2Q&q7{cD;SvTv_v7aYUA^M6xdm=plfPwHf#r7vk3x!^K8dpf;AInhc!hGV`9W_ zUi3DZHBFU%yU#nvV|%o34*w%n5|<}b=$&R`)cR3x*rpDE4$QQ-H?K8-K6yRzX(ane zNPq|7B%EoyNcyknlsdKj_uoL#IW~(Z(l8r}S&d6%dE8Ty{%}Sh1R~fKPYXpw!>#RY zMW%njd1!r!o*Xv4ce4}Z&t09Rfn9}M$ZNIuk!!M@?QVzs$f; z3X_!{YaR>_POVl62+T11Q&7|qXrdS0ZI!WVAodwq%zT4qh>BKM&DZNsdr~Y7pqHHb zvo)?F_nMB$pyFdVTZy5lCoj2#`}7LWOifK0HEVe>OcUC52XZQ?6>^LcmN3BX58^g!B?3XOb5OmwY6^#lw37BEvf~u*BlB zGAZX3Jzy>WTU?fabi`6Oga!uXiKWS`AJiSUVpb2xc|{&N0NZOK+XE_Nb(yr9NtPj+%g0Htx7{j4hozgR&PWIB3+teE_uhuXXV$*&q>v3GpR z1_1GYL#JQA$a43otQ5~tDY<2hfw57f|1bCnL*~2|=a-iQS65e!^S8IQ9(j5mzZu-2 zq6%>2dy}xv7XlCisN~dmSv5^1vk~tU3d*XwT0hpmQ2dG;4+^W@erG|=-^d9=c4ykT zgk}!F)PYm}1F8D?8!!$$UgPe!iCOMGCFz{xrluw=Au5_nlbW?jucWO7LCcYOq?C02@>?;uwj=#KBUV!fmA07r{Z~i~jy$L*&YyUs)IX$O- zr#d;>v@z#sp(08lYr8^dBN8HX5LvR0;hdhbrxGPwk|f!)FQaTBGfDPkvQE~)U<_mC z_qp$Tbm%$t^gQSLeEXw$30BifezVcy!XYX+@XDFv1 z4Bjq?JGW0n#QFxgio=t^J7;~C_cR2h5lCt}prUA*z^ZYx;)>czem% zU-}uUcU2xhK-%~MQdDW|J8fh_?~qwt((Ahg53_{q)Ui;^qvSGJ>O}o~paIK1LFfVn zlKRtinFR_adsDzO+L1eOJ$F0%!=h^^L|1o0rWqaQg9i_cYM%I?QAG4yUf#VOLJ?JB z_c9KV+uM)27>v~A*tgim88l#8kYojS2sUzZl7X3i(z4g4G1X*bk^3-CNT{QgRVAcl_TPg>UtTL zI=lDmISlK4=n(RcL&d!{vC#mcts1I<*afW#pAfJRUP_H0v)BW|*SM`=#69@LB^m|h~_wB$f5FX{@OCcOSpO=!b z!|GhFyl($HyYm>+eR{s$THT!X@xVirtJ)swrdW_@v**ttf^Qc7br^1`|Tu zMP~PL@Z#)JWZFEg|5`03a%5HT%FxizM+t*@G7bYyELg&kAxFvvXdP!maWlB-<;BRO zW*Px#tRAT-z{dxk3dqyx>Sb^R>?iq_XvOy>o4{WefB>aNAM@DL&CfhPKiz~}bER*| z8ZgRUUMVRlUS0srIgg}!d8J#p?*t~znOZhnMsw?DG10t$`omHLgnXiNNIn!~7~t%i zo;Y?cXuQ*h4uvVY$s*Ip>EO&rLI=fa2*|6ds?L}L7{U{@XZLRVI)e_^IE47Aqly18 zdA5apbO*$Lv0VrnxyZA$qf%+z&D=zD->M|@`x7%zCD%p2UVL6ML~Z5b+Bfw_q9h_@ zzM`Jr;N|BzBE$6Hmft&|iAKk8d(md{<(A31$v0+-0yyStWkfI#`M|L+7^*yh{0btr zi2g`0G=|aM7l4LMFn)!>^oWRvk2G53XcN2BcqGv?RkDCOl46wCA7$Ax9jtw*{(FBj zJqj0t$}+|r7~!MA_vRq=e`4h@*$)XYn55`R1iEa= zM-CkVpA>Rf7J!t>Nm=179@hw-MnEI(Z2NEG~$ z*WIp^A&}csI(fF}c*=z{ZqLWEkSzx;@-9)4;GY4ee{y_%Cp0ef`%FoXo<$|vuPu7x z&fQvmPi_aEpuf>Dee*PwkFu&^Rl>6|r^PYNa zbV|xENZfZ7OqGYq-t%Dq-y?VCDU?SXJ_Na>wGnSlgWKj)(&5(#I?svh+9q%=BX7oU za|xEQ8KKVeM-+vOpinSa92DQ`l=1ETMx2q9JJ|eq#1#E*^u7Phn7f(gCbm2*({Rr7OIP0q__aJ(Y!jm1=ND$zWn%DVz>6(1EbNJEm^+Jv=Q^J3L zA*NauZe6fRwthFsMG5`5p_LAr0IYC0RknF#qEdfFZiJKKvaZpcSA=kUeEr(*OV&5{ zb!4PhMyG=#yayeS$6mwzDLzoAZw%=2mMvS1x+{W4nu+-v6&cxN&_?-?2Nj;l$o z=aFQWkWd?|$D#u=Teqfw`>sy<-7nFea33ZSc=! zHZuTBlm{=_fL(p1&_p9~eTr{qXQWkP^D*Dg}vOj%%rM8;l3!U%p@ZkxHm)f($@k^U zgGk{2C%$ovLlYM}@}?IR71@l}u3t{wD6~vqomX&h@ErtD<9VtGF8%w4hM#E8d4qLpt!|K+5%>i@WLR+SKf)hH&w@0G1gVq+i&+O`<_}(mm~&)Tqy26v zDW?Hs3RDk#qtm>t@^_=_F(>0Lnak4oPRBIlW+wT?oj*eY?X!;wvap%Vx;$Y&aQ0jf zf+vF(5*-fP1pj~7R}iRhX7tT(ExpgU#9dR*?+>HzsPhX`b1*zcq7wD1dCp`KOj@76 zL9PHEz49Oy!mmc!6n+9~?k3eIy)Fg=v^k$M^@rv_R4#mJU!#7Gmy;AAXUi2lJ&ont zr!(qeIzexc;@0!fiy&(O$Z3r?oyqEbHi3w$;RK4m^QfeLLR$Fu)Rrd3H+5WdD<5?v z#)<7PA2nX$QSzZ7#TZ*d@LSKMqioN#G7Tg#;-ND#KXc&ytK{X%cQ({eac|Nd|FkxY z8v0Ze9b@71?6}T5PSYky-sd&sae&*dk+~h<EJRHw$M?NZW@yuXo&U(Tpl5xkb^w2HlZGPmV%BC<`=H;`v=Kx>vD3Am zC0W-daiHI(zvV=vF}P1)DWc=zwrVA~9EONIZ?Qjm1rL>EwEXHcw4$3Q$cVs=z0K?t zXFn3YDL8ZN1xO-jB5EY(*XQ~(6;3qQ%n}HR_@N-+%Si$-^=H#e)61G*`@qomqoKZs zPW5My?$)H^YHGy`cn1RHh9<*54zw(HY-8e#OMF)G@!5=a(QWF_yRXZnu-hj!IK3n% zs+_f-y{ud5wAI%o^-Y=Ne3&G87}M~kC4IH=kZLn-vVhhLa-Hec?$dHM(}TF1i1qBc zyVUgg(`F=P>|( zlHW{m8j)1Pn~+YIvF$3KY$#(VApnQ3c!3DJ*}dN%qHSatL{=r+X*^#1=8YRuSu+#O z9g`!SHmu3Fdi5CMMYxH|onhNraC+f8GPFGUBWPDdpfMErz@le%eyolx=CCP^lcB^$ zocp9FXQ#P^WQtKq#o26Ilcl`8n9=g=-b&0cpdyGB{HiVnh6huYygb z7!FKH&(WBZs62p9D2`C+3a%yf)?Rg-wdU z4M;p(`%JqSSbNkQWY9c3S60VuRKBUEj~^+qYXvDa+%F5|b;wo)_RBL_RBi#-EQgxm zwGr-!-}>g+%rv76eD0ncY`p3%KD-~*_1zU1w}OgBGUaqJv8w8(rUx=g zd-twISO+%j>*^SRDAJv9?tOi|FbUf5%8ayl7c(C;HHq95MxoA1 zWY)LqgvfE=`d6Ru+Kg0!0a9NY85tm?8Q?Vbgi)$`$}p_XooKkra7cAB3$}{lWv7+xtNj`e&@xHpu@41^qw0+rdZ1t^>dKm0(H^`@=R83Y>a;AD=`EHBlRU zW=kOGr1!0|Df6@r?Z+febpOzo$1mT3WaG{zbK_Fxm#JT;elhS;JHEweSNp!>haQvg zdl_npkI4yf3H}{Uqwf54F{Sm9)v0*r_q8S}7;8pC8=IXab%03+DC1yL6ktAAeDIt| zaxUkq=Av5Z#hpT1?sT8(l>}DgX+vyCaT= zk>8s<(tP!u<(pS)r8pJiDORmbcVto9_hwaq6Sjqsx!Q)wF*a@Au)a^8R=y9qOXeRv zgYEaiS0<=Qz%KCF>ds#hRAJ2CDBbQn@=p)vr(2jw8Bb=GiK6e+V0O9ibez}eup zk&&^5q@k`}TBCte4Ren=g=D)ncd5!9>}9@#Gq`|9f-*_l3`xF{dHI`p`ckhCO7;Tz4e%p+4A`t^ zZ`~ABSO+a1E`Z1Jj8tfp>ds*!X_@s_Sr-!HQQ_b@GYXxWbFN`F4Ed8L<~3mNe#r>^ z0jH_Oh3n2z53 z^;-dc6TlTDnA6Z`sqkI|))>wK+ z5mnYQa@p^+z$s` zoFX3wEbdh?#=pEsHmcCLTEi zM90I>t24~n!on906Fb1hTq)vYhi^xzW5Gr=NzG#@g@uRMvwVZggnsbbUE+VzMl8-i zE6rDr;U+#z9w4o)4A!!6UfH@{wLhk~;nMmOte=0?&HQP5YUYGhnC$(Y{dU#03r~si zO&@#tVUa&>94GSRr?nT&|8ZR8yXsX3?*90Xj4q>9qEX30hSItHYvQim6rI*R|0`jj zP5540yzU*M8Q#>)kvi^@AxR_ejZ6yvX;+@vr>s-VsXvNEcvNEN_|JC}n`o%gtE(6o zDBtl!pJqc4v%DesxH-Ll`^dXW<*9ts=`1Xy&)o^VD?imM^LV_&ti6Q9I{zcPLle62 z!6wz_<2wxEO;VtyxC{UM<=P`hGCvN)o2V#>N^sOq?cG9>v=fQ{L_w`Cjm9K@`s-scp z_S<)2t`WMcKF1*z37_lr%Fd0E>=(~b|MTZz>zoGPG4T_wh)8+tpJ=8K-qWx{%pMA3 z6F2p^rnfk=VB9Gx#M?Vxp&8R469qxsjKonuoo4TqiME&+6lC`Y*;fBdmTRUFsb zIF71@hAh^XhmAe!Qoke7d{w5~_ePrNywJ^mqa9sqE= z`LY~*>*@zV*<~#dBndQ_^5kED)l|~ZaQ5`Jpa@do&yX7Sb;t!wCU8a{l`5X2FS4>e z^3M^L(LdcJ>F+M>e$;5WnVKf*s}+BbY5qcYunR9OdClp@?c0}k%F60qie;(jizw+O z9ElAl+<3&iJ=h$rRk?T&WsfAciJ)6=fw5`Nbs5JYye+}SWgBdjaZ#n6DbhVu@hz~% zYl|f}e1pgcN6P->%23q3B#cbE$9U;nXZYQ`;s5pN{6=A#cOz|`vuDo=;BYhs0<)}# z;>?qN{{Dw!PWJXLU7DJmoqZ{@8Bz+3v@__w@i+wiFbQ*oJ94g+?h=x8B)(RiCfMyJZ>J76R6%@So-G85}TnGW*2L0?DQK_M4t}O8m-@u4b-q3 z6nPr>K?lj0x9agJ>*B+`&K|4OzM*KKsi&jk-C0K2YERKkSY2f*xz`}6ej~X?_15^* zg4KunCjvjhzrf$!Tl&^iq&7JcZ7c_7PtRr0Tvu<+i=O7rWZRa$9gx#-1`3E1{R zU+{dzn9LKR^XU|njF}hkJHsjhHBs|xOKMcJyNcH{WujzUF*qB8c8S(6Jb)RbOLTynpdtS)=A6cAv zLNd?D&s&#oHEr9LELjrY+1WYM2CkyvL7+bQ043$=>1_((zwMWjmgXOHkb^YMbUwO% zJhv{{*i?(pv4Gw4#-lxmRVrD;z>y(ojVdHFoz)3i;`G`}=}qNKD_~l&+=PT2XatFE zK`K!pB_$w-+hZFM68{+SC-Sr0Y5*#l@GFA#?6s-{Kp#M3^Mrw&J4|cXq?d|hclzh)OWeo z_46KzFgQ*!OBdDsUL}u@FI`vcL6zxm;eEHM&cESl-KC$AN}^im*8=+phfDj3PtEozf)emg^no)mt)v<>k6S6 zYX`K@>1SZrs>PGkzZiKqES)b5y(_dIXbOQGMd&(A@xvw~% zITf#7z3PJuF%iL=8g4<3-UuRWkP;0u!&{JwI-J{jv%I{Vkc1{OcsA+k>5a|x)tU2r z^)u7?$SwC}k|LFGG$My^asrAi{6#B;gdSm%S)hUX@4F2Awc^9WXr@m-s&CxbY-Df$ z;;lL}C{L4+rR%RQH?tJ%ouH%b4gU~>0KlNEM{7lWgM!qj#yvfwYmSi}CDYnQ`)y*Y zY;O!UX9~l*D$b16Ty?xrHB5`DH$y0HQNIv1V9d{Ps1s0l<0>@Ql7W2A$%(?>7I1X3 zLPMN?A%)9D;v;)|+hx0jf4| zpcU7c^03^oH-79#ie=Q))wh@cA-0b0hFpxtgQJWJTthN^Wrgd+KrdHK6ka|J4ZO9= z%F3qmVFC(oKo##wP}C>lPP@o1xMm3qv!+3ZQSr^#j-1KN%35=9Mjv~HT)6>{`SlHN zd#Kb-ATS(jJm|Tsq`0_PEXnPio_D?b%&%cpp*HQhl0rfgtp>if;Sm%_K*iFTn4Gob2tpZd1Ln)>}o`oiW{$Be~9cxRT@6Rh%@GpJ*`7bfdiqk<4VdC1fx6q*Qgb zxihD;825x}F0I{4llrXgd?l|k$IIRVf((puQI4(XZ+1q#E_(Vy#dZCW#lu0ov|-z~#mz*f=rW}ow<-rTbnx&e)w98LdHiN4WxYCrNiD647{FF4G{^wmqjmX=HdpZ* zHxxMvl?xUvv%i|}Zr&myZzrYA-NHiHJ+BVRQJCt_6BA4O`pkc=&uiRD(?zC`r*IIP z!+!lt;$0`IPMv_C zHM=o2@npon*UND<+EclsVNv8^xsjac^r*?|qKyXT82UH+!5bL>#ZP{?#=E#m{zdw_ zB=U7e)y{xb7QkC-Fw@p~o1&L}`3Zrn$r{HI z#GW`%GJB>`|FiH2=2$I#j+38ApA4kTggedDN0v6`t>sVL1C0SFGwG8@@>eShwhF?y z2uWDinDr-3E?l^96_3xOAW)p;QB_q{q%S~_N=z(@-a;&STXe^c8?!Rz ze+9bHF(uXV@}EN$NE0g z!l-=y-*u9degbEBZ)9!irBxzsrCatE0a&pW^V5dC%+NwYl?s0L-;76xhAa|B}?Xa;9kIquM@`f^`X6a(@I6a*lOCq7W-*s>iOV zS1bq)!yzv24u>0$B)OJ${5H|7QUPf~ip31vn+zF#E$GL9ot}iuHb3ErNe5d+a#E?B zHAj@YDinZE&C@SQg_bj2@&%nE_+MjdMq3&ux3`FYEzVt}fDubMj!^1&Zei(pbUFd{ z`&V%!_PMXPHh(?J`5F{(%L=nYVAdvFG5BrG*>8galI9_qpFAPcpU4usQpKRQV#(lL zgYqTap7FIGU(}E_cPpj3xxP2o;RfF>$5FfaVc95jlsiubzBO7vRrg<6(eq!?Z2NNl35_u{ z6x*?5YA&FPpN9c)qZh+`^WE#JEi(WqoM)p$9?ALpS^7e^j{|b)4-#JANb{;K{;l2X zDW2U80NKX^6tL{&h}NAWhz;$Ww=6?g{O~W9<QU2mb45n~_viI<;)#`p#y^sVyG|`KqP4+3L5=Jc;lB`7Jde}W+J4tMrk*|AS&Sh6hJ`kr=d40MM!d zqrP!LYW*vhmR>EOc+JTQ@Hn-5`$yd^*>Av>a4 zL*xKA;E#gSGm0&e^6O|=H>ez~uVATPQlLBE14&}`$D;}h60p}Iv!?fX5S>aco2C&X z??M+evyGLhUS5|liKYeqo2duW{BFn;k&<@;h<7?oR7*>?w;m^WQ$5y^nVzLwjfa#E z#9~_z%+6yRQ@v}}#A-y|j8+cVV#2#Y<|mjJsBD&`9|)6kRAegtCnz4<+WG0Hz*7Hb z&b}^YZC9S;|WsEK6nhDtTJW`-hbxM&Xr^<{XZHgbm$rr;_?ico0g?iRyS zm;<)3l-GT-=zdt3S_P1r6R2F;pD7l+EcHV+86ZpC)FIE(e|!bP@UX{Fr9k(s7$;YR z($QhGbleqloRQ};q>rE;nBl`WWO5l4ao$PwTqfY-?d^R|fBJFu@+8hwjZCO?=c{zn zLx%=(iK{73>pNaYHygj`nSO{|fafPHba%3&V+)>voIEl1Y>WEO)X8=T@6j1 zRS?%HnaPDEe>FGXwoE|QzL|k=BV*OWbGp;BVGu0wb&mNxG2QC&9N!}wIMGSPV-eGe z4ED=wlF-mK>5gMqM1)Uc)rtnJFA_xWd4Hvf?Zqo&Vu^MDl zIvViY;BXA0qEhHc>d?#}K`YHlO8tZFHj}OLLo@e?0j}=OqlxwB+1F?#25r;VobdI* z4ei{XSxY6*o#7#VJzZyNP5rRDLG8x(J&FiDO^SFi5T($-eZ?Wt0Cu1B?-$NnfRYL;zf zpX>-9Xg=W!Q+geXFAQ&CZt4QGJOR2aHW%EZGR53!xk}shHS?6FPktWQadZ#m1>zLs zmzOC{iZ*%I3nctl5+EqZJefN`0=$cGB^KfEnwNT_5^9}hLdPe48(**}Y=VMdQ=c)K zRN`3}s!@S_Z8_eN>^6c^Qe5Lc?i!#>u5Z8FrluCqL;&9%9I z4;Jy{n*KA`KYzo9gv<4(K$oX3mj8O`j*6f>GbC5DmXy4fo%X(85`1eknnh3&E-L=> z%l`%-gC&VDd46-wI)AN({K#MzOWd7F>~LoVa2nG<(i)eVH7w=m^o_5b7@T$qQ&b2= zG`mOoLv$P7`tWiQ&JS9V4`k57_uBOY6O;C6cMRt`w@iz>;~4DGuJcK`tVI-GVjg4B z$Yi2eN>L})uCU<{=F6x!e5-WnqY8O)IY>k&0X> z`oEGiqlYRqV!7-olc!il&r(WSE`CNI6$hRvEbMrA5n!FVigFn+K- zNCnBx#@2WTC{A6fa#&Ch26nj=+MHQU>qk&CS@|@!XwMEY{v39}beecNR;Tb>8ryc> zYzw{-b;8*2(GAld(k=<>JHC)wspR6+r8E5*TY2xxzvKm036PbIF(`&5W=y1Q4sn5_@nLDd&1P+PdN2w!c<*@y;8RUT4aa&n1d(hQ7Z{$eScNk1+c^Z9x zbB;6J^ab%lwHus#?YCaqs<@(};=$ne&lAidoVQHSDDKS+^$7Vm43jV1r->k*BGu3g z>CP?)Ok+;!1cq~$0(WC7ANwcrd)DA%f5B9(hxi5P*8nw6ixm>HPsXjpgr3L4zjSWe zGzN%P9M60?pM?Gb+5&cNSHAXLHI?AR11mGmPMMHipKT4xy7c?%1hLBM0^yRm8sxT90?~;yjZ0C zw*`wjAjLELt%V0Jo0xQ$j*Zz9k=w3Ofg0MKd-kkK*G+gQS@_|so}QmoW+?0NA#^gc z)+PYLe3a;kzCwRx;F8eN2$5=_f}$*Kn+#VS^TpEFlgrfqDevvYyUY*YDji3k#K7H#iaU zkBipK#>SAdy1MElhHdGxZgNfKTDiMQ8scUPZ9KcXmq2aViI3=(ZuZ1HhwrU&2Q#vu z!k#i>K~`Y2G!v|hjW;q~sm_9}Rw=RfF(*cA{jt}`+$ER5*<3&fOQRU0Q@M|fnV^Ml z!yVbalcV=I#`vy{xSIgD5CX78zV2LtK-T;Aix*59`T6C|(A)%}x!e2x7RY}golIod zV;Y=;VTve1_Zq&i^_u-`;! z>j<^6A#0rhv!Zjv-x_bMnuu*Y6Kn@PErb9IyxK@YS<+S6aE3gm$s(x)$9jn?;Ux^) zeqVzv`Z)F|+wPn^#BwIEI^9LDVhXmwoU0rloukPb_EZwZTU~q{9F|aPej+{w+pQ0A z+=(cJW}e{ISZz%eb+6ZhSd%j8Zx8^DW-m8l+~&7Su+{$CmC4~Kn0WV9twTMzJ?80N z;6LmEanG=nLTBOQ;XmEyXFi^Z&kw_lsmF!XoSbzVX9N+))==&oY<=JwCvq33FnAsS zu1!NS!f;xcj)6gdXk{QB(psZ=6?lcwywEUO_Zx?X3mmo<7~joQX=&-scNX{V(4)s) zEFF9YHOJIynF7XgMo_-B7fn4aU4%WwFF zp^Ou{ebABfd^5)J-^7~xX0UR--GdWp3SllUI#^l_%j6!1hOzeHM{bLcxuWvr!Khj> zhsQS`{igev!2@~xl2TA0s1qzqUGIOS%Q=V%IcS(Ckl4IT(=c ziABOnUXrcPBy?PHX_Fd!qQ#{@0$8oZaPY|@E6>3zxB&?~ zbAMR*vZ4@*kA>f0%i7GA)cCh*;o5T7N3Tuv%X%?hF8kGoU6B4%w6fDoJ8=^=vqN#9 zHB0S8vS|4@c8Q#Ei32xQBdTJ!;2mY^@+y#pbWSEOOT83NX^6u$7$k-Su zIt(?1gc-1g8qezJ94F=S{<`q8XU|PjdDgHu@-%U$G?XVwKMW)b3|$jAX_i{#nsTsD zO`5XIv1O+Kuj1}|VU(;KKFE=)kUXbv-OoJe^N46I))#coz&p*12=Dq#OK=*EcPc9C ze_Y3-`TbRNXQ4aln=z1ilJu2SQa%OKdT{mA&@E#-(nhn3btzvkwAIR%?JwGIvx}#J zjp+(x3ta9GF)LW1^V{+Z$aKY?`k9ziR?cHMjqMP0jGqHF=G(V#mwpl(JFNg(u22*D zbo<7|#X&MHDB^E7>H!V0&uxVo>!UEOulaPOFy?k@ZsV{|*reWZjw^2&g79P~gFssZrPjb3^CZ1xBN zGvi3G$@iv+dN@W>8XhSEOz!0Y%tki{Xv=?^>Tf0){x{PciERkS7iy+!tdyFI;*__O ztgpAXwHxE6gP`1<5X05VmU}g@JUH^%&)D^(?WmJ?qZsod!mM|%yG=dQ1KjjhWZHa4 zyLavs1ZKt7-8Ch?NhR(|)A?tiO?w4rh&Xdv?YMwbGucspaAnRAy5YtQeD_ycm+aZ% zK)Y$0cH+_&_wzh?hxEo02d596o17*g{6~DH%-$K z0Xn)#8uBgwk-gDTZDE1?N&;0b=)25&(%#!g}%i(0*HStqt(&cwxA|^O>6<%9`0y) zNdMv3T0WpfKnesip|OEs?(^km%^`iPQ84-t|J8)~mo42qO`79EM5p)XH+2rKVWec)%p}Rx1SaK1n-}*-7N*$0E z{IU^0uQQ=AoM?k&55Fv&FR9 zl|LNC4RTUA{vCOz8`YZI74d9(q_4PJZ$KcuKFJ^eP9;OAy{M!3hhf1@PPX3gh4na~V8oOF#^WRf>S_^ttP!Nkqb)#LJea zrA~>6zNay7O>An<&_1m{YJ)M??fxRpMdieuj*Fd#>Cz%ess+F&`iADT4 z<^in0Zs~eV17j=ttxSb)O?%J!xyk8?dfCghlk|_142Xp2cW5x+G05e(TkRst)5Bk< ziteSDr*8|#j79_|FW9)gU^M<)!C=TU$4gS{p*|@D7;{K6gmy}F6A z4Wq|>ypDn)g|}oJEERX?Ic?pmB<;AnX;3n#+sw?&=+|HOLR<-#g7Yd8&z`-6@T=9s zU1U?GXN?R59^$g$zMu-y_?&<1Fh5lM$GYqj|H|`Y0)bA=|FjIwGcog*d7OZv5c?j0 zLxb8I;;Mxfo}M_x6Mx;%ryOL`$58ML&K!bcSPv&?sgewG9mMoGvGsu%BvNCx?Eye0 zZEmi{7mF#O$TrE+nKeIOi+lz&+4A{e$Sn>X5*0V_f~<5G%U3)ifS)~OeTSYL{;zF{+ zP+|a(?0V&!8+sWc=vGNKffSU&Tvu#5_ zHxVVAbgxp)wP0SxFXauSaOg>uySVDTbNVR}rAv`NGA_t~2bjH*#fdgJ{+_wXZpvlhc;VrU3kkt^fS1;=_`_K zX_DDifAUEc!tl_+TDjehyF1%GH8xR;IHAW*j!{&X?)cwO&4pDTKS3tr{nDuVoiu~Q z33wg|coJ_fc;g;Z6Eg3NYIK$^tgw6Mjp#np2IRgA{)0LQql0J z&UeFe-GuMvMT`HtP|B(CWzYu!YTyFt)kSU%Ux+6dQ6EF#OpoYB%au7tPM}ELVMmb% zxaMq0t85ePs1WdnKf1k6l_xlKtC)bMGL;+9yh#c zqM|PX>3n>j0KQ0^p*j06?^Sp_}m0{@s#){DI2(2>7&lYU>j=lOksHZ3#aqsb0%ESWP||pN`p@ z-d+PgPeQ+RARSQ(*WO_02dW_cGq3GmTMV9=u}&Pvn5ewQiMy{bw@7+#B>!s^ohUkp zswI!mI&hruW6?z2k8c3%G@&nj*4=%tlS$=l1K(iKSDgwa>(!QHGHa0mOT7NFjm&9+ zETMmIZ!dui0D{Eby1F_e;PpV_GRDlKJsqfwtya>|eeWIZ1p4fTl~5Gnf^Bm251NYe ztn4S_2OYU#9{`}fTZkP0213`8;v_Mz4JqyeTxSOcj+)a=1gsAjqfo7{WEowO}-JXJ)q(n+cVFv*4kM8HPYb zei?z9MP?qg5;C}v70iHrU?9#*TygX|7X%tEaGtwB^B)R}7T*d}$&mpFVM3zIzic5U@9EuNJzUP&CTE7!?UxatF0pAM3v;^R;a30B3o%?crQJYqlfQRbq@<8 zVu0T^fTZT)6TUTaz1aeK2J-7zdOoSL^LPLdi*8io@$3u1w)|8VOuaLhOPLE(ICPkzUTR6f=XsavC=l$?- zH+q?Nl2tK4x;CAqWF<*i+2z1G+-7_l`5KQ1#(94jK$xnDEQJ#r0#lK;rfs4k5en1! zPNU_V4Xsv;^W^vaS*Oo=4g^UoWh4h|)r1QC}g*DiR@tkRX=q$>v=i{?>_37XY>VzwC zW{?pqCr(%p*JZZYR-W56YqrQTSh({;dE1=);~)9<(b4PB=2XNUB>_1(VoST=Lq@Ze zZ!WE1T7WnK+35W4G6?ITNE@+>c<8?Bk8CJ}A>CDV$0%VnG~i4G{Ndh+vin#zRD-8C zw6wJNV2bp^aqOB0ht5%4wiK|sIb*@GB5haeJv+vFIZfmgbb7PO{kfQMTO@@uqfutS z?soSzn2Is*;l&%ejjVr1emkEhsybIK8;FtSAs@dB&h6l ziws1y^1hwiIWz@Qzv4`|DMs)opqEPF6=5Iy{0G){@IW#ErM zZ*&9i{(5P6*vQEB0s`Kk3@>+ILO=Htl;D2_eL+7{C;@nj|7`*$^+yQLkPy{_iqo9$9Ux>kPLq=Xb>3^*8kJ5w zBf^>L*Y0d8Jz@eGUB-pCrt1>wJL}FdHbHC-A&vYMIZMxJL(ld~2x%PFkXTxJ#+Fo4 zR(J6E>!y8qO07da0&TvK#?4_mWOd%`bsCP!?qZeJ`pY#B*o=mc!FK~kn)bn_(?4x1p0KdOE;q&Ftb)E&71+tMFtXZj@sOKH8owS9DT4RSm zy7fh!fWW^M4*!wLnN*5!?vcB_N`x;1aermM9|eZzQl1-M$xdpY)6vP^si4qG+Y5KO z@vf;!SMB(5KpEo4mR_M_^d)Yr%*oBq_4V)1BmbR^vnAcXbF{opFnbm`JKO09~ z?R-)GPS$Hz-Rr3*_N1lR{0UHt>_YC^K)NzH-5P>#vtwJ6L|$Er z*o%qULWiC=Yq2hQ$kYHuXYPcaPTV_yYLchQz}u7;N2{<-ybrNHa$@Wb{o3=jB?>K9 z>%+kTx8EqZmAq z>({TPys&?f!D6xWM8zXjNW7`0D;Zb%-k0AG2{}e0j=ifKX{E7F*%q|6t!*8;-i5EL zcqDQH;h3cBfO3M%tt^1E2Zc8CxJu=9+YtOPI0g^u(p~)RS29eH;^jHK%-i zJv)oN?*-DAELmjyYwxAYOeQn?tiEDU81CZn#t`Vyr-3w(Pdh1@kT}r^l^02!B}9(r zV^+Z;oRji?8(`;y{2Yy=gY>+nLnvdF8Qpwbe1Ar>Ty%5(tuV5#&dSY;lT((tI(=-P z*(vSl7#D&pgU8go?tK5=YVG?0WbL#fncjr87+PcUpR8~Fh6!{-B;Qusy#I zBOadg2WzlvVQ)Z>4*{D+o~-)jv=#6FJ2H1u;M_XH+Q2>3`l3sN?ZY^?sJc!x zvE#RGuIigF+1wiE($jyc`5M#X1>m@wawdU@z#`YM{~Z&WA(BUPh`W@yPR($t-O35k?@i}kM1FgsMQrz7sNhDKS;eC z`>igUCnSJdMASB52gjW=a&eKxNR1LA7;d)n>c_W6Ve(996?388P*hAHK}<1xg2Jb^|EZP9VZ1dr*(oO%8pd1yOZl5O_Hb5f z^n0~ddh1DMxvAt-{+PnuD)L;bzlIx>8JpXTTnUpIvHga*UnZdI7bt8Hcln7;)-os; z5gv&VpV6@;aIFgP1s(ynGy+=kK$pcHeQK?AblZ zsPE+A-<4iZkQu--$WnjD9E+pxX^c*YEbZg=(CK#RSOQt1;>!+6HWH23LuVby0mN;T zdJL!NmLkz@IZycn4Za+ECp`v#k93E`q>IE9Me_1Ay5~T2A?hT*INqj-ENLI9Bk}I zC$b2uzms^fnxD7Kdxf|#m4EfJ(s%Ewn?~VLQ}XcJ5I+Pi|0P`pZkr6=X=jFI>zyzq zcBVL-9BBrIW&$%Yiy9Adjm!I+R+;C73^;;cM~HgUy?ydCuM* zPmC%l(X_*$U;_{pG)PH_iM6t*&z8Isi=ugG{h<_ADA${@;HHq*e0gQ}VnbeYN>!CI zYky=0erX*T@SN)m&_2vK88VuPdv(6$2T&$A|MEB z7V{6~Ib6-Fn4v@W3eS9F`rkA$^Y+50fCcJpq(2}<90bhJa|WcQ!0fH7|^S@Jb{3okD?=o(su zs@bw*?&;s85vY-WND1nQEw|@7V!*^OkXZ@rlNb_;Z+slCJ%!Cb{C+q;e3-Z6|A)hy zuZR}FPWc&T0{vQb6QCOo^{`$xK0CvCp^l_ExZ7FFYN^J7>=40peAcpKPckf#wxGce z;#>>PZBsH&`mz3kanB;1w6&a@blqoWRi=0`|BkC?16T=}Lq|zvTV^stQr!jDoX6(J zxbJH+Xv~YVq_w$rfYnBP``a7IM+lM{q|D~Qj}A3TPUe}8N5D1Q8=0OeqJpsP0e9_U zmbO9j7~d3=eyEroA-eqnvmF?g>A7296=%6Jsi?q>QKsOk6dcB3$5R6M^`Y?(A*~=- z&+~4cQq5L9PhP2I_3hEP))mC*#_L_Iit!*gF@9q?b4_6Vo&H;QaQXeo=%cB0rr$+g zX)*+LGhcN08pwx*1stEUmNenWOXPe-1^(q|dv>{b@X1gxQ8wNWOpW+>i*&^MV#Ujo zqg@L^!-yf&bW%}iclzJ`u$Bcp9zT9Sm9;8<^1W3is;noqW7YH5L9tQ*xDBpm3G`$e zXR*I^zW%cRW&ssqE|3PmWl>!7UbgyjI75DJ|D5-dEb5Qw|Fe;g@cD-y(L8-EQ> z0S7ceYjs*$8Z5vE*@33oo526?!V@V0zSdA@p&=DoO$*9hW>U|ERr)rVTqQfIc2^EX zSrW`EgBvm~Tf~L*wSmFDHD@0$bA2l3Uin@Ops8?__jp!=yC463mkj9oGh^DFzbzWl zAUWppcf78LX6$AOqCU%!JTj0SoFjy(jKN%`p~mTylT;Do?kN?>=HEVPQ85&S1Tdlc zKeIk6Gm2>hhhO#*1zkm41qwKQjLz%)1>s@1lKOWdLs0`3aa_3PGjIF3@c)JvV7VzN zf1>C@fW+vie83RX%9fDY=toGp7bdQ95z(?9?O43-acG911QmiB_jDzdl(d`Wqx;^+ zX?K?JbD$rv70u6zalls5!eoIunwU5T%UJ5V46grUFZ5?b4w8dTDd~xS zlL~+;M&+b>Uue3w)D@|^1%Id^MAEEf4$tOk#9WkX)<=CP2vxa=LsD6*A}{&?>#Q z!aN-9D00>vlYxCPz?a(tC&}SHp@@lBF}QMOUQ3@pk4xv^JT?sna~d0YOFA{=r3Q8) zbH~&6QeaN0SOpg67A{Q9%iEx#Fn;>v1QaAgJq@!7%U*jpVjRun-=IIujtD4Oemr0X zr(I_*_Th|*$97g4uxU0kQ{#;DHJ8+i5AqHMP}qYMXn>Nbgy&krH0ZD}XQ4|4pGBI@ zbreyT@G-W38$6Z?%CA8hmFBXCpq$SK>hTK(&D@#y4E%{x@thF*0h$}l7095(<&G^j zWz7TvH+&xTw48=d?5RbX=&Fnv7zoIxIad z$e;*?khY>sK}D)n5D5wbwgKV>0RjnA+kz6HwhB^&j3Bfw7#3MnLTFhs7DB`-L=p^5 zKtuyEAS95G%zeKv^k@&`{G0qx&iQiQ-0$7)^4$B}E!aNY|N2d6U!nq%kCbi&#cUkY z=pO)+)@VgWQ96w;U#7*TtnY_ye>;f&BDnx0-o(*^Cagaw7`ih5n;!Y zfJcBx%MsJ2oT*588sAXh!E9w1Tlsw1BsQ$n6F+JDn|DEr7+q!MQ3?Qo{N`?OaG`<^M z>z8Qrg_BDG&FqNFM~&PGsoIMes8{|bup&5(2z0qc-A{##Yn|zJ<6Xhw(0;f#5(|Xw z_uMeMofh&W;KvhJF$@3-)cc`w+1XjW9F0wqYgHo1n&H`6f|}13;G(04gbxO0ywJ`& zL&sN0GEg^=0PDC%`2p4d{Jcw7|8}B!Z%}(jhdmC9Sqt7~okKCSr3FUEj)PW9U8tvA z9&DmaLKFHhAQwXZjn%%5RVl3NdxJ(R6ladAdDrv!n+lK-^Oz1`I?1BdyuF(*Y|4OC zxK*>_3$0`?=|h388TXG%%I97y- zlB#`?zj)WH6ULJrU@nRNU+yCi2^3#kFbK>IN5pgU_88 z4%f((nHwMeqa%0CpR6ij%!n~&Z`>ZJl5N6jrBlT(@ooOE5HCJm|DUif_v?}p#{BXp zx4$2IdZ8iD0&`p$)?-2xx6h{jNWnB(7V1m;o&i|TpsvIyW5>T2n&}WKuu%*@Ix-qY zUbv9Oh-q=?DN9g~3|ABn82H$D^&Z$hOm&VQk>5xFzJzZp5y1r1EE+?pdrwlQw{K)$ zzsm_8`Rdpz?aw#P>TS)s&y6ko8r20WMq;-L2hI|^fOmCPL&Z6i}u!c%aWrGTj3OVsm?VFMT7n)EB21h#gZ6$>vzJQEGo^n&0HHw z7fE8qBwMks*B5Zykpa-Rj6JwAST)5XpE4W$cv&Oj`%Lk5MqWDAY(=%5qv^RhGKLAg zZVG?pgguLb}xlRhB%wzxFIz{8aG=cslGqZQj35a_~pwvw?0TKR+LO zo2HlLZ{tyO<~$76^dd6PZ+a;zam#M>1vD2G2xU{XftRpj6#WJc-QX|yGR7qL25Y9e zy4n&Ff|9At#hs4TkmP+JpRbB0zM(YE;ap@JFgtS)(Fgx`58#|ySPv`3i70#ek}`3FE(#>(p! zLNo3(U%p@RV9l)Me-9D#0NHEc31?mzB)mU0nQ?nS+3xQLA$aP63cR-SoCL=n;%O_PYkRC=868Kw6-fvMH-TZ)l#74}t{>MR4~d$BA!&3`gR%$`)v_kd&-%vL!#(c2H5) zBM`CJ`ap+?*xFV33;U*RsBF(90nNtk@P27ACfK?yYxmW?g(l2nq)t@^tM$+r0n-B5 zHyRA4F5=uVm|E^dG;KiJqk?Qib6(p??IKMRS{8Wi%Llh$V-W%wDCY-~#hA%iU0jag zktdjvd+wGZ9TdZZwDs|DohJX8onhA5}d-lCMM!Hoyx9o%L67X)V3+ zF{I$lVzCt0rQI62S#_@|IWusp5PO_Zd*Ah;qYc3t}&qN$># z1?1l*yGF9Dqk68g91Z3&*lLeZSnB7m=E8z3wlzIVQ;Z*5&r1L~>oYthikt6DgJl#J z8Clvjwhb&%;78ggNZJ5zN(4x|0w`@Dxu&|1*cVk%m*BSje1f~Xu>A14oSdw#93GFC zF)#qQ_lI3vB^kOO1U=DQ%B3Z_Hy8>yz7VYZ!-W7w)u^YF^G+<6pq_G(lt!`fswV~4 z#D3giYnBlqiPGhEV)yb)%EkWSNI{n8hLo8LB#?-{>);R$*IVW442U1M fE;LsNJ>kGba#gZ0+LF1cXy)*2na}S8Ucw-N;llK zH+tUp-21!t&$~Y;xSc&S--!@(qzO5~M`)ZTU+H2M`4=@HzLwb=RBg-M}rHh(UQc_jDXJO_T zTHhxRZv;8BMN5VxzK$oq7-Y;gl6SH`d>-TG(XQGB&rNHNrRqheQR`}TYpz)9N;SHU zL~W5|`z1qpb@j$Pk1d>#6yHQa`DYJ>2nhvQQ)=XAX7nzq2QF)2`Z6#uT=u?WT^Zwo z6`{r$PKGOTvU5qG4JIXg`#=MO?%uty7Qw{ZsA*tiHtezAuoV`J7aV-yXKvQ&6b_D8#i^ep!QAfA(@V5&dz}32 zHMUrlF*jdX(fM*Ki-b!kL|&=BTB|TmgO~Rf=2>^Ql~*=+6?qz11cHe{QPI%~GBP*w z5z(XL7+*=ev@rb&c9YS zHZhU2vU=8|FE*xJELMLoHqA8`Q^~b5NS8L8<2=ovpunFl&QvL*+x&jmV$U7ZmztJBBhP42&QJj*|;1l$gE(`bk&LisD=* zI1}+{?h(d|G)JDi*;#!j9*VuAV|Vo(toxdZk{#4;NO9s;-9n6_>S|Ry{`EJ_fj6?B zr@I-)>mA5b*xB0BlHq2Tl)U+n+;DStV^3aDF|VqMi~I$VBYHHgt8)|RA22Ye+RV$L zrF^1{GR*X-Y@ArJE+-&BO5JKNHOvqHE*(3&l3(6#k&3Fy)|6lVQuIdL$zN|DyR430 z!0^^Z+!*eR?LbOlqI&bpf$jX=?NMS%iZU-R@8!3T-82x*QIc7iLn#}byxCog`}rqP z`8)iB8N-sQ+kCU58~hy|9oHYdF#LQ!ut_H?GqeAy$otTa=CKI@wy&+N!R`IIot;uM zGc&2&~!o0qJ+f6*@@cT_wHTG-}{g< zakOGJX4%Mkz*A;^Bmyl8OVJ~lQo5>w&x zDG?hel$Vi7*x$b}GdtThX&IrxkA8~Xa-pvJ<*WWrw%Rqvlk1O`F~xdfIMWvoCQkC; zRHbgcXxuAbU$+*28wuNX`NC@=>$VyjrN|1(N4a>6;U*0MQc*Z_miSJ`#gj+0z1xD+ z+n*L#{Ushngk4C$ATgvL|Kh>QDO#=>IA z^$48c-z(|lG+1%(t-`$iNQ#h<5E&v~m!V9LvV3n!ccIeKXxnxMc9nZFHQU3Bo1ZRHMg;KBeEhJr z-ku-vPJ;gUS0kR1q@+J`S7=zd16hA^;HOgK7>wN2DiEKGKjG|Md-^x!BP;$u5ZIzuJS3rczSC>NqKkJ&X=Y|mqJ@9`Yw~{liBq4gD|K9T+n1vt zBR3Lu^B4-}`SP@Bd_upb&4ug}84ZoNGzrdGPxj62%{TJuN5mabb_=(N+6V_UFyhW*!L@3=PR%>_a%qwS}$Pr6l9I?aDYdv^Iz2Yr# z=>8G=la>ton62NGl_2}Xp&RDeGjhwjJo6{JpPbD?C;svd%j(i=d_aJGq13SZn%kk3 zA60TVZM3iNWxJCj@tKW1+~=MjaN^sCEV0+PZ*iIxCE`WyRtDi5d|EPy?wXS`Fi218 z&WMqkyET0xCn%UaJj`u7S}2E0Vzc=(*|wFKX~}NrP9R^R10rY9ZsAgMbDA$XD z@nZtko`E9JWN{$3YG+*2h?ot$z7I8+&ixeSWK-| zXt=K34Gj-R&L`7Q76?4N_SfQCOZ@kbbS;*>OhLE14dt2Yb{%+kMmMS^y%quf3(5y? zUGtg8^H9$7@*;O>H{@gV;xkypm`Teo>+%nV-O>#uC39bWN?@#--&l99$n0+;X0)^ub z_Jt(?M8HbqfT~Bv@USG{swlq!_75$c!VFj^_^PU^dQm*|F*^Ew9{uCvdBvSk*%v8xbL&oyR_WLg zA67oTJi|m0n4O#~=rD04ZZ@i%yy|gMUA56!&7%Ez*EapaO@Hi08LDfXKOH9FIEzx< zZk#uJBaGomXugwowrNz5;D)=by87#T_d*=Zt(2Q&%<{9td9VFNWBZB)_GjE>6_Hzh zEGo@^WB>%hZTbcR>_*agrE<=0F_*vZXy?T18N!o((z?=#7kzSrJYh}5dZq*U6D>KC zC=Y)S0iZ1G)O*O*pB#O-ckf=GwEMas&JD%HtgHq1F4Bfiq-c~MvmYVf|M42HzqdCz zFOTtPL1|~I~G3w0P`oo2~q=H~8`;ohe>ad;@~?p`Owg%sjF zIo#N9QzD|U%zBP-#B|+%q4|czz(!Yn!p?+;rm*l^Ksx80G1ja+jYOA~O1~+Zn{RIi zzoT&5dE`T!foG+CR<-W=4G&PY$MK6!*<=kU4^ z3{7FhK7YP#w9^zbHFX`?xuzr`Vc?ZJu)=Ic+k={VTRxw*Mu5~~Bv{;XBMK6fn+o86heDb^9p`30Y>q3RMO80)5wse_HV>oQXF?E*3T|$- zaM)v{((Bek--b}7_hy1k?(aJT&7kIa%i<|Cv{~8ZrugDe8kBVwDofyc%gx0) z1bo(BOeVq*9UaJ3E!7oCewMfKWX@7O-!OS9JN!Y)*{FP`20VdyNNYu z%7%h$9~z2Yhq?`Qe=^R;6Z-?D3o9$#hkJ7wd3k(ebY}$y23cSGZIM2^?}htJ-R*Vr zK@0WW{AIhX>xvKMrNY~DMX5q$t|pF|BbJ7WUyuwNln6CGVA20(C>h5SIl1{XKy1jA4TtoRkVVZ}+S8{`f7(}vhR^jb zmrtY(3@C<%g{5(;V;G^P*kPfO4K{qVna&^9iwx?}my-%mMXgR1P@taJ+ZZqW0ZYqA zoF%1Cp~LX7;v6w8-_GIFqoY(M7j^rL8!U?p*HICgRQX8i%F35?opGD>Ui0$y#jS<; z%s8B}xHCV0 zew~>*a4I_?;U?_%b8yPWNBcMsHQb}4 z3+_esZ6aGTv$9m8*~|ulZp|1Q8h*EM-|$3vI;0fw>u)WT9yy(zz^}UvSu*#q^&z5V z3>W9*G(SR0dnnr3m8P83behs$_g_A)TbjDgg0cD9lH+zhJHoo!*Edn6+P>Cji-t|^ z%l7hC)FZtRI4;GSe6F!l>F&FYs`9e3NnLI$x5aucQo3fqrtUb6Vf5U;?*GX7G<^MQ zp?!}%pIvEUw;7@Ee6L`oW+SgQxdK_^cpwA+_A2&9)29YnR*WZ)pzDtwgR#QtxQPof6SK9C=uT8hK zPFflsA3CA7|L2AiA+C4ni&mwXjWu$@%&oCicTHAS*0gD9&Y7Pnv&<1-Ws(sO{$|$y z_PvF&T=bE%U(b8eUb~;c_`5L|Jl(JOKly2Ufxi5PtVS05_@%8X(*YwIlK~^QgPJ8I z@)@9E3@jpiebQ2jucNI}V~lm2`YR-b@@QU>-0F+6Kgq)+X|c0ku>tO?S9#E}ABN)A z)}bn}TOuZn6qLUk9&zx$bnVja%+A41!03gWtV{OQVDh-6bJmp+!`DO;bpv_J5LbDv zZEW;NY6*ogMBj`o515r7Io7u@0q^MK-64D1cnhcu-IYsAv2XDje&_;i37?bGn>lx} z_BjM4kNhZMKeZmvmU9YGbzTW>L0%=VxYB;;F0HfsA{&*{7QC zAD2^!vFYyQ>L$vFE-x>S_Wz}o53C>{09Vf8?dg!Or$L9|bmTo7nF(En5L{A@kHYqJ z0@(xcYqGH?_JSvN3rYp3OG~4MV**@s$A}jKqOH-1<2+#{*GkRxs-3!vb_36CSd4$> z4TbNF=f!^ba3`=Od3JWzedvnkO9mpp%uJ(nUq8P;JmLAv4GZ)!$H3Tc?2P4}S^K$N z$?+_t`8{ds+H~_mphwQaM%8h_At^Y!H?>VZ`(0;+#numw;LHNSk>#OS-MDZDTOu|# z*4WfkR=7!K$h6Eh9sNWC13wOLoObRh1i>=cB^^!6oqGQKi2?4#66wr@o0>Z(Rlxbi z!bUE>{(H=2;x!!gfz0%nimpdhC+9hh$c3P`=Q$ug`UW(DLU!%ZJG4_C`mKLNRF!uj0IJ3_brBc=%_KLZj;M?*t1mWlQx z4`?lqaYO@QFX6<$s;In- z=DL5|vVC?z!OgoP9t(ILisItgJe3qU*(6!MzPC_bEu^G2Ps7d*XSl8w^ebKzXEo^J zKk!`SGJKgtC7j&t#&yHz4WZw|BkTv?hfIfEx*Gv_m+fg%tFEJ0o{Vg6!n3b<$TS3- z{BViGQ@(h}{wN$lje&tg8BC|&A_*Uwz!r5?Ja@rM1iaSX@UA_lN(g5f4wD8pZx!~ zk&Vh#dyTumtHKh{a$@+Qv%wv7_zz07Q`a&9EPP*frk)b&vnKY4Vi*=CbegH3%w+C zFi#Lj;i*t^Y{`TO$fKE=Vj=QsYV_WX!5^1@&+#iCs>hyNfGwbag@C8*S+pxTqVRc= zoRyys*7bCu2`vSZTteZ#xOnJ?56Qqjg>MJDPc+9(XoKJiG=P8xEk~m|y*Uj+TWDx# z>x^|~U7bd^p>2JHTNWOuLiS68i2^qhK7al!KZ_1@NOKbs1orm!0DR=>i5APZngM6n z*xKecGBYwVCI+y6PZ9$o<*~MQ;@Ov;s4g6N>HuKkP99gNXAheiWBTpjBkx{*%bNBcmI1G;;T`(yS0kggs>c{% zp&|niD@UZb(Oq;Df$iq(@p58fgVSVO(pP?7K*kpKw?SfY%= z!e#5)*t<)HftV2Nfe-^nYG% z9&5j1Dm7vce!s-+z<%$@os%r!O&KNn%nU597Mw#aE%kkiq`89|rCug^+ysU@oa)29&L2<0?#ZpDj+#Z_Ih52u?2C?7BmElT$v z_&|UO`kjeMwy&@6PZn%J@YvV+Tq{yTQNYlkHM?`L)h$AqSy1r3Cs1km_^Nxtv!&md zkx(D&w(Y9!zNc5qs9LsE?mQbgeo^n~zovsMMI2`W*(*Zs%6}v1jxWCcV!cp*t5RZH zODEEPNtrx>A=phnv|raI0gohn>F-_HJ@;#u&ZBIBkcg;lXlyJuCWh?EDX3rpP=Ngc z`hp@!U%HG$0{{Qmij|&M}_b$7;EbAqH3s$*BcsS_^p)6n=A} zpUiW5%Ncc=D#`yrRlxg>Z8ec%??&y)u@&1n^nRZU7+F^2AS)YX1f2x@J01Gtr=uam z0J1DO=w0ZEbX6Xr-V^m~oRs0AC?92n6E|r|b(iL}CH#GJj11Qs{L7LW394hyFH3vc zdJ6PJ(+(v6v?&^hTQrnvd;scOPb?nlZEOzkK=7sLp+xF+t9mT1Z#0M#*bHEiITs(n z<-4que?IN`qIhH(;a6C0sh~LuJcLG1vKyNf~-E;JwJ3a(;~}s;Uef z0@ngtK1AW|Gs*>)O5k69OHY3AN$UZ0-TL??D){ky|HD@0#3`iJ>~t_#f!S}I>Ofqj z9Ijuq0~Nt&W0oOpTEzc)WS?tL#7oN@y{P`|i5@uZkpb~Qz-2eiguKl*MSc9y=eE!; zgMRyvPpdoW^XI#I&eXY^DCT55{iJvSVH1VCHZrFeKmDmx+Pq?N1a-t{obJC~1I{{cW?e%xObk_ot{=Jt|i56fzyFQt&3Xk1%CZ zl^yxrsNtn4Kwcl%+M|vz2GtkR4%hzO%gqDG1OEH1eR53Sf4`G3!Py&o`j$Y}*pY4S z@vlJV{=SPqy&q)E9H?<=KTfRkSmW@gn38nh`u*8`(%;=^$v7?aa~&;Z`Xi;zd8U+U z33<2`Ka(`O#cQ*%_B%NVE}q}!X%9@XCl;Np#1ME|Q?)W}n~w1Ve|&T>Z96aHtj0?E zZ_-laW41Bd(fl>|PVZ@RY*Cbir0q>k9o?ay>90*9*6|;IDazhnPL;1&uL1rgO^29X zIl%{?W@STJl_M{8wcJF(M%hHAF(joG(_E6t-lTQcbA8M{o9^_;G3$J}Brfd#&w4Zn z6zR1SEn@oO;NYm#xmIQlR@%(1$R+H$x|QecD-|zP>mGc`HJu-5^D;lmE0f##Mms<% zXyc-;34ZbOQ7tP#2#Uxv3dYX-;+&$vfH#Qh%{>?oFJc`v4Dq3osHcGTU zz0wF*P*lvSs&bBR(a2aGz+_^ju#Mdsd#L_PHaU)~GzW3JNt{VNgVkgps?!QW>a46R zwyTlKhyOSrd?Q`f^d`UhtQ+RLWvMZz5A^-yG4HL?veNAPB=QdiQ#(7gs^qS3*6`)K zqQ2tSH_o+nY^8AD^__bSHg;MIaQexc*>}|vl%G9I%#=&tu38#0h##9<9k5jMJL%6E z_25YzMI76H-?ERl%*$)5mC5hOmATb>s%2wnVHjsjB!c`4EF#E5QfYf?yeP5RNnlkSCK#OI6AJ_DV%kPcIWFv3kq( zppD8?Xv_|w4!)54g&M@yd3E~>AAhn$$SWuyQ^PeL5xTT9lz&~^qUNQ+*6^vLgz#;L z%@yRlJSu~C$9>)1nRbh8^YgmYtw@PhB$Qd8URvKppS{$fy^BT@t%6HUIJF3(?g~%w z$^b!W@x31L{EX7l{=O8`d*I2kg-5T;YOTZ9ZG38p0@wotp`7&S_lO$76YL34?2bXak5sXE6yF=kYyezs zbhGNfczL+=)L2*DR$au}?_BrKs&amd+1!#Up2S&mL{RkBGUAdZ=>Ms|VzBs6h7=GZ~2RD-YQSxvRNcDqs}|>Xpn( z0j>I$k&%&7%gM)bBS9${w~iKS?T_qry~{2nhooH27u3A|A>D*}_I}H_i#Bq9>qg0o zR)w^(;BRxA!6Fn-jb2VsAk-aV^}j`QFBWCz*QrptZ3bs3a z%f&S9=b`3YY&vLj*(i-e+*e*E$b##SU%nU~a<-}Ut$D4?gjppHYSn*C99OVr+&?Z- zbXl3R7WEZ#E`82bs$abl#VZ91uzxnrlv%HhU}kPrGp1)i-<*I`>~afE$KHmwit5De z<#DBul4Rj3x9ZK7s7JLN79U+Z1q0nV2g$6yT#e$gGtO@ZEI@88jaJI}5o@MG1P%F- z%C?S-HdEb40!k3~~7#=b}w;;nILg6IpalAokcf5CUH@rQy%XPNbdGc+jvGH)^ zihS^0C^WhqESldAA=;R^Qe0QM=LFLo3MGhW;<{++C!~W-y?k1xFJGtz;q7#uL9FzF z2^=olru}_=%Eru}=lXg`o2rW1)DGQRh)v!w-7S_zai<2)U*;yOZsz&XZ6B(mGAd@Lj#z3+2u;g9lp+Oq=D*$e%-vEl5_dj(xir+x?QF@&ny+Iw=?BdGDk~ZwG?T# zQzOS2G@kd0!(W$cO%Um-Z1uxC#2y3@yvG5fIxl{XX1 z?kh&b+;OH9|3DUhIWhtt+IY%ytv-l%|26Q*Vt$>=tjdr;n9$8`y_KeYdTnXPQCd0> zX-7{Mo$i8r)uwx%XNK!hIc;Wkw)oc8R+DQE{H}T`R(AI2 z;pT1;X+=o&tkzXOA=W&c@NLq8iSG|1>hfZ_9iA2;!&J@Xjf^rgw{9JQPSZc+^uy@m z$%oMC?zs)n$;m7$hjw0%ss%zUHC6k*h8Wj-t1UY}E3@#~$!-h3?cujb>%rx!=}vA| z-F;h7EGR9xMFVSiG^^xJpB$s;NgLLwXg5GOGiWzbc(-ahVyKoeFf`zMU>bq3Ed~F^ z{yh@xdn7!4yWSTamcO_%P%%orhDr){G>=hL1D4&K5?{fEWbw_5G=_i z3Y%{av+|C6&xG%^Y^+*xY$j7437|0Y^XJFvmY)n}wq_Sz%--*GsB>$WQ4A1)3`}fnZA+eNxs>{+gf?&N zZU~^L#AfvL_6Fvzd;P#r$~-YXgZZma8nD6wc!D{~}1{C|NMJ!IadmSZ1qT zUuK$L%;w9bVOv!#VDYF>5;q`dU;H-Ojo&-DznG8MLTFA{EZ%2eP=MUUKB9hHMnNHT zcz76UB+ehrvhQRk>12$Wry-hO-d%TpU^{=sZCAU)JrHU-)Sa3LA7LjW?9qv>`-wc= zCtlbL(hk3a9sxx$=a)Kyg0I7vG|lhXuZ&h65YU2bo|}E#pR>O*$Y*u`MpbE1qH2Bi zavv|VuU+%^Q4IuQa1e6hI$TNsk)l*iYv$$Rpv9$4qYmJY4^p%p-7a&uO6p4TIJ^%- ze{!$@>Lu!5j$<>+x_o(E(oFYT#6vE~4N5doxL52AUcK`qqoU#~P!CiFS6Fyr(woRu3K!k;?_ zcKgU;TlgbUZo@^Mc94YaBz1AhDu|AAXYSx{E3se|)seow5}WuIGqz}JYwK$&=@YAn zk907Tu<%fF+p2}SFG}+A5uJ@sff(>WX3=Qpz`}`hZsqr}K7KJ$<5c|6`sddaGp(7n z(5l1rc2yl>EnR4yU46-rY4s}SR z#|x{cSwd4Z(s3z-_p>BgP`2{b^*=Gyp`oKs$r;GlK)T&w{CT#FH0@Ys!);h<-86}? z-qya=)5!>Uz(C^bA~K`NNlA}E>sq!OD(>Q|?wZJ*tROnceqMRv__Q+r2$`_B%r~i~ z9_o^)5v`i|IL+nMH3>uwF562+u{>kFVbVW59JXSs1uPgbsVgEE^E*tX`n&BiLGJE^ zWUTRgKr6B72i-Z5i~gk-N8~5Sdv&9^N*!zV=(PW=%`7BXCcjz@5B24AM3)1;rgGmU z^K8^cybJbznEM;bgM>(*Csbr{#)Po_evC&SKN4kURLI1V$D)dGT}0BkxVb<-?u{Kz z&?_JL+1@VKu&Q)3D4oY6jtuvSH&it~~6`G4~|jB`zkC$55CpE}UeKDtYt*}r;wW6w&6K1Y+K64$+T zjc`EO)s3B>XT!J7Hl0<9Uq_FB^VuRIUrA3dHFFRXi^y>5i;q~>U;m6YCd>6|iU#W{ z-p`^!cZC7ld&btad*;=QHx^gr%rlG3M(oAc7{ld)-whd{vescO(_%N#%O#L>{rYuW zN4asD4ghb9ms1P<*;@J|L&`dop7g#qS0Q z+L@9oOk&-lLQ>&-H}IGX@%CPNsuAt~nNx#S(B|2up<;vVw6tc~=&O9`VV$%Cp$fB8 ztK4A36pL63xl0a6|3Cl;FG0fa(VuNjD zMF0JZ5B`peE8-G?ZkpTFU@-X^Q zUcAz7^fDSO&<;rf8qe$uRij%gQLNA>b0EJ4O^oF$(6oDEPoD!GM&R+IJcxCjHfD`J zy~3>Hw2fRMSk!9KM=z~+pV>Ng*z@*ZP^dV;87l~~vHR^Miwq7l=JHAA?6w)>`> zo+;G+3BOH~iXC1oGKhDxuWy0sz16Dy1q&z!pN~IrRfjUz5d$X?k#ta)^J=%bz}h<^ zZJc|o(dr+z#>IO=OC8m#b=mCWu5x2zW6lT5<)EP3{tOmr(=SFsKBTuFp_UBlQ`_Q} zaofWd!{HJmv5wPHdYDN9KTINt5O&J>*C%fli}B|wrN*I9;+K?_#cu>vu^}no51{zO zhSmD#CCPX`btq#rfm#8mqC-ldy9vV7?~2Qfin`vu%w{o^M0j6u>8QFCF1nOkOwi1N zC=@~kxt~AbD=J(HA;k3c_m>FeFp6g;KG$|emi9@UDs8tp4C`#vkd3*)izHM~}6&pcj zw|w0BgJPcRvypNH7$#S)+Fp`*?G`l@rlFD$kSZm?PUA)kPZ%K0OC0@yEesOFBAxTX zje`zUK1RK1#-kNhkOa9W)>C0MjmkpQwpSLQ+kPd2;>r5dT}S$~F8A%?v}xV$jLz~a zlz`&4D%@jN{DpqnR!X!O=uoboJ0rgKXZNu$Jb#uD0R=5CF5W-}Q^qjg5vy-HjoJ1x zgrumNR~lJ7(}AkF;Suhi8+$!bXqR%+rS{inEU3!ghsrRwhKOkcitwJ_5+(F2%b<%z z5YC{QHq#!yQ5XM+5awbiq?K+ggKt_O_d=*MveS{=hPBWKxBhXf}DTxw#wKwXubB<@% z4mLi<$6IiXKfpGd&@kX~SCT>@1J>HWz83E|>ZZg$01*)Y*F=oXj9AH6Ex8E&R2Eq%EUC5@bWLM%F9sWT>;YZRDk{mZ$+6O1(&#Day z+DiD~^1@dyK1+I>8ffFghy4xRbRvAWGn{lJ0WY%9-_%hOZ{R3siEsBDXc&y*BLcHu zEB7U^7Blb{WAN^(4y9SxND9#P4 z-nC)g;!kL2uDblX-!XfSs)zc<{;#ih@Qem>dL>%e**$VvC=Y6pj^QJz@7_+Sih&2e z?A@3)?dRtwIe}4qzfKhH%|r*JZm3 z*b7{@2ly7bcq?S(L=075;&2Y01dt^{7PlL&y0n{@g97sBu$+D`QW+qiHFgM|LS2Q~oi>2XwAd%D zbZo)4_KnPvl8;8Qs2JuyFVWzfdorVqt2^zhJF4d4gDiFEAb#`Tt-jY66$z}#9PbTh zK^6sGHw8O5j+KX&fg${-CAQVz3I>qg~42(;NDqODtNzOfJYQuyVTrFhnaz}Z+G@Qy?Ar6G$kmr{CfWS=9r31xbH zF1}#4$U*OrkZU0Di=Sc=s#o-@mGuV}!A=CbMH~^m^7qA}(|BcdL)pwMcU-Mj#Y>x( z;4&0oLMf1V2o#&Zib_cZK^nB)>MSWcOL}6Uftb zzy%ef4?b?YV~u!F9;#ye4+NqI7R}3{lgY`*_}-T(=c2y7RNS?)GYGZJ3B{dU;wX<} zvt?X+a(uvb_^a`*7*u?rDvASQ*`PwUlAs>Ff<=l@1Pf8QWD7iK$}IGcy5f=TWKfLU zefM?n~SRt z9R}z0XDcm^v6|SfaL$Q_P&n^ulk++irAbCpL(z6o(IdEZXPb`7x&G(X;Q0`Gh|kRG zX$!p%=-D?kLIM@6&{S;F;-X-AD{! z|F^bI%BjYTFwV*5v4G_h*jJqG0<+?92*g4oCbIT{fAbJnR zrxp!itJ#UmtDC(p8T&}MQX@Z2GPaGS3-w`7_cbWeHk@wuPt)n*oFl8WpOE;iUO01u zYY!HEG#%?Jl!UThT~?ZUerYHR3bQsIH#$~(Ma3B-)s!@Q5M;C#8PTh?{JMQvmY#^Y z9>@Dm@)Yw!n*AWowU+`70BhhB4b)JWro1c&1w*O3P|gKHdtgO4IM~9BD zHx6OS5eB>+CGwwMq~tSdAg1k%<5dN#4;wKXE)l!0m@|0bpsE@T)?Oz4Z9>x-s;87? z1YV-D<`@Z@Im(5Pp}vcmklUa$rWVryi}=`Mdxei{rMeFP$l%HK=L4_xTwY<7eP{@o zD!nEc`X)&0vJXD~d!d&Uoj7kRp5UIDVo6l1@Xo{2t2QvI+Eim?$aKn})3G}HvfWod zcws-K^Og)7%lK5vW$RwQPY-=^WA(3b&wq;RZalj4R=6K5~bh zi|pE7^2F+_EztzKC#^VQ5^hyd=w57 zZqie(ha;3d#FyWG*@G;450kup@%=mT9$Z#@a^XHYfB9ukV*j<#&)?W)DlUdq0gFOw z^eny4H52R8%r_3fnS+naa?8wp{ryeVa6R+O-n(}e9tR_Lk1U3F64%{s-*%sKaHm;V zT*RM)Ydfp)Ys_279QA58h)!cTJm3b$?qdD%;+H+;n-kuZ_Fj<7{Q@#-^A{&rV#hkC z`UK^?a=0_OR#sli@Qf|=sX{G^A^NqCOdM}JHr>~FI8(|5?)ff*+$p|)6ZW(J`yo9A zh=ULO#t&!NTL1vkYV6_4oyzap$Jtup+62eEuAs^{y{{bDeB?jVQXi1x6R(({)vgn;`4luS!R!`yu7t* z9Tx7q5JV_`3WF|BUk~aTsxX^gzI-{qvLf|y46;4Xi3w<^sgIZQyN+ml)EJ51K7MG0 zkf6qI(qY{weMTQZeY#b%vuTD#Ms%6@e|o~O=}J0o?kyka5ieiyPBhF6Xl$Wy;zg2;>gXZUj1XQtZC z9x(@ISdyt3bJ{<(0G@9X(&xq>rP(WR^5bVA=whW>mMLpWjaTsm9<93XR2x*E)#E_i zI9n66zrPRLl(S%f+P{8Ok9Te}RxcH09a^SjFZvnK^9Q_-@l6$9q^X^~ibhFPLkxO* zEbG4?`ixaOh&VXxd_=789X_9PFLdQ#V2Y&&CzqDm^_b9LO&2Z}8cYk+U2&tieD!Lfwv&1dmnw02o+=T89Wrb4RAr!T zN>Z13PpmBDdh2AXe#M9XsP}{$wX^((-hoXt{ChNoI!)`o+u-K4w6Bwpa4a%)@J@h% zQ!~(xJGfGryUa$I+kSy%~Wzne}fIb5bn`$`<4@H&nZJk#vb7u?IhvcB(>wb5Qj!xBwVP2}_rM0kjp2xhh<83dKEAbc$ilW- zV)RNiNE9R}YwwJe^KUOz-hTp0NC(i^=7C)H=GhKJoE1ZOyKth6#9?Hl1hsFI@vKR* za?CN$9GA_w(@;i!zH|(~-GV&NmVBMDTU+FsTZU`AwLa1G&KV5P%FI#jyKx;}gm#6n z;jO1@hf&=0N(U1M53ePT*FjiwBDs5DJL}y$$K#GivYB(o&cA-#DKzL(FSMFgFc=lH z8Yx@uM(h|)buG^u2FAsWXZ^P^Y%lFutJ!q)`)uIx?YQy3HmI zsIJ7u#y+$bdl>3#XlnZ2ZgHS#dwJC#5()J`k`rJ-l?UVM-#N0etM`$qdtbbRtgTdC z=&|Y*?wIStN!!Rj+0RFTvd@ODZt9pn1!^SEy{=a}gmB4r;yqk@+W4@NG&rz*V{I$n z!;Z}awMFf0X2S&Dc$ADrv#*+m2knH}#wR||pHw1VOuu?^GAzC2`r}-Am}`p*sy7TG zVh`D8!m+UzC+^^`PHG4DVk>Eu|g+0d^hf<_yCssn6aewmF-P3I4j?Dfh` z1oKx@kvr6E&ve(NX*VCBPc_EjJuF`ZxUO~$sFNQcWJY$jA9(%d^%;g@b8w}fAX@D8G`14|M^(m1m>T`t>H_`qA}SyzcS56P?0T&T|p zo;!E0du%M0wpy<}Obp9+hn&)9grcnl&ZJl+3KNfC2Jf~>UzqN^UsSkvS3KRd{{Q0h zr?Ep(xF z%?FT^FL(F$M&Ep{QCDi`wz)(3G=|Bbne^U7dJL(-?}J8a|1aS4%!DOL09c08&^%Z? zm&akZuvs#Mq8+)a7Vo{hm`{G8uqds_d27KC^sn{dI=2IAH@Bn*6x^^rJ*ytfVSJ9O zC9B-l{i@S<#4XHT&~tl_ zTbVuLxyiW)6jD!h-GWOD6?1Gyzr6Y1dmOfS#GuK+gY3F+ZiV%4FAtGfwx=ddlrHRW zvFZ5ucz$8w>Br@zrT0)#uIbLp!$YR4+sj{7nbw>f4NW85(p#wYt4|HL;Oqa+3Ymxr zR;w*MmWFJU-ovkL;g(ZXy`fq@P7=+o>C#;K$7D7-+n>0(xlOrdQd3h;fv*W=`Ow-2 zj`e8bb?Y9u+19Sn(NO~U-92~hV5A=sHx&Dtj;HV3?Lrw5tXIwa@&ty<92W_Ns)rV{hC(Bs=M~Z9rj$^dk{Cm44!JrsKs%n z{}w9ijk_6X^E7I?KtxTeDYKZU6VnXz_ive>H!La33)DQ>@|zOjUx>F}nevOT9+{e- zpU2|6jAD#!Ylp&LiYt*xv-4a$Bx0*CCuG9|q8W|((#=s1je&vgI!xEql?OthCOr3F zcyb!jsj|=H`U_V%c;YW7LyB$^?GnL`OnuSyh1HaVi%V8S(`(N{V`UqBAF?{pAH0c)l4$??%c zF0ShcO^+i}rBi$7$i}Qpi1-3qnOt4%(q;mi*?e%iI`DVH<01$gbSda>Td3K&2f!i7%(Oo5D~HkAvH1l4L}WS3^>ds|}EQ!?Z*q_;c-%bft1OHgYAP|Mk(G z$Q$w7WMt<07k2+Nh%ni!9Bd_>HE?INxAxkLjQ8ov=y;*y>Po+Nfav=&sJ!mV$!xl&(S}A?dD(FBkbNO{QE=!)EHv^0GXpVp8Y{ z3*0e#OCuhC2#4lEy-V1}Y8KkYQPb@WATR&Y8A~Y{LrF;)2)P>?E56%FAUZ(Kb;^}3 zngL17R6GT@$ zAYgkQiOf~`FLwqS9#ab|LM@i#IWMEh!pbX!j+kCr?N}B%1=ji#NrF0{_xw4AYx_bYu#S^!hpLdx8 zEZi1P{85FEXkK*MBSuyyIYD+tYU*8x!HA#;?U|AiF_cdF&$O$a(y-HZ^0Ao0@RRZv zXXh1$)BR0!j_pC(jvjwf&E7snw|b!I_~kcKhJVXgtt9*}>b?W4$$M=-ZBOfWToe}| z3M~#CAS%ixv31}C6lE_(0RcgVY!X_FED;q2k)@)dB3t$dmL&p-fXI|68yO*l6%vyF z^S*CTu-4-_?fI_n&vmsIktFZ?{>C%z`+lCE!Z)E(dW+y|uk5dKUJU=Z?EFV=ZC_H9 z)Wx#Ivgjaim?Kf^cI_&@(0PvW&c>)E$5!vjOO}@!`rU7Q{w!XS`ue{UFHtmEFqs%4 zg#}Uv)2W&|VgASBwbxK!Mhi~>rtmB5gTt^+k#*CYNp@-Ke|kQ+7V(-jf$P=Aaw5;7>F8a0{6+dG{>Q~pc`U3*RpT2v)Jck0xqR5urQ>}hE_(_?hOsI zoA!bg;r17vkHhkw8Al;$<#YZY?l)O9B)`4dkeexKj|A?^L}9Ii=JtEU?<31PPCY7G zF86rRnv`>WLDetLc8Pbv+jgvZJljdeth-ot$#*zqgiX76PoPzKfPKku^wq?(8qpK& zk0y2B+GEbYP!AH2$4qX(udEV%@dr}QV=88Z zmig|^ywyOXiG!#0PX*4bx~a*%v=1T;a2+Sko?Ry)0VJ|n-J@gGFJB&I6u|cnc>;NN z=HS7D#l^+DN?MsCx}B|<(BX$=?Z37a7VdCzagls(3u>*JU)v@oTs^y$X+bc_uKg)I z8K~adwF_8d-OR!I*t9fRD25o-YJDmp0fH|iDQ(#vQobuix61R(lE7Gh=FFA0STM!B z>fPRZN7huq+}yk75m%hnn0#l`n7H_QH_VQ`u>p*rP3Dimd3$?%b#tyfe&n`5*+Z=m zagTHT4Jk-Ys50?}Pz(x(hn9A3DMv?R=e^6-5G()4W!@Fr>o2F=&% z#|D~RO08)uii@PQ?kqMSJ;-of=Hl*4AVB%M>*vHSWAvtf8aa2N}LA`WfXwHaDJp^9x z)Ah@@nYVNY7fHbHLy@65PW>&(d5;_OJr?6vxnDIpMxp-0;)ZDCaa$~i`wm_#`yGi_ zOo{qu=LH=0SyKX%vS;Qxr731*?GQExLvNl^WI&RLqZ?uL6J4fk=R=6rTN}4Z0*a6J zXla@4MvI1#%i{_?Q-2Uz64H?G;R5?c!%aGdsxj#f8!pB6^~Sb_l=dxvN20U0W$V^O zf`U7D?j(CkOPqL}V-gG|_gFdszU1iskD&6q_3Fz?RTp6>uR;-mKCWLTNQHuIC@N5H ze>#Wvqk5FmQbEBujhIWwFmi{h;@+aN$Ds>T^bvcu5M@$ z23yK#Fyk#^acTiquSx{0$yg9zu+80l-FrDfLoX^5L`SlG4UkZNonPR1qW7L z-(RJRbT@c#t=4RDnh_Qs-)INa;03(9|1~?4QJ2)Z*bMS`b89QBHY2*bg-zq|ec8|@ z&{PV+wqqiYNoFCnbA%20^r>{8f`5--12(c!b<); zg1l#uyB4_wZu2~t21wAg<^zHY?ixvqi1cyiVhaMB1;sIGM#xib_%rAaF^HITJpN-O za<6Ylj`PlMI1L66NWM!Ad8{08+4g-2nY$qLo?sGqq!SPtq#0pgEpi8so7N({?W^pY zcd``lTjkcf@Cx^~5H>F|VU?S z^6A|mC~M=uI#*$Jr0|#S``pX>UD_?(pL(5?pihtl(7|}lTb^~3&F!=3KSVj}fD^@a z#eGCYs=J@zF|HsX@@X1#;+ZZ`FNQ5sIYPV3nl8vD+BIjWPELv)YDtNWRfP^Ji&s}v zK$;!QRT6w1+liGa=;SqfCptS4qq=a}V%n(44%jbu`gs&#vNzhK47N z5JkAw=eCM0SfE7{MB8^@#JLU5Rg9F0SXk)5h?a z_(qjMWV6BNq~Y7I?Z0=TB2>Oav~}phjT^$GUu=|?FAsI^N5&xV=Pv{!A4tJBh3>z1 zCxua|rg{AYy)_zT5s~%Qsr-p(S+>yeD*Vm+5!-n1Xu0g1;kfu3EN#3YvJ5Hh@qVPN zDz~K>C_v-_<%LqaCB5>GyRAjy z)7~k0DQct^;;SKY0HccpAJ4~TqG_@Jq-CO(;-#nhYupV{;BDIdC8G~U$}CaWNk?~! zY}v0!n4)==PuCr|nSCoo&e`Zn(D?Z33ew>A#;jY_!P2;8zaqKwbsbwE`_34d)Zvk< zR<0oQBGHz4@oWO2UCTW6kD!^R9`@)Wj{goKHh1qzXv5R?`#hP*0VL64)DzqyWf@oE#~^>7ka75)G?hEs*`D!zIoNsk|CB3`6{04aS6Kz8qk*dKZzykvlf9FluL^-wT;8j?x~2K~`60%l z08Ft5o5eF}Ty}M9!J5IWc0$>3XT>UswvKWOC?MlW*yawLXP9s+Rw6Qs?KQn4BJ|ud z&0`1@Y+r@}DTgjg$;=Rvz}07iC50Rd^kHuZ&g41i7wZeyujwUcGQBp#)3n|8U0BR+ zb*Z?EBywQdML}kv9GjA|C6UYxI@Y%k9rbGzbTMu2MuO8YGUs|vkE%JODQ5^V#w!pvmH)B7v55F?%T39Wg5#Cnc4{x-bNwPxC=6&wDGYsmK@yYkG3P!rJQheU8f$YAc&|Uis>B60!B)(mkI;`?E<_ZGeJhn z*X;itC+v{v{G~P>T?OF-joL;Xjc)XwnC@EJcI;_Ss!wG?)ch8~g4kk|6M!mk6v7!lk|> znxRh@dRK+n$!K&_xer`ghK(DVwH1uqOU&xMKMvWl*4-ly72Jj!6?mL$) z>$9mx-()K2FbBb5v7cLQn32X_E$v1%KZSYMv9OI|@c}5`W?vBbAx7I572tE?q}5iz z#s8dRB_VOHtAZ6byvED+(3vwAgVypqw$u;HGDNB>LU$V(-A8#g93p){Jo09{Gc=;3 z3TJ4QKNF*P4bo@8Mh728ec*K0o{(5uDse(Z4}Tr+_>(}9Qc@HcmHx%7n@vr^qS6EN?@=n# zIfnh)gs7Tir_+!xqV!n7U5+7}tt3Pi2ppYX5hlsw75n)?Pi{)KtkiGx^Rks>Ks3kl zZ1%Bk-+rsGee02Q^}tc~=6WT?o#%$RZl`TMFUVE~QFSj`=pG@jhJbld_g6?PjSfP( z7rTlvR200L;^Oo~O+&-3jq`!(TCw8d#-x@T3gUv*@3p1w7mhIRjjgvZ|1t9Td!8kR zN?1AWIUov_D(B#m1G)u4eu&-!x;H4qRGF`e(csQWY3zUgtUE?M(&fV4sQt=C2Ta_L zb6y!JFX~pipw>2+OWzkMK=b{LRpN3XXU#drF9I!*a9w+*j}Uj{GSg@c&)R%C%FXC5dj17gYgnW6!1MZ-uSy#%hh@508+Xo+3SHVBR0ptR-wwQI$Xl=k6sl*Git1GGbvX50s=OR_yBbW%_7PE+|SH*4zot>Z&*m5bZP5!G^qKf4h}qW zAg(={qyA}Ey>}sS?D3+l8cb7!pamxvP zG;hUIGk}NTif>C|xFdT#-_9e60N7hgxqGA+flgeR5ws<}BOSg6I3KFU>+8ct&`hha5pxJ#&~$f}kXhY*;DE`bL(92(oyGa%1Rj%6)){8991(a+ z<`;ZEBblY0@)+|}Ow8_jcNLGu6$(Hh!!s5}KAEXRqPU(pd2%(wLnyFBc%}4!I#Rj< z^L@JJpJ){?lLAZyQ2DkQ5bncI;T?}-2ZhIfps9p3#gE!m|d3s1^%7*7r2+T@Z zM(cP1fy;^!kN+9-TyK0()f}$t@oE4BnZ=7Ww4b1!5~sPGKTxSqCaK^#akkvC*J*=2 z=yI*zhh+svSOfYylkv=S|3OxJ{>O&U`8N0r<8HbU)5q3#Tb$NFTiMTH~ zK-vO(6Rs-+TEwe>E&;Kprb_H_daxIJtjZZ1$XmN+ZOm!2D+|qo5cUpp#oDqaq9tvX zZJ-tT7ykCBGWjlX-?r`BQRWz|^FOeGxdW=Z*?zHZI3b}gmdw-Sf9v$pD`tV+$?CSI z?TrMBeMk5AHmhB`0Dyb1hT%~j{S?!+&+qbo5M z^6OK9<%D+x&4WK~efIKyA~gSTf8%fKME~bZdC3OdpO5b@v~{lEa%9d*y|MJ18csvL z#-@Co^wlKlL?vaA(l=^j(Hi53H&Ooaq$_m=+|d3wtdbqMIovgM)H(5-sD4m8b(Z|;t8(ng4xF?jc z(vw9fmu>44lZpdnRt}6~l+rg;nLqt@e!yL5xovs1O~zHGUg+-lx?InM(2_)>+^fu# z?<|Bx8kfb!#`-uvPwMa)E~>L~Y8qG&0h|4t~iY7_*tEjaHE{{%rbER7+gsCSTsQpWgh0Rsjyos9XpWTpA@xFtBP{{ANzkSGc z2FB6ZINuL-HVYewJOl*ux`(Zvo2DI2U~<&U^NBV$qbT zX(gqgw&bO?DkaIMbpTr7E|Dp4dSX$J8Z^`PVRScPU+~f5z`X6|&C7%KY>PT8Dh{oz}CdVpo>J=512r?hTXLjvM z&<-?D3y(~y@4M3N=D>XzCs5p)AH1vyRTnoH{x@gnKiYlQeSCcC7z_rH4z@V?M}Wgh zfB`?c;d(Ts@P~+qh(PDul_4P^Q^pvey!S~~R*%q(O*%Yllg5vEAST^Ay~c9eokp8A z-Dy&R+VNp5t0(#c$oQRiy>R8q8PEypTgGwr8?Pf6ChUoeB3}4tGLl=dW%Z4jdDmHJ z!h=^NsH!eaON(<4jk(bv%47T#)+q=a_O@b%kN zs1noGhE6+~^Im7po}-ib+#MaPx(-k6iaW<{;Y6*^UWkjvfA2Al*Pp)fECt%X=Rk(; zy-d}=?U`2B--uy!kH!BJpEGR$ZN4t*HSt+F9Hoa$hxaeH(5Wa4)AD~XKdvkue-$;8 z!vBL`fCMDpmG<{58y(Dl)y~n^4OV^)=h>_?_UyGJW5Ca?UD0tLAgzylCYG^%6I*S$ zE3I)q#X@gcg0>8^&N98JoMj7a9mgvtyfHgX%pk*NAH_u}Dr=09-oZiVFGY4qRPQ-% zwDfo}2!gIMky|aC#4N=8i{ar#_Jb{~4$jEP(Mn46J3Zow6LytUlYMe}IN7fW6ySe~G* ztVpZ6D0__zm1~2q1@_!KvVL1yR+ccF0JZ0cGpIkJfrMy)3J2*VT9*B)M3S>AD;f+-U9f^$`zL!yD5_0adB}coX3t*hr!XB5xFNE3L-=- z){$cT`~rn!il05(dpjJMl~U-}dh?nWhf&rJ=ZA8;jY;%;rv2D!(xC#2S(~j`RPbuAyNg8{N))AA?#3I>z!@PO(;z2q$)e4);bf><) zKByT}9vt1E8uiOha`N&*1J258B_-MUbCDawUADBh-*RCxALCAte@SLxCJ*@?hr9Q$ z{2LY@C=?0B*QGY3TkC*3YHLc@xKpc6C_0;-lQ=9WI2tvIg=-Ca(cAX^1&VYI8fFc} ze`Y&gl=Xy!qChN8gSr-IZK$fZsLq@Aad|tqzdU2cm$M#2oVw$mN)l})VV9OYN6bp$ zo>>6vUk|VU`gZ;Acsr*)4vWd)vgwkiV!Xy0pQQrn$BzuzCuiHufWd8BQ>6jopEq#L zqu{gFq(#FG)@W9U?8sV^s#IOQ-n%9wR|Tc05r|#-q{(6~O;Q%H zbv=-It<@kHxmYyJ=ZU#{U4TL_;pM|@V73Y;Z=(*uMi)`00gb)pl)wswp%|asX{*aV zIGqN}h%9%z{M+Gwo0Y=O6Rjdg6n5?>w#U3BlSauUAPQGjG7`DNon1gz) zBJOEg)t(TUB1nk_MQs+c|e=lH0(TjnIvSYU*C&ck160glKu?>rC7@T*N+RWhOOP3Gd zy1uEH1nJyz7|4PF59ss#_9h*3me{6@D1?4^?Xc;mjIn>7;9-9deI-DeD1w;j;B#A0 z-E;$Niu~|`(JVCi_yE|6vHr$dI#TiiH`)B)3qr6Cll_=on6&$&mB7N2`50p3cZCF3otvs zGuM;l0Epw(^=v>JTaIXQ$_`X8+Fh7gPg=6qj58}L7|4GvyfHmam3$xLr4BuRV3fbo zjXsLDF>BP{q8BV}kg+5ObY0nGc;u)$2C&v+`G{Fu1(TqOtNLm z=*_TDWd=uPxqVx3!J=A^L3Rs!jsT_DXC8TftG&DX26GFIHLG(gG!FI$u~>m0q7gS{ zl|0m%#jJBeGeGb3``BKX3&pUeAgeXY^rBaW%Vu)C60#SmwN|yal347l@i2PJXif!b zD1V~DgYpUCXuPP!p(_& za{!_4aX8VaB($H`H{CX^QYuVpP=snDmb=Jp#G>ZM&?0`^c>V$}u16@e66ks7&U=}4 z*tN?hk-vm@W2>mI3F#=IYh)BuS65e)=$59{nvPz=yBQn9SNXQ2^$hi~fd?fm_d0(E z88!Uuz=Bg#Ekv9RGdY|=?{st7=>&hm&Ilk@(Ab0204U<479fXDz|Uq&%oQAJCodDE zcc_8*kRgB%bZ$GRX1$XU>#J7q(stGx7n}h|o&o1#FS+SvX}#T;ZLZ2aAt%ktB%1{L zW=slW4;(O5u7rI1<$~Pqf{9>p@r&fid^njc+oAd3RP^nMJ_1Mo;6Q<0)i}C+yn`^v zMp&2N+HcK}B(s$nO-Y2HG&k8zhSngMDqvePg50Gq;d4~?Snr%NMiVNW+}-DJP}4gQ z-jNYduHiD2<|8844cGT;SfF=}GhL-;XgHsMI%S&;AUU^(Gc);48u!ho(-)nfJ*#e3 zX*=L6QZ3Wn!;+>Q>Z>>NSFLJ3;pFt>g*xkco+dF%KS(_{|2VVHKF*e+Nz;?LhAwnX z6fep;KW%kC#JaSCq_W=HGz48aKgXi&cOR2co48eK#(p}+ZicDeUZ96a%V3)8whI1_qVgjx*m1$SzD zi!%#GU2li``{%1RqYsZ8Ed5u|i?{NPD6hD{hxP7}CiC)}PxJEVgR2}S?-?xfH z4fOz7?;()G7RRCRdf8waaU=XHqtsgQ31Y4|cK@@?S7V8Rj_ zyOzGT8(E8cF`y4yqaVRb|M#GPy+99t6tB*I{AEzU?7bA8v?sn!9a246zfS>~y%y_k ziZ>RhTBSdJp^lDCK4!(w&XJY%ZEwkDma}?$AKr*ktxE$@XzPs_@(n=T%)h6e?RYki z@qD9d)8d7bbRJ8dH2> z@}Z-rtE;|9J9&u)j z6EhR)&aom3A!DeU^l6;(evkTlYnEWXG4-v~iS72L3KAP)NQ(aojZr@QrzY-0IK{j_d!qJ0iz{@Uj8Q<3P|vo=`#pU;~2_G1-R zKEqYoX_(*?_dy+qU@i#TaQ6bYm!6V?bAZo0zrz2hw2v z2F$E0|B*D9ku4yRouHtQjIrO9D_4G&h3-p1IwoG**Rve@1H~aZ31 zR8>{&&V7BUyu6&4gyk~dSpPAU|8&Cdz~!)9c~j#dsfef%Qc6KVY#|JLrOw8>F4{N3&U<(oMW{A`nuFgIUV2Ip&q&}Bb?jVtVAv7Ka@aLi?K zhz9;jB$XM@7&9Oopjf0!>3{n?lR>K3`JPu|e$ARAK}}lQ9rfcmNs9>ySdXe^0;Q5M zcf0i10hgORMN05RWEK_RhY;ZfIN`2*WYF`ulYKsOH>1;D zI4~W+gVa^MpGM}v-=WDjf6r_FdYdSNtqk9XBU)T|3b zfo;FPs>j%f2Sywm2z`b8uds_x|L+Koi3x5m z3zj@3uu^FWG%?G}8{6l&#+W@CXD?@0>SJ96MSm_N>4L*aCDm$~WtLUrKcTnw1C}oQ z?j04eN|$mTXu6I7yrxXd_k33aMYSuGoO&|oD+xpu zsK`54VeJSv!7|x4=w5Z8BFdF36r{jVGx6_L9rqfX;s@Mo=nB}PU3B$z=SOz!HPmJ! zix&f;Q6P1icpI6V&mQwqRgZ~2glKN2!MSgGArrb-2B*Sg(4!O`yF$rH+jZKW<+`=7 zWk}-V+~KHPV;7b{fe^`!F3`p>GC1MO?;W$b5OX&Lh2{79?A@{#8zhky73tvftetx% zC1DsB+f8+)DGc|FZEwcJy01h{+K~`@;%f`0`P*=kZA*XoCUk0(4^Ln@e61VgmnSTH zn6wHNDBaPiXUCNW{Vr?ai2fNUfd~wSc<9M)rd@*E5>ia*ft&Kmok(9J`1#HUdqb}i z`+&bos-2oNB<4a`b(r^0{55+QsgMA@wjJ9zx;vATPv<^%{fWWtKQMr00HT;t-JHy| z7G$UsM~3#U;Jrz+lr(mEBDaL#?%Hu+02541zfp6HP7@dR9Qx^YxNnAbdpax_8S~m< z5}Q5hY8fAlNi2nJ@avK9-#heLb-aYcnK0$l(N)D*Ro9!%-;K{NG2y+fKVdcQWnF+u zi*S$Su?_7{9BQbCezfB*ZRsYY|U$g_o1Z#aDp5u0;pn@x0IN zF!U{jdr|>YFQ~zGIPy=|C|FQ3c!Eg8UlJ!oUsHwiK%nHJWw=SQYH9Fq=;NCHfZ3y# z5)hELca(?hYlPzlxLyiZ^=+4tc4>o6)mAL-wdVeK%Xs#PT#L(DCfs3C32#E2mu3MwElq@yEW%BD*(clIJU*)60-=EtZV$z-Q|7=x#XJz2k$utG(BS`!#UQwspXDGW=7)E!RK;u$~Cb%nEDo~8CX$|6+@R&~5X=d0etESH~4 zjjXa8JBfzmxSlY+?@4ZK>3=-tfq^DH%Gh*V9cVsm5Q6H^aJp0#Wl(qD+O^A9(X`?50(RPs+$V-TlK}HfBRtcL_Ug%`-NnkR z>Y`Qlob%K>QLeA6n>0B+Z?DLti=yj#dc(M+ka*k)I9XwCmCBR!Ij;UC+F(q7U-{YrC#9%~p4eb6bMzX@kOCz1 zKg)!KigZR0-!=CJXbNO4DAUeVcYIdB@8*ouLGRcHCozcA$vol_IKLq#NU8$LgE1Dg zK;z#PdH|0dtgKj6TB)|{WV)16l=`IV1>gE(MCrj4D5m9cXj*VZ(<%N^Er%-ic2M~5 zYy4);!eY?k?%Fj?z0oZGc09t#@xq*Uu|5G+%Fg|M!31uW1?$f4K3nsE!I3g(B?iK3 z0U=a6qRS7M)&M5o-3G@qW)FBIk-6@-zecJK3VFxrmrnFQqAUNx8?4N)HGygdm%HvC+-?U-i$_@uHA0of zi=Yn4B&@4O)1}kfmIED`aT4CcaYyBXtyaXjX z*)%is!#hkccX6#FEoRCFDLz`SjK>?ZP=Ocjg$8y%YZSrHuTVI9i~p&@9S;&7KW@1Z z9X&X{0={SG=`&}f@87=<(v)NF-wCe($e?<_IV9#923gC;LJ%O_JC2o1BiAh)YhQ{! z$Qp#QjEi>Pu-*fl!i}h?1W#;edgfqeYSC1W8X*80S4f^Bu*x;KcOeMmWi0{&uY(*u zM0dNdE$TlFq_ml4aLRJG0#%Nj00y@UoT$j237@r&u+N@|QBs-5WWy0j

    wYSyzyF|=w6rAlm9Aak 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 AG5`Po diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_select_center_details_tree.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_select_center_details_tree.png index 8575c84d77be6c94452c5a427bca4c2fc8fabcf1..e259f55a051034f251b19cfad58ca3de212c8f8e 100644 GIT binary patch literal 45504 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