From a4869bf41adbb3e6f325126e62789cb5a47eca1a Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 1 May 2023 11:45:33 +0200 Subject: [PATCH 01/35] #625 option to set the Tags page as home --- CHANGELOG.md | 4 ++ lib/model/settings/enums/home_page.dart | 3 ++ lib/view/src/settings/enums.dart | 2 + .../common/behaviour/pop/tv_navigation.dart | 25 ++++++------ lib/widgets/home_page.dart | 40 ++++++------------- lib/widgets/navigation/tv_rail.dart | 19 +++++---- .../aves_model/lib/src/settings/enums.dart | 2 +- 7 files changed, 47 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11ac2cb77..fb35625fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- option to set the Tags page as home + ## [v1.8.6] - 2023-04-30 ### Added diff --git a/lib/model/settings/enums/home_page.dart b/lib/model/settings/enums/home_page.dart index 5adb6788b..cf33a0fc4 100644 --- a/lib/model/settings/enums/home_page.dart +++ b/lib/model/settings/enums/home_page.dart @@ -1,5 +1,6 @@ import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/filter_grids/albums_page.dart'; +import 'package:aves/widgets/filter_grids/tags_page.dart'; import 'package:aves_model/aves_model.dart'; extension ExtraHomePageSetting on HomePageSetting { @@ -9,6 +10,8 @@ extension ExtraHomePageSetting on HomePageSetting { return CollectionPage.routeName; case HomePageSetting.albums: return AlbumListPage.routeName; + case HomePageSetting.tags: + return TagListPage.routeName; } } } diff --git a/lib/view/src/settings/enums.dart b/lib/view/src/settings/enums.dart index 642d1c305..3ac2afdf4 100644 --- a/lib/view/src/settings/enums.dart +++ b/lib/view/src/settings/enums.dart @@ -104,6 +104,8 @@ extension ExtraHomePageSettingView on HomePageSetting { return context.l10n.drawerCollectionAll; case HomePageSetting.albums: return context.l10n.drawerAlbumPage; + case HomePageSetting.tags: + return context.l10n.drawerTagPage; } } } diff --git a/lib/widgets/common/behaviour/pop/tv_navigation.dart b/lib/widgets/common/behaviour/pop/tv_navigation.dart index 8af4081ff..e51367139 100644 --- a/lib/widgets/common/behaviour/pop/tv_navigation.dart +++ b/lib/widgets/common/behaviour/pop/tv_navigation.dart @@ -5,6 +5,7 @@ import 'package:aves/model/source/collection_source.dart'; import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/filter_grids/albums_page.dart'; +import 'package:aves/widgets/filter_grids/tags_page.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -33,25 +34,25 @@ class TvNavigationPopHandler { case HomePageSetting.collection: return context.read().filters.isEmpty; case HomePageSetting.albums: + case HomePageSetting.tags: return true; } } static Route _getHomeRoute() { - switch (settings.homePage) { + final homePage = settings.homePage; + Route buildRoute(WidgetBuilder builder) => MaterialPageRoute( + settings: RouteSettings(name: homePage.routeName), + builder: builder, + ); + + switch (homePage) { case HomePageSetting.collection: - return MaterialPageRoute( - settings: const RouteSettings(name: CollectionPage.routeName), - builder: (context) => CollectionPage( - source: context.read(), - filters: null, - ), - ); + return buildRoute((context) => CollectionPage(source: context.read(), filters: null)); case HomePageSetting.albums: - return MaterialPageRoute( - settings: const RouteSettings(name: AlbumListPage.routeName), - builder: (context) => const AlbumListPage(), - ); + return buildRoute((context) => const AlbumListPage()); + case HomePageSetting.tags: + return buildRoute((context) => const TagListPage()); } } } diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index ff4defde4..f2ea00c12 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -24,6 +24,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/search/page.dart'; import 'package:aves/widgets/common/search/route.dart'; import 'package:aves/widgets/filter_grids/albums_page.dart'; +import 'package:aves/widgets/filter_grids/tags_page.dart'; import 'package:aves/widgets/search/search_delegate.dart'; import 'package:aves/widgets/settings/home_widget_settings_page.dart'; import 'package:aves/widgets/settings/screen_saver_settings_page.dart'; @@ -345,32 +346,23 @@ class _HomePageState extends State { filters = _initialFilters ?? {}; break; } + Route buildRoute(WidgetBuilder builder) => DirectMaterialPageRoute( + settings: RouteSettings(name: routeName), + builder: builder, + ); + final source = context.read(); switch (routeName) { case AlbumListPage.routeName: - return DirectMaterialPageRoute( - settings: RouteSettings(name: routeName), - builder: (context) => const AlbumListPage(), - ); + return buildRoute((context) => const AlbumListPage()); + case TagListPage.routeName: + return buildRoute((context) => const TagListPage()); case ScreenSaverPage.routeName: - return DirectMaterialPageRoute( - settings: RouteSettings(name: routeName), - builder: (context) => ScreenSaverPage( - source: source, - ), - ); + return buildRoute((context) => ScreenSaverPage(source: source)); case ScreenSaverSettingsPage.routeName: - return DirectMaterialPageRoute( - settings: RouteSettings(name: routeName), - builder: (context) => const ScreenSaverSettingsPage(), - ); + return buildRoute((context) => const ScreenSaverSettingsPage()); case HomeWidgetSettingsPage.routeName: - return DirectMaterialPageRoute( - settings: RouteSettings(name: routeName), - builder: (context) => HomeWidgetSettingsPage( - widgetId: _widgetId!, - ), - ); + return buildRoute((context) => HomeWidgetSettingsPage(widgetId: _widgetId!)); case SearchPage.routeName: return SearchPageRoute( delegate: CollectionSearchDelegate( @@ -382,13 +374,7 @@ class _HomePageState extends State { ); case CollectionPage.routeName: default: - return DirectMaterialPageRoute( - settings: RouteSettings(name: routeName), - builder: (context) => CollectionPage( - source: source, - filters: filters, - ), - ); + return buildRoute((context) => CollectionPage(source: source, filters: filters)); } } } diff --git a/lib/widgets/navigation/tv_rail.dart b/lib/widgets/navigation/tv_rail.dart index a408e2a50..e1ef726d5 100644 --- a/lib/widgets/navigation/tv_rail.dart +++ b/lib/widgets/navigation/tv_rail.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/filters.dart'; +import 'package:aves/model/settings/enums/home_page.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; @@ -12,7 +13,6 @@ import 'package:aves/widgets/common/basic/insets.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/identity/aves_logo.dart'; import 'package:aves/widgets/debug/app_debug_page.dart'; -import 'package:aves/widgets/filter_grids/albums_page.dart'; import 'package:aves/widgets/navigation/drawer/app_drawer.dart'; import 'package:aves/widgets/navigation/drawer/page_nav_tile.dart'; import 'package:aves/widgets/navigation/drawer/tile.dart'; @@ -240,13 +240,16 @@ class _TvRailState extends State { return pageBookmarks.map(_routeNavEntry).toList(); } - _NavEntry _routeNavEntry(String routeName) => _NavEntry( - icon: DrawerPageIcon(route: routeName), - label: DrawerPageTitle(route: routeName), - isHome: settings.homePage == HomePageSetting.albums && routeName == AlbumListPage.routeName, - isSelected: context.currentRouteName == routeName, - onSelection: () => _goTo(routeName), - ); + _NavEntry _routeNavEntry(String routeName) { + final homePage = settings.homePage; + return _NavEntry( + icon: DrawerPageIcon(route: routeName), + label: DrawerPageTitle(route: routeName), + isHome: homePage != HomePageSetting.collection && routeName == homePage.routeName, + isSelected: context.currentRouteName == routeName, + onSelection: () => _goTo(routeName), + ); + } void _goTo(String routeName) { Navigator.maybeOf(context)?.pushAndRemoveUntil( diff --git a/plugins/aves_model/lib/src/settings/enums.dart b/plugins/aves_model/lib/src/settings/enums.dart index f12c6ce7b..1c868f99d 100644 --- a/plugins/aves_model/lib/src/settings/enums.dart +++ b/plugins/aves_model/lib/src/settings/enums.dart @@ -14,7 +14,7 @@ enum DisplayRefreshRateMode { auto, highest, lowest } enum EntryBackground { black, white, checkered } -enum HomePageSetting { collection, albums } +enum HomePageSetting { collection, albums, tags } enum KeepScreenOn { never, videoPlayback, viewerOnly, always } From 413d41c78d9f111057b35b23dd07a3e2775b5d30 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 1 May 2023 12:19:05 +0200 Subject: [PATCH 02/35] remember whether to show the title filter when picking albums --- CHANGELOG.md | 4 ++ lib/model/query.dart | 3 +- lib/model/settings/settings.dart | 6 ++ .../common/providers/query_provider.dart | 9 ++- .../dialogs/pick_dialogs/album_pick_page.dart | 56 +++++++++++------ .../filter_grids/common/filter_grid_page.dart | 62 +++++++++---------- .../filter_grids/common/filter_nav_page.dart | 47 +++++++------- 7 files changed, 109 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb35625fa..34eed96ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file. - option to set the Tags page as home +### Changed + +- remember whether to show the title filter when picking albums + ## [v1.8.6] - 2023-04-30 ### Added diff --git a/lib/model/query.dart b/lib/model/query.dart index 82be471d9..29d950240 100644 --- a/lib/model/query.dart +++ b/lib/model/query.dart @@ -8,7 +8,8 @@ class Query extends ChangeNotifier { final ValueNotifier _queryNotifier = ValueNotifier(''); final StreamController _enabledStreamController = StreamController.broadcast(); - Query({required String? initialValue}) { + Query({required bool enabled, required String? initialValue}) { + _enabled = enabled; if (initialValue != null && initialValue.isNotEmpty) { _enabled = true; queryNotifier.value = initialValue; diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 86a9019ea..b9a0ea3c8 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -118,6 +118,7 @@ class Settings extends ChangeNotifier { static const tagSortReverseKey = 'tag_sort_reverse'; static const pinnedFiltersKey = 'pinned_filters'; static const hiddenFiltersKey = 'hidden_filters'; + static const showAlbumPickQueryKey = 'show_album_pick_query'; // viewer static const viewerQuickActionsKey = 'viewer_quick_actions'; @@ -625,6 +626,10 @@ class Settings extends ChangeNotifier { hiddenFilters = _hiddenFilters; } + bool get showAlbumPickQuery => getBool(showAlbumPickQueryKey) ?? false; + + set showAlbumPickQuery(bool newValue) => _set(showAlbumPickQueryKey, newValue); + // viewer List get viewerQuickActions => getEnumListOrDefault(viewerQuickActionsKey, SettingsDefaults.viewerQuickActions, EntryAction.values); @@ -1107,6 +1112,7 @@ class Settings extends ChangeNotifier { case stateSortReverseKey: case placeSortReverseKey: case tagSortReverseKey: + case showAlbumPickQueryKey: case showOverlayOnOpeningKey: case showOverlayMinimapKey: case showOverlayInfoKey: diff --git a/lib/widgets/common/providers/query_provider.dart b/lib/widgets/common/providers/query_provider.dart index 426cb7c56..e811e92ad 100644 --- a/lib/widgets/common/providers/query_provider.dart +++ b/lib/widgets/common/providers/query_provider.dart @@ -3,19 +3,24 @@ import 'package:flutter/widgets.dart'; import 'package:provider/provider.dart'; class QueryProvider extends StatelessWidget { + final bool enabled; final String? initialQuery; final Widget child; const QueryProvider({ super.key, - required this.initialQuery, + this.enabled = false, + this.initialQuery, required this.child, }); @override Widget build(BuildContext context) { return ChangeNotifierProvider( - create: (context) => Query(initialValue: initialQuery), + create: (context) => Query( + enabled: enabled, + initialValue: initialQuery, + ), child: child, ); } diff --git a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart index 6a74cd192..253e1ebaa 100644 --- a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart @@ -14,6 +14,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/empty.dart'; +import 'package:aves/widgets/common/providers/query_provider.dart'; import 'package:aves/widgets/common/providers/selection_provider.dart'; import 'package:aves/widgets/dialogs/aves_confirmation_dialog.dart'; import 'package:aves/widgets/dialogs/filter_editors/create_album_dialog.dart'; @@ -106,28 +107,31 @@ class _AlbumPickPageState extends State<_AlbumPickPage> { builder: (context, snapshot) { final gridItems = AlbumListPage.getAlbumGridItems(context, source); return SelectionProvider>( - child: FilterGridPage( - settingsRouteKey: AlbumListPage.routeName, - appBar: FilterGridAppBar( - source: source, - title: title, - actionDelegate: AlbumChipSetActionDelegate(gridItems), - actionsBuilder: _buildActions, - isEmpty: false, + child: QueryProvider( + enabled: settings.showAlbumPickQuery, + child: FilterGridPage( + settingsRouteKey: AlbumListPage.routeName, + appBar: FilterGridAppBar( + source: source, + title: title, + actionDelegate: _AlbumChipSetPickActionDelegate(gridItems), + actionsBuilder: _buildActions, + isEmpty: false, + appBarHeightNotifier: _appBarHeightNotifier, + ), appBarHeightNotifier: _appBarHeightNotifier, + sections: AlbumListPage.groupToSections(context, source, gridItems), + newFilters: source.getNewAlbumFilters(context), + sortFactor: settings.albumSortFactor, + showHeaders: settings.albumGroupFactor != AlbumChipGroupFactor.none, + selectable: false, + applyQuery: AlbumListPage.applyQuery, + emptyBuilder: () => EmptyContent( + icon: AIcons.album, + text: context.l10n.albumEmpty, + ), + heroType: HeroType.never, ), - appBarHeightNotifier: _appBarHeightNotifier, - sections: AlbumListPage.groupToSections(context, source, gridItems), - newFilters: source.getNewAlbumFilters(context), - sortFactor: settings.albumSortFactor, - showHeaders: settings.albumGroupFactor != AlbumChipGroupFactor.none, - selectable: false, - applyQuery: AlbumListPage.applyQuery, - emptyBuilder: () => EmptyContent( - icon: AIcons.album, - text: context.l10n.albumEmpty, - ), - heroType: HeroType.never, ), ); }, @@ -276,3 +280,15 @@ class _AlbumPickPageState extends State<_AlbumPickPage> { Navigator.maybeOf(context)?.pop(filter); } } + +class _AlbumChipSetPickActionDelegate extends AlbumChipSetActionDelegate { + _AlbumChipSetPickActionDelegate(super.items); + + @override + void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + if (action == ChipSetAction.toggleTitleSearch) { + settings.showAlbumPickQuery = !settings.showAlbumPickQuery; + } + super.onActionSelected(context, filters, action); + } +} diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index 168e616f8..39567170b 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -29,7 +29,6 @@ import 'package:aves/widgets/common/grid/sliver.dart'; import 'package:aves/widgets/common/grid/theme.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/scroll_thumb.dart'; -import 'package:aves/widgets/common/providers/query_provider.dart'; import 'package:aves/widgets/common/providers/tile_extent_controller_provider.dart'; import 'package:aves/widgets/common/thumbnail/image.dart'; import 'package:aves/widgets/common/tile_extent_controller.dart'; @@ -82,38 +81,35 @@ class FilterGridPage extends StatelessWidget { @override Widget build(BuildContext context) { final useTvLayout = settings.useTvLayout; - final body = QueryProvider( - initialQuery: null, - child: GestureAreaProtectorStack( - child: DirectionalSafeArea( - start: !useTvLayout, - top: false, - bottom: false, - child: Selector( - selector: (context, mq) => mq.padding.top, - builder: (context, mqPaddingTop, child) { - return ValueListenableBuilder( - valueListenable: appBarHeightNotifier, - builder: (context, appBarHeight, child) { - return _FilterGrid( - // key is expected by test driver - key: const Key('filter-grid'), - settingsRouteKey: settingsRouteKey, - appBar: appBar, - appBarHeight: mqPaddingTop + appBarHeight, - sections: sections, - newFilters: newFilters, - sortFactor: sortFactor, - showHeaders: showHeaders, - selectable: selectable, - applyQuery: applyQuery, - emptyBuilder: emptyBuilder, - heroType: heroType, - ); - }, - ); - }, - ), + final body = GestureAreaProtectorStack( + child: DirectionalSafeArea( + start: !useTvLayout, + top: false, + bottom: false, + child: Selector( + selector: (context, mq) => mq.padding.top, + builder: (context, mqPaddingTop, child) { + return ValueListenableBuilder( + valueListenable: appBarHeightNotifier, + builder: (context, appBarHeight, child) { + return _FilterGrid( + // key is expected by test driver + key: const Key('filter-grid'), + settingsRouteKey: settingsRouteKey, + appBar: appBar, + appBarHeight: mqPaddingTop + appBarHeight, + sections: sections, + newFilters: newFilters, + sortFactor: sortFactor, + showHeaders: showHeaders, + selectable: selectable, + applyQuery: applyQuery, + emptyBuilder: emptyBuilder, + heroType: heroType, + ); + }, + ); + }, ), ), ); diff --git a/lib/widgets/filter_grids/common/filter_nav_page.dart b/lib/widgets/filter_grids/common/filter_nav_page.dart index 7f235c29f..b2a156655 100644 --- a/lib/widgets/filter_grids/common/filter_nav_page.dart +++ b/lib/widgets/filter_grids/common/filter_nav_page.dart @@ -2,6 +2,7 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/utils/time_utils.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; +import 'package:aves/widgets/common/providers/query_provider.dart'; import 'package:aves/widgets/common/providers/selection_provider.dart'; import 'package:aves/widgets/filter_grids/common/action_delegates/chip_set.dart'; import 'package:aves/widgets/filter_grids/common/app_bar.dart'; @@ -106,30 +107,32 @@ class _FilterNavigationPageState>( child: Builder( - builder: (context) => FilterGridPage( - appBar: FilterGridAppBar( - source: widget.source, - title: widget.title, - actionDelegate: widget.actionDelegate, - isEmpty: widget.filterSections.isEmpty, + builder: (context) => QueryProvider( + child: FilterGridPage( + appBar: FilterGridAppBar( + source: widget.source, + title: widget.title, + actionDelegate: widget.actionDelegate, + isEmpty: widget.filterSections.isEmpty, + appBarHeightNotifier: _appBarHeightNotifier, + ), appBarHeightNotifier: _appBarHeightNotifier, + sections: widget.filterSections, + newFilters: widget.newFilters ?? {}, + sortFactor: widget.sortFactor, + showHeaders: widget.showHeaders, + selectable: true, + applyQuery: widget.applyQuery, + emptyBuilder: () => ValueListenableBuilder( + valueListenable: widget.source.stateNotifier, + builder: (context, sourceState, child) { + return sourceState != SourceState.loading ? widget.emptyBuilder() : const SizedBox(); + }, + ), + // do not always enable hero, otherwise unwanted hero gets triggered + // when using `Show in [...]` action from a chip in the Collection filter bar + heroType: HeroType.onTap, ), - appBarHeightNotifier: _appBarHeightNotifier, - sections: widget.filterSections, - newFilters: widget.newFilters ?? {}, - sortFactor: widget.sortFactor, - showHeaders: widget.showHeaders, - selectable: true, - applyQuery: widget.applyQuery, - emptyBuilder: () => ValueListenableBuilder( - valueListenable: widget.source.stateNotifier, - builder: (context, sourceState, child) { - return sourceState != SourceState.loading ? widget.emptyBuilder() : const SizedBox(); - }, - ), - // do not always enable hero, otherwise unwanted hero gets triggered - // when using `Show in [...]` action from a chip in the Collection filter bar - heroType: HeroType.onTap, ), ), ); From 584ab2b3bfc93dce845b25a1f3c5a1e7ae9e5b70 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 7 May 2023 22:58:34 +0200 Subject: [PATCH 03/35] l10n by weblate (#620) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translate-URL: https://hosted.weblate.org/projects/aves/app-android/ml/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/el/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/es/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/eu/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/hu/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/id/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/it/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ko/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/nl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pt/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/uk/ Translation: Aves/App - Android Translation: Aves/App - Main Co-authored-by: Aitor Salaberria Co-authored-by: Dick Pluim Co-authored-by: György Viktor Co-authored-by: Jonatas de Almeida Barros Co-authored-by: Linerly Co-authored-by: Raman Co-authored-by: Raman Co-authored-by: Skrripy Co-authored-by: Thibault Deckers Co-authored-by: gallegonovato Co-authored-by: glemco Co-authored-by: rehork --- .../app/src/main/res/values-ml/strings.xml | 9 +++++++ .../metadata/android/ml/full_description.txt | 5 ++++ .../metadata/android/ml/short_description.txt | 1 + lib/l10n/app_eu.arb | 24 ++++++++++++++++- lib/l10n/app_hu.arb | 2 +- lib/l10n/app_id.arb | 14 +++++++++- lib/l10n/app_ml.arb | 1 + lib/l10n/app_pt.arb | 24 ++++++++++++++++- lib/l10n/app_uk.arb | 26 +++++++++++++++++-- 9 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 android/app/src/main/res/values-ml/strings.xml create mode 100644 fastlane/metadata/android/ml/full_description.txt create mode 100644 fastlane/metadata/android/ml/short_description.txt create mode 100644 lib/l10n/app_ml.arb diff --git a/android/app/src/main/res/values-ml/strings.xml b/android/app/src/main/res/values-ml/strings.xml new file mode 100644 index 000000000..3df6e6419 --- /dev/null +++ b/android/app/src/main/res/values-ml/strings.xml @@ -0,0 +1,9 @@ + + + ഏവ്സ് + ചുമർ ചിത്രം + തിരയുക + വീഡിയോകൾ + മാധ്യമ സൂക്ഷ്മപരിശോധന + നിർത്തുക + \ No newline at end of file diff --git a/fastlane/metadata/android/ml/full_description.txt b/fastlane/metadata/android/ml/full_description.txt new file mode 100644 index 000000000..6c92748f8 --- /dev/null +++ b/fastlane/metadata/android/ml/full_description.txt @@ -0,0 +1,5 @@ +Aves can handle all sorts of images and videos, including your typical JPEGs and MP4s, but also more exotic things like multi-page TIFFs, SVGs, old AVIs and more! It scans your media collection to identify motion photos, panoramas (aka photo spheres), 360° videos, as well as GeoTIFF files. + +Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. + +Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file diff --git a/fastlane/metadata/android/ml/short_description.txt b/fastlane/metadata/android/ml/short_description.txt new file mode 100644 index 000000000..8c9445bd5 --- /dev/null +++ b/fastlane/metadata/android/ml/short_description.txt @@ -0,0 +1 @@ +Gallery and metadata explorer \ No newline at end of file diff --git a/lib/l10n/app_eu.arb b/lib/l10n/app_eu.arb index e1929c0bf..2b28a73af 100644 --- a/lib/l10n/app_eu.arb +++ b/lib/l10n/app_eu.arb @@ -1452,5 +1452,27 @@ "searchStatesSectionTitle": "Egoerak", "@searchStatesSectionTitle": {}, "statsTopStatesSectionTitle": "Egoera Nagusiak", - "@statsTopStatesSectionTitle": {} + "@statsTopStatesSectionTitle": {}, + "settingsAskEverytime": "Galdetu aldi oro", + "@settingsAskEverytime": {}, + "settingsVideoPlaybackTile": "Erreprodukzioa", + "@settingsVideoPlaybackTile": {}, + "maxBrightnessNever": "Inoiz", + "@maxBrightnessNever": {}, + "maxBrightnessAlways": "Beti", + "@maxBrightnessAlways": {}, + "videoResumptionModeAlways": "Beti", + "@videoResumptionModeAlways": {}, + "exportEntryDialogQuality": "Kalitatea", + "@exportEntryDialogQuality": {}, + "settingsVideoPlaybackPageTitle": "Erreprodukzioa", + "@settingsVideoPlaybackPageTitle": {}, + "settingsVideoResumptionModeTile": "Jarraitu erreprodukzioa", + "@settingsVideoResumptionModeTile": {}, + "tagEditorDiscardDialogMessage": "Aldaketak baztertu nahi dituzu?", + "@tagEditorDiscardDialogMessage": {}, + "videoResumptionModeNever": "Inoiz", + "@videoResumptionModeNever": {}, + "settingsVideoResumptionModeDialogTitle": "Jarraitu erreprodukzioa", + "@settingsVideoResumptionModeDialogTitle": {} } diff --git a/lib/l10n/app_hu.arb b/lib/l10n/app_hu.arb index ae5050bf8..d634e332b 100644 --- a/lib/l10n/app_hu.arb +++ b/lib/l10n/app_hu.arb @@ -119,7 +119,7 @@ "@aboutPageTitle": {}, "aboutLinkLicense": "Licensz", "@aboutLinkLicense": {}, - "aboutBugSectionTitle": "Hiba jelentés", + "aboutBugSectionTitle": "Hibajelentés", "@aboutBugSectionTitle": {}, "aboutBugCopyInfoButton": "Másolás", "@aboutBugCopyInfoButton": {}, diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 89fbcc29d..97398a84c 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -1304,5 +1304,17 @@ "videoResumptionModeNever": "Tidak pernah", "@videoResumptionModeNever": {}, "videoResumptionModeAlways": "Selalu", - "@videoResumptionModeAlways": {} + "@videoResumptionModeAlways": {}, + "settingsVideoResumptionModeTile": "Lanjutkan pemutaran", + "@settingsVideoResumptionModeTile": {}, + "settingsVideoResumptionModeDialogTitle": "Lanjutkan Pemutaran", + "@settingsVideoResumptionModeDialogTitle": {}, + "tagEditorDiscardDialogMessage": "Apakah Anda ingin membuang perubahan?", + "@tagEditorDiscardDialogMessage": {}, + "exportEntryDialogQuality": "Kualitas", + "@exportEntryDialogQuality": {}, + "settingsVideoPlaybackTile": "Pemutaran", + "@settingsVideoPlaybackTile": {}, + "settingsVideoPlaybackPageTitle": "Pemutaran", + "@settingsVideoPlaybackPageTitle": {} } diff --git a/lib/l10n/app_ml.arb b/lib/l10n/app_ml.arb new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/lib/l10n/app_ml.arb @@ -0,0 +1 @@ +{} diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 7e379a006..e695fe3ec 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1294,5 +1294,27 @@ "viewerActionUnlock": "Desbloquear visualizador", "@viewerActionUnlock": {}, "settingsVideoBackgroundModeDialogTitle": "Modo de fundo", - "@settingsVideoBackgroundModeDialogTitle": {} + "@settingsVideoBackgroundModeDialogTitle": {}, + "settingsVideoPlaybackTile": "Reproduzir", + "@settingsVideoPlaybackTile": {}, + "maxBrightnessAlways": "Sempre", + "@maxBrightnessAlways": {}, + "videoResumptionModeAlways": "Sempre", + "@videoResumptionModeAlways": {}, + "exportEntryDialogQuality": "Qualidade", + "@exportEntryDialogQuality": {}, + "settingsAskEverytime": "Perguntar sempre", + "@settingsAskEverytime": {}, + "settingsVideoPlaybackPageTitle": "Reproduzir", + "@settingsVideoPlaybackPageTitle": {}, + "settingsVideoResumptionModeTile": "Retomar a reprodução", + "@settingsVideoResumptionModeTile": {}, + "settingsVideoResumptionModeDialogTitle": "Retomar a reprodução", + "@settingsVideoResumptionModeDialogTitle": {}, + "maxBrightnessNever": "Nunca", + "@maxBrightnessNever": {}, + "videoResumptionModeNever": "Nunca", + "@videoResumptionModeNever": {}, + "tagEditorDiscardDialogMessage": "Pretende rejeitar as alterações?", + "@tagEditorDiscardDialogMessage": {} } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index a09e87d79..0e19f56ad 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -332,7 +332,7 @@ "@noMatchingAppDialogMessage": {}, "moveUndatedConfirmationDialogSetDate": "Зберегти дати", "@moveUndatedConfirmationDialogSetDate": {}, - "videoResumeDialogMessage": "Чи хочете ви відновити відтворення на {time}?", + "videoResumeDialogMessage": "Ви хочете продовжити відтворення з {time}?", "@videoResumeDialogMessage": { "placeholders": { "time": { @@ -1452,5 +1452,27 @@ "searchStatesSectionTitle": "Штати", "@searchStatesSectionTitle": {}, "statePageTitle": "Штати", - "@statePageTitle": {} + "@statePageTitle": {}, + "settingsAskEverytime": "Запитувати щоразу", + "@settingsAskEverytime": {}, + "maxBrightnessNever": "Ніколи", + "@maxBrightnessNever": {}, + "maxBrightnessAlways": "Завжди", + "@maxBrightnessAlways": {}, + "videoResumptionModeNever": "Ніколи", + "@videoResumptionModeNever": {}, + "exportEntryDialogQuality": "Якість", + "@exportEntryDialogQuality": {}, + "settingsVideoPlaybackTile": "Відтворення", + "@settingsVideoPlaybackTile": {}, + "settingsVideoPlaybackPageTitle": "Відтворення", + "@settingsVideoPlaybackPageTitle": {}, + "settingsVideoResumptionModeTile": "Продовжити відтворення", + "@settingsVideoResumptionModeTile": {}, + "settingsVideoResumptionModeDialogTitle": "Продовжити відтворення", + "@settingsVideoResumptionModeDialogTitle": {}, + "tagEditorDiscardDialogMessage": "Ви хочете відмовитися від змін?", + "@tagEditorDiscardDialogMessage": {}, + "videoResumptionModeAlways": "Завжди", + "@videoResumptionModeAlways": {} } From 042c3e652f68ac34e0e7c4edb29853f38670d899 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 7 May 2023 23:07:02 +0200 Subject: [PATCH 04/35] l10n --- lib/model/app/contributors.dart | 1 + lib/widgets/aves_app.dart | 14 +- untranslated.json | 711 +++++++++++++++++++++++++++++--- 3 files changed, 674 insertions(+), 52 deletions(-) diff --git a/lib/model/app/contributors.dart b/lib/model/app/contributors.dart index 26b45a414..fbdd2fd55 100644 --- a/lib/model/app/contributors.dart +++ b/lib/model/app/contributors.dart @@ -55,6 +55,7 @@ class Contributors { // Contributor('GoRaN', 'gorangharib.909@gmail.com'), // Kurdish (Central) // Contributor('Rohit Burman', 'rohitburman31p@rediffmail.com'), // Hindi // Contributor('Subham Jena', 'subhamjena8465@gmail.com'), // Odia + // Contributor('Raman', 'xysed@tutanota.com'), // Malayalam }; } diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 377e8b415..01ef95154 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -58,7 +58,19 @@ class AvesApp extends StatefulWidget { // temporary exclude locales not ready yet for prime time // `ckb`: add `flutter_ckb_localization` and necessary app localization delegates when ready - static final _unsupportedLocales = {'ar', 'ckb', 'fa', 'gl', 'he', 'hi', 'nn', 'or', 'sk', 'th'}.map(Locale.new).toSet(); + static final _unsupportedLocales = { + 'ar', // Arabic + 'ckb', // Kurdish (Central) + 'fa', // Persian + 'gl', // Galician + 'he', // Hebrew + 'hi', // Hindi + 'ml', // Malayalam + 'nn', // Norwegian Nynorsk + 'or', // Odia + 'sk', // Slovak + 'th', // Thai + }.map(Locale.new).toSet(); static final List supportedLocales = AppLocalizations.supportedLocales.where((v) => !_unsupportedLocales.contains(v)).toList(); static final ValueNotifier cutoutInsetsNotifier = ValueNotifier(EdgeInsets.zero); diff --git a/untranslated.json b/untranslated.json index 1f27c1cb1..d07633804 100644 --- a/untranslated.json +++ b/untranslated.json @@ -1244,20 +1244,6 @@ "tagEditorDiscardDialogMessage" ], - "eu": [ - "maxBrightnessNever", - "maxBrightnessAlways", - "videoResumptionModeNever", - "videoResumptionModeAlways", - "exportEntryDialogQuality", - "settingsAskEverytime", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "tagEditorDiscardDialogMessage" - ], - "fa": [ "clearTooltip", "chipActionGoToPlacePage", @@ -3572,15 +3558,6 @@ "filePickerUseThisFolder" ], - "id": [ - "exportEntryDialogQuality", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "tagEditorDiscardDialogMessage" - ], - "ja": [ "columnCount", "chipActionShowCountryStates", @@ -3690,6 +3667,666 @@ "tagPlaceholderState" ], + "ml": [ + "appName", + "welcomeMessage", + "welcomeOptional", + "welcomeTermsToggle", + "itemCount", + "columnCount", + "timeSeconds", + "timeMinutes", + "timeDays", + "focalLength", + "applyButtonLabel", + "deleteButtonLabel", + "nextButtonLabel", + "showButtonLabel", + "hideButtonLabel", + "continueButtonLabel", + "cancelTooltip", + "changeTooltip", + "clearTooltip", + "previousTooltip", + "nextTooltip", + "showTooltip", + "hideTooltip", + "actionRemove", + "resetTooltip", + "saveTooltip", + "pickTooltip", + "doubleBackExitMessage", + "doNotAskAgain", + "sourceStateLoading", + "sourceStateCataloguing", + "sourceStateLocatingCountries", + "sourceStateLocatingPlaces", + "chipActionDelete", + "chipActionGoToAlbumPage", + "chipActionGoToCountryPage", + "chipActionGoToPlacePage", + "chipActionGoToTagPage", + "chipActionFilterOut", + "chipActionFilterIn", + "chipActionHide", + "chipActionLock", + "chipActionPin", + "chipActionUnpin", + "chipActionRename", + "chipActionSetCover", + "chipActionShowCountryStates", + "chipActionCreateAlbum", + "chipActionCreateVault", + "chipActionConfigureVault", + "entryActionCopyToClipboard", + "entryActionDelete", + "entryActionConvert", + "entryActionExport", + "entryActionInfo", + "entryActionRename", + "entryActionRestore", + "entryActionRotateCCW", + "entryActionRotateCW", + "entryActionFlip", + "entryActionPrint", + "entryActionShare", + "entryActionShareImageOnly", + "entryActionShareVideoOnly", + "entryActionViewSource", + "entryActionShowGeoTiffOnMap", + "entryActionConvertMotionPhotoToStillImage", + "entryActionViewMotionPhotoVideo", + "entryActionEdit", + "entryActionOpen", + "entryActionSetAs", + "entryActionOpenMap", + "entryActionRotateScreen", + "entryActionAddFavourite", + "entryActionRemoveFavourite", + "videoActionCaptureFrame", + "videoActionMute", + "videoActionUnmute", + "videoActionPause", + "videoActionPlay", + "videoActionReplay10", + "videoActionSkip10", + "videoActionSelectStreams", + "videoActionSetSpeed", + "viewerActionSettings", + "viewerActionLock", + "viewerActionUnlock", + "slideshowActionResume", + "slideshowActionShowInCollection", + "entryInfoActionEditDate", + "entryInfoActionEditLocation", + "entryInfoActionEditTitleDescription", + "entryInfoActionEditRating", + "entryInfoActionEditTags", + "entryInfoActionRemoveMetadata", + "entryInfoActionExportMetadata", + "entryInfoActionRemoveLocation", + "filterAspectRatioLandscapeLabel", + "filterAspectRatioPortraitLabel", + "filterBinLabel", + "filterFavouriteLabel", + "filterNoDateLabel", + "filterNoAddressLabel", + "filterLocatedLabel", + "filterNoLocationLabel", + "filterNoRatingLabel", + "filterTaggedLabel", + "filterNoTagLabel", + "filterNoTitleLabel", + "filterOnThisDayLabel", + "filterRecentlyAddedLabel", + "filterRatingRejectedLabel", + "filterTypeAnimatedLabel", + "filterTypeMotionPhotoLabel", + "filterTypePanoramaLabel", + "filterTypeRawLabel", + "filterTypeSphericalVideoLabel", + "filterTypeGeotiffLabel", + "filterMimeImageLabel", + "filterMimeVideoLabel", + "accessibilityAnimationsRemove", + "accessibilityAnimationsKeep", + "albumTierNew", + "albumTierPinned", + "albumTierSpecial", + "albumTierApps", + "albumTierVaults", + "albumTierRegular", + "coordinateFormatDms", + "coordinateFormatDecimal", + "coordinateDms", + "coordinateDmsNorth", + "coordinateDmsSouth", + "coordinateDmsEast", + "coordinateDmsWest", + "displayRefreshRatePreferHighest", + "displayRefreshRatePreferLowest", + "keepScreenOnNever", + "keepScreenOnVideoPlayback", + "keepScreenOnViewerOnly", + "keepScreenOnAlways", + "lengthUnitPixel", + "lengthUnitPercent", + "mapStyleGoogleNormal", + "mapStyleGoogleHybrid", + "mapStyleGoogleTerrain", + "mapStyleHuaweiNormal", + "mapStyleHuaweiTerrain", + "mapStyleOsmHot", + "mapStyleStamenToner", + "mapStyleStamenWatercolor", + "maxBrightnessNever", + "maxBrightnessAlways", + "nameConflictStrategyRename", + "nameConflictStrategyReplace", + "nameConflictStrategySkip", + "subtitlePositionTop", + "subtitlePositionBottom", + "themeBrightnessLight", + "themeBrightnessDark", + "themeBrightnessBlack", + "unitSystemMetric", + "unitSystemImperial", + "vaultLockTypePattern", + "vaultLockTypePin", + "vaultLockTypePassword", + "settingsVideoEnablePip", + "videoControlsPlay", + "videoControlsPlaySeek", + "videoControlsPlayOutside", + "videoControlsNone", + "videoLoopModeNever", + "videoLoopModeShortOnly", + "videoLoopModeAlways", + "videoPlaybackSkip", + "videoPlaybackMuted", + "videoPlaybackWithSound", + "videoResumptionModeNever", + "videoResumptionModeAlways", + "viewerTransitionSlide", + "viewerTransitionParallax", + "viewerTransitionFade", + "viewerTransitionZoomIn", + "viewerTransitionNone", + "wallpaperTargetHome", + "wallpaperTargetLock", + "wallpaperTargetHomeLock", + "widgetDisplayedItemRandom", + "widgetDisplayedItemMostRecent", + "widgetOpenPageHome", + "widgetOpenPageCollection", + "widgetOpenPageViewer", + "storageVolumeDescriptionFallbackPrimary", + "storageVolumeDescriptionFallbackNonPrimary", + "rootDirectoryDescription", + "otherDirectoryDescription", + "storageAccessDialogMessage", + "restrictedAccessDialogMessage", + "notEnoughSpaceDialogMessage", + "missingSystemFilePickerDialogMessage", + "unsupportedTypeDialogMessage", + "nameConflictDialogSingleSourceMessage", + "nameConflictDialogMultipleSourceMessage", + "addShortcutDialogLabel", + "addShortcutButtonLabel", + "noMatchingAppDialogMessage", + "binEntriesConfirmationDialogMessage", + "deleteEntriesConfirmationDialogMessage", + "moveUndatedConfirmationDialogMessage", + "moveUndatedConfirmationDialogSetDate", + "videoResumeDialogMessage", + "videoStartOverButtonLabel", + "videoResumeButtonLabel", + "setCoverDialogLatest", + "setCoverDialogAuto", + "setCoverDialogCustom", + "hideFilterConfirmationDialogMessage", + "newAlbumDialogTitle", + "newAlbumDialogNameLabel", + "newAlbumDialogNameLabelAlreadyExistsHelper", + "newAlbumDialogStorageLabel", + "newVaultWarningDialogMessage", + "newVaultDialogTitle", + "configureVaultDialogTitle", + "vaultDialogLockModeWhenScreenOff", + "vaultDialogLockTypeLabel", + "patternDialogEnter", + "patternDialogConfirm", + "pinDialogEnter", + "pinDialogConfirm", + "passwordDialogEnter", + "passwordDialogConfirm", + "authenticateToConfigureVault", + "authenticateToUnlockVault", + "vaultBinUsageDialogMessage", + "renameAlbumDialogLabel", + "renameAlbumDialogLabelAlreadyExistsHelper", + "renameEntrySetPageTitle", + "renameEntrySetPagePatternFieldLabel", + "renameEntrySetPageInsertTooltip", + "renameEntrySetPagePreviewSectionTitle", + "renameProcessorCounter", + "renameProcessorName", + "deleteSingleAlbumConfirmationDialogMessage", + "deleteMultiAlbumConfirmationDialogMessage", + "exportEntryDialogFormat", + "exportEntryDialogWidth", + "exportEntryDialogHeight", + "exportEntryDialogQuality", + "exportEntryDialogWriteMetadata", + "renameEntryDialogLabel", + "editEntryDialogCopyFromItem", + "editEntryDialogTargetFieldsHeader", + "editEntryDateDialogTitle", + "editEntryDateDialogSetCustom", + "editEntryDateDialogCopyField", + "editEntryDateDialogExtractFromTitle", + "editEntryDateDialogShift", + "editEntryDateDialogSourceFileModifiedDate", + "durationDialogHours", + "durationDialogMinutes", + "durationDialogSeconds", + "editEntryLocationDialogTitle", + "editEntryLocationDialogSetCustom", + "editEntryLocationDialogChooseOnMap", + "editEntryLocationDialogLatitude", + "editEntryLocationDialogLongitude", + "locationPickerUseThisLocationButton", + "editEntryRatingDialogTitle", + "removeEntryMetadataDialogTitle", + "removeEntryMetadataDialogMore", + "removeEntryMetadataMotionPhotoXmpWarningDialogMessage", + "videoSpeedDialogLabel", + "videoStreamSelectionDialogVideo", + "videoStreamSelectionDialogAudio", + "videoStreamSelectionDialogText", + "videoStreamSelectionDialogOff", + "videoStreamSelectionDialogTrack", + "videoStreamSelectionDialogNoSelection", + "genericSuccessFeedback", + "genericFailureFeedback", + "genericDangerWarningDialogMessage", + "tooManyItemsErrorDialogMessage", + "menuActionConfigureView", + "menuActionSelect", + "menuActionSelectAll", + "menuActionSelectNone", + "menuActionMap", + "menuActionSlideshow", + "menuActionStats", + "viewDialogSortSectionTitle", + "viewDialogGroupSectionTitle", + "viewDialogLayoutSectionTitle", + "viewDialogReverseSortOrder", + "tileLayoutMosaic", + "tileLayoutGrid", + "tileLayoutList", + "coverDialogTabCover", + "coverDialogTabApp", + "coverDialogTabColor", + "appPickDialogTitle", + "appPickDialogNone", + "aboutPageTitle", + "aboutLinkLicense", + "aboutLinkPolicy", + "aboutBugSectionTitle", + "aboutBugSaveLogInstruction", + "aboutBugCopyInfoInstruction", + "aboutBugCopyInfoButton", + "aboutBugReportInstruction", + "aboutBugReportButton", + "aboutCreditsSectionTitle", + "aboutCreditsWorldAtlas1", + "aboutCreditsWorldAtlas2", + "aboutTranslatorsSectionTitle", + "aboutLicensesSectionTitle", + "aboutLicensesBanner", + "aboutLicensesAndroidLibrariesSectionTitle", + "aboutLicensesFlutterPluginsSectionTitle", + "aboutLicensesFlutterPackagesSectionTitle", + "aboutLicensesDartPackagesSectionTitle", + "aboutLicensesShowAllButtonLabel", + "policyPageTitle", + "collectionPageTitle", + "collectionPickPageTitle", + "collectionSelectPageTitle", + "collectionActionShowTitleSearch", + "collectionActionHideTitleSearch", + "collectionActionAddShortcut", + "collectionActionEmptyBin", + "collectionActionCopy", + "collectionActionMove", + "collectionActionRescan", + "collectionActionEdit", + "collectionSearchTitlesHintText", + "collectionGroupAlbum", + "collectionGroupMonth", + "collectionGroupDay", + "collectionGroupNone", + "sectionUnknown", + "dateToday", + "dateYesterday", + "dateThisMonth", + "collectionDeleteFailureFeedback", + "collectionCopyFailureFeedback", + "collectionMoveFailureFeedback", + "collectionRenameFailureFeedback", + "collectionEditFailureFeedback", + "collectionExportFailureFeedback", + "collectionCopySuccessFeedback", + "collectionMoveSuccessFeedback", + "collectionRenameSuccessFeedback", + "collectionEditSuccessFeedback", + "collectionEmptyFavourites", + "collectionEmptyVideos", + "collectionEmptyImages", + "collectionEmptyGrantAccessButtonLabel", + "collectionSelectSectionTooltip", + "collectionDeselectSectionTooltip", + "drawerAboutButton", + "drawerSettingsButton", + "drawerCollectionAll", + "drawerCollectionFavourites", + "drawerCollectionImages", + "drawerCollectionVideos", + "drawerCollectionAnimated", + "drawerCollectionMotionPhotos", + "drawerCollectionPanoramas", + "drawerCollectionRaws", + "drawerCollectionSphericalVideos", + "drawerAlbumPage", + "drawerCountryPage", + "drawerPlacePage", + "drawerTagPage", + "sortByDate", + "sortByName", + "sortByItemCount", + "sortBySize", + "sortByAlbumFileName", + "sortByRating", + "sortOrderNewestFirst", + "sortOrderOldestFirst", + "sortOrderAtoZ", + "sortOrderZtoA", + "sortOrderHighestFirst", + "sortOrderLowestFirst", + "sortOrderLargestFirst", + "sortOrderSmallestFirst", + "albumGroupTier", + "albumGroupType", + "albumGroupVolume", + "albumGroupNone", + "albumMimeTypeMixed", + "albumPickPageTitleCopy", + "albumPickPageTitleExport", + "albumPickPageTitleMove", + "albumPickPageTitlePick", + "albumCamera", + "albumDownload", + "albumScreenshots", + "albumScreenRecordings", + "albumVideoCaptures", + "albumPageTitle", + "albumEmpty", + "createAlbumButtonLabel", + "newFilterBanner", + "countryPageTitle", + "countryEmpty", + "statePageTitle", + "stateEmpty", + "placePageTitle", + "placeEmpty", + "tagPageTitle", + "tagEmpty", + "binPageTitle", + "searchCollectionFieldHint", + "searchRecentSectionTitle", + "searchDateSectionTitle", + "searchAlbumsSectionTitle", + "searchCountriesSectionTitle", + "searchStatesSectionTitle", + "searchPlacesSectionTitle", + "searchTagsSectionTitle", + "searchRatingSectionTitle", + "searchMetadataSectionTitle", + "settingsPageTitle", + "settingsSystemDefault", + "settingsDefault", + "settingsDisabled", + "settingsAskEverytime", + "settingsModificationWarningDialogMessage", + "settingsSearchFieldLabel", + "settingsSearchEmpty", + "settingsActionExport", + "settingsActionExportDialogTitle", + "settingsActionImport", + "settingsActionImportDialogTitle", + "appExportCovers", + "appExportFavourites", + "appExportSettings", + "settingsNavigationSectionTitle", + "settingsHomeTile", + "settingsHomeDialogTitle", + "settingsShowBottomNavigationBar", + "settingsKeepScreenOnTile", + "settingsKeepScreenOnDialogTitle", + "settingsDoubleBackExit", + "settingsConfirmationTile", + "settingsConfirmationDialogTitle", + "settingsConfirmationBeforeDeleteItems", + "settingsConfirmationBeforeMoveToBinItems", + "settingsConfirmationBeforeMoveUndatedItems", + "settingsConfirmationAfterMoveToBinItems", + "settingsConfirmationVaultDataLoss", + "settingsNavigationDrawerTile", + "settingsNavigationDrawerEditorPageTitle", + "settingsNavigationDrawerBanner", + "settingsNavigationDrawerTabTypes", + "settingsNavigationDrawerTabAlbums", + "settingsNavigationDrawerTabPages", + "settingsNavigationDrawerAddAlbum", + "settingsThumbnailSectionTitle", + "settingsThumbnailOverlayTile", + "settingsThumbnailOverlayPageTitle", + "settingsThumbnailShowFavouriteIcon", + "settingsThumbnailShowTagIcon", + "settingsThumbnailShowLocationIcon", + "settingsThumbnailShowMotionPhotoIcon", + "settingsThumbnailShowRating", + "settingsThumbnailShowRawIcon", + "settingsThumbnailShowVideoDuration", + "settingsCollectionQuickActionsTile", + "settingsCollectionQuickActionEditorPageTitle", + "settingsCollectionQuickActionTabBrowsing", + "settingsCollectionQuickActionTabSelecting", + "settingsCollectionBrowsingQuickActionEditorBanner", + "settingsCollectionSelectionQuickActionEditorBanner", + "settingsCollectionBurstPatternsTile", + "settingsCollectionBurstPatternsNone", + "settingsViewerSectionTitle", + "settingsViewerGestureSideTapNext", + "settingsViewerUseCutout", + "settingsViewerMaximumBrightness", + "settingsMotionPhotoAutoPlay", + "settingsImageBackground", + "settingsViewerQuickActionsTile", + "settingsViewerQuickActionEditorPageTitle", + "settingsViewerQuickActionEditorBanner", + "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle", + "settingsViewerQuickActionEditorAvailableButtonsSectionTitle", + "settingsViewerQuickActionEmpty", + "settingsViewerOverlayTile", + "settingsViewerOverlayPageTitle", + "settingsViewerShowOverlayOnOpening", + "settingsViewerShowMinimap", + "settingsViewerShowInformation", + "settingsViewerShowInformationSubtitle", + "settingsViewerShowRatingTags", + "settingsViewerShowShootingDetails", + "settingsViewerShowDescription", + "settingsViewerShowOverlayThumbnails", + "settingsViewerEnableOverlayBlurEffect", + "settingsViewerSlideshowTile", + "settingsViewerSlideshowPageTitle", + "settingsSlideshowRepeat", + "settingsSlideshowShuffle", + "settingsSlideshowFillScreen", + "settingsSlideshowAnimatedZoomEffect", + "settingsSlideshowTransitionTile", + "settingsSlideshowIntervalTile", + "settingsSlideshowVideoPlaybackTile", + "settingsSlideshowVideoPlaybackDialogTitle", + "settingsVideoPageTitle", + "settingsVideoSectionTitle", + "settingsVideoShowVideos", + "settingsVideoPlaybackTile", + "settingsVideoPlaybackPageTitle", + "settingsVideoEnableHardwareAcceleration", + "settingsVideoAutoPlay", + "settingsVideoLoopModeTile", + "settingsVideoLoopModeDialogTitle", + "settingsVideoResumptionModeTile", + "settingsVideoResumptionModeDialogTitle", + "settingsVideoBackgroundMode", + "settingsVideoBackgroundModeDialogTitle", + "settingsVideoControlsTile", + "settingsVideoControlsPageTitle", + "settingsVideoButtonsTile", + "settingsVideoGestureDoubleTapTogglePlay", + "settingsVideoGestureSideDoubleTapSeek", + "settingsVideoGestureVerticalDragBrightnessVolume", + "settingsSubtitleThemeTile", + "settingsSubtitleThemePageTitle", + "settingsSubtitleThemeSample", + "settingsSubtitleThemeTextAlignmentTile", + "settingsSubtitleThemeTextAlignmentDialogTitle", + "settingsSubtitleThemeTextPositionTile", + "settingsSubtitleThemeTextPositionDialogTitle", + "settingsSubtitleThemeTextSize", + "settingsSubtitleThemeShowOutline", + "settingsSubtitleThemeTextColor", + "settingsSubtitleThemeTextOpacity", + "settingsSubtitleThemeBackgroundColor", + "settingsSubtitleThemeBackgroundOpacity", + "settingsSubtitleThemeTextAlignmentLeft", + "settingsSubtitleThemeTextAlignmentCenter", + "settingsSubtitleThemeTextAlignmentRight", + "settingsPrivacySectionTitle", + "settingsAllowInstalledAppAccess", + "settingsAllowInstalledAppAccessSubtitle", + "settingsAllowErrorReporting", + "settingsSaveSearchHistory", + "settingsEnableBin", + "settingsEnableBinSubtitle", + "settingsDisablingBinWarningDialogMessage", + "settingsAllowMediaManagement", + "settingsHiddenItemsTile", + "settingsHiddenItemsPageTitle", + "settingsHiddenItemsTabFilters", + "settingsHiddenFiltersBanner", + "settingsHiddenFiltersEmpty", + "settingsHiddenItemsTabPaths", + "settingsHiddenPathsBanner", + "addPathTooltip", + "settingsStorageAccessTile", + "settingsStorageAccessPageTitle", + "settingsStorageAccessBanner", + "settingsStorageAccessEmpty", + "settingsStorageAccessRevokeTooltip", + "settingsAccessibilitySectionTitle", + "settingsRemoveAnimationsTile", + "settingsRemoveAnimationsDialogTitle", + "settingsTimeToTakeActionTile", + "settingsAccessibilityShowPinchGestureAlternatives", + "settingsDisplaySectionTitle", + "settingsThemeBrightnessTile", + "settingsThemeBrightnessDialogTitle", + "settingsThemeColorHighlights", + "settingsThemeEnableDynamicColor", + "settingsDisplayRefreshRateModeTile", + "settingsDisplayRefreshRateModeDialogTitle", + "settingsDisplayUseTvInterface", + "settingsLanguageSectionTitle", + "settingsLanguageTile", + "settingsLanguagePageTitle", + "settingsCoordinateFormatTile", + "settingsCoordinateFormatDialogTitle", + "settingsUnitSystemTile", + "settingsUnitSystemDialogTitle", + "settingsScreenSaverPageTitle", + "settingsWidgetPageTitle", + "settingsWidgetShowOutline", + "settingsWidgetOpenPage", + "settingsWidgetDisplayedItem", + "settingsCollectionTile", + "statsPageTitle", + "statsWithGps", + "statsTopCountriesSectionTitle", + "statsTopStatesSectionTitle", + "statsTopPlacesSectionTitle", + "statsTopTagsSectionTitle", + "statsTopAlbumsSectionTitle", + "viewerOpenPanoramaButtonLabel", + "viewerSetWallpaperButtonLabel", + "viewerErrorUnknown", + "viewerErrorDoesNotExist", + "viewerInfoPageTitle", + "viewerInfoBackToViewerTooltip", + "viewerInfoUnknown", + "viewerInfoLabelDescription", + "viewerInfoLabelTitle", + "viewerInfoLabelDate", + "viewerInfoLabelResolution", + "viewerInfoLabelSize", + "viewerInfoLabelUri", + "viewerInfoLabelPath", + "viewerInfoLabelDuration", + "viewerInfoLabelOwner", + "viewerInfoLabelCoordinates", + "viewerInfoLabelAddress", + "mapStyleDialogTitle", + "mapStyleTooltip", + "mapZoomInTooltip", + "mapZoomOutTooltip", + "mapPointNorthUpTooltip", + "mapAttributionOsmHot", + "mapAttributionStamen", + "openMapPageTooltip", + "mapEmptyRegion", + "viewerInfoOpenEmbeddedFailureFeedback", + "viewerInfoOpenLinkText", + "viewerInfoViewXmlLinkText", + "viewerInfoSearchFieldLabel", + "viewerInfoSearchEmpty", + "viewerInfoSearchSuggestionDate", + "viewerInfoSearchSuggestionDescription", + "viewerInfoSearchSuggestionDimensions", + "viewerInfoSearchSuggestionResolution", + "viewerInfoSearchSuggestionRights", + "wallpaperUseScrollEffect", + "tagEditorPageTitle", + "tagEditorPageNewTagFieldLabel", + "tagEditorPageAddTagTooltip", + "tagEditorSectionRecent", + "tagEditorSectionPlaceholders", + "tagEditorDiscardDialogMessage", + "tagPlaceholderCountry", + "tagPlaceholderState", + "tagPlaceholderPlace", + "panoramaEnableSensorControl", + "panoramaDisableSensorControl", + "sourceViewerPageTitle", + "filePickerShowHiddenFiles", + "filePickerDoNotShowHiddenFiles", + "filePickerOpenFrom", + "filePickerNoItems", + "filePickerUseThisFolder" + ], + "nb": [ "chipActionShowCountryStates", "viewerActionLock", @@ -4717,20 +5354,6 @@ "filePickerUseThisFolder" ], - "pt": [ - "maxBrightnessNever", - "maxBrightnessAlways", - "videoResumptionModeNever", - "videoResumptionModeAlways", - "exportEntryDialogQuality", - "settingsAskEverytime", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "tagEditorDiscardDialogMessage" - ], - "ro": [ "maxBrightnessNever", "maxBrightnessAlways", @@ -5646,20 +6269,6 @@ "tagPlaceholderState" ], - "uk": [ - "maxBrightnessNever", - "maxBrightnessAlways", - "videoResumptionModeNever", - "videoResumptionModeAlways", - "exportEntryDialogQuality", - "settingsAskEverytime", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "tagEditorDiscardDialogMessage" - ], - "zh": [ "chipActionGoToPlacePage", "viewerActionLock", From 9d08e88b1a9316e336365109782c0fcd96167626 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 7 May 2023 23:42:47 +0200 Subject: [PATCH 05/35] pub upgrade --- lib/widgets/common/map/leaflet/map.dart | 4 +- plugins/aves_map/pubspec.lock | 16 +-- plugins/aves_report_crashlytics/pubspec.lock | 24 ++--- plugins/aves_services/pubspec.lock | 16 +-- plugins/aves_services_google/pubspec.lock | 28 ++---- plugins/aves_services_huawei/pubspec.lock | 16 +-- plugins/aves_services_none/pubspec.lock | 16 +-- pubspec.lock | 100 +++++++++---------- pubspec.yaml | 9 +- 9 files changed, 87 insertions(+), 142 deletions(-) diff --git a/lib/widgets/common/map/leaflet/map.dart b/lib/widgets/common/map/leaflet/map.dart index ec9a5b0a7..a48ff84e6 100644 --- a/lib/widgets/common/map/leaflet/map.dart +++ b/lib/widgets/common/map/leaflet/map.dart @@ -247,8 +247,8 @@ class _EntryLeafletMapState extends State> with TickerProv final bounds = _leafletMapController.bounds; if (bounds != null) { boundsNotifier.value = ZoomedBounds( - sw: bounds.southWest!, - ne: bounds.northEast!, + sw: bounds.southWest, + ne: bounds.northEast, zoom: _leafletMapController.zoom, rotation: _leafletMapController.rotation, ); diff --git a/plugins/aves_map/pubspec.lock b/plugins/aves_map/pubspec.lock index 0fa75a49e..d19fe7fac 100644 --- a/plugins/aves_map/pubspec.lock +++ b/plugins/aves_map/pubspec.lock @@ -81,18 +81,18 @@ packages: dependency: "direct main" description: name: flutter_map - sha256: "59dfd14267b691bea55760786b47d3172d47cdcc0d79ff930746a5ad123491b8" + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" http: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_parser: dependency: transitive description: @@ -189,14 +189,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - positioned_tap_detector_2: - dependency: transitive - description: - name: positioned_tap_detector_2 - sha256: "52e06863ad3e1f82b058fd05054fc8c9caeeb3b47d5cea7a24bd9320746059c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" proj4dart: dependency: transitive description: diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index bd6dde97e..bdbe2b15a 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "6a0ad72b2bcdb461749e40c01c478212a78db848dfcb2f10f2a461988bc5fb29" + sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" async: dependency: transitive description: @@ -68,42 +68,42 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "239e4ac688674a7e7b5476fd16b0d8e2b5a453d464f32091af3ce1df4ebb7316" + sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0 url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "0df0a064ab0cad7f8836291ca6f3272edd7b83ad5b3540478ee46a0849d8022b" + sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48 url: "https://pub.dev" source: hosted - version: "4.6.0" + version: "4.7.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: "347351a8f0518f3343d79a9a0690fa67ad232fc32e2ea270677791949eac792b" + sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444 url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.0" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics - sha256: "02ce958507138d938b4611e3a4910667a44b969b0c20a810bbc97bbf967ba0d7" + sha256: e8424f75c0fd466a6ae4d069b313ec84133ef275c00a5a3a416b75b99fb3e831 url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.2.0" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: b9c7b8498c877a2901ad323fc92c10f672be1597bc82d08f121f6228f321a7e0 + sha256: "381e28f33d5255a698ac7755c3c4fdff42382be0154f375564e6852aa46f9d8f" url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.5.0" flutter: dependency: "direct main" description: flutter diff --git a/plugins/aves_services/pubspec.lock b/plugins/aves_services/pubspec.lock index d6f9acead..c1769f099 100644 --- a/plugins/aves_services/pubspec.lock +++ b/plugins/aves_services/pubspec.lock @@ -88,18 +88,18 @@ packages: dependency: transitive description: name: flutter_map - sha256: "59dfd14267b691bea55760786b47d3172d47cdcc0d79ff930746a5ad123491b8" + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" http: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_parser: dependency: transitive description: @@ -196,14 +196,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - positioned_tap_detector_2: - dependency: transitive - description: - name: positioned_tap_detector_2 - sha256: "52e06863ad3e1f82b058fd05054fc8c9caeeb3b47d5cea7a24bd9320746059c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" proj4dart: dependency: transitive description: diff --git a/plugins/aves_services_google/pubspec.lock b/plugins/aves_services_google/pubspec.lock index 5a9c169ee..5e08d6ef0 100644 --- a/plugins/aves_services_google/pubspec.lock +++ b/plugins/aves_services_google/pubspec.lock @@ -127,18 +127,18 @@ packages: dependency: transitive description: name: flutter_map - sha256: "59dfd14267b691bea55760786b47d3172d47cdcc0d79ff930746a5ad123491b8" + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "8ffe990dac54a4a5492747added38571a5ab474c8e5d196809ea08849c69b1bb" + sha256: "96af49aa6b57c10a312106ad6f71deed5a754029c24789bbf620ba784f0bd0b0" url: "https://pub.dev" source: hosted - version: "2.0.13" + version: "2.0.14" flutter_web_plugins: dependency: transitive description: flutter @@ -172,10 +172,10 @@ packages: dependency: "direct main" description: name: google_maps_flutter - sha256: "24392ef192f3b00bcd93151375676805a9933574423a5bd5509a0ead2e8a4215" + sha256: "0a7e0bd1dfe594bc86892d2e69062e3f80b267e378042d82e6b87a8efc798013" url: "https://pub.dev" source: hosted - version: "2.2.5" + version: "2.2.6" google_maps_flutter_android: dependency: "direct main" description: @@ -204,10 +204,10 @@ packages: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_parser: dependency: transitive description: @@ -312,14 +312,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - positioned_tap_detector_2: - dependency: transitive - description: - name: positioned_tap_detector_2 - sha256: "52e06863ad3e1f82b058fd05054fc8c9caeeb3b47d5cea7a24bd9320746059c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" proj4dart: dependency: transitive description: @@ -409,10 +401,10 @@ packages: dependency: transitive description: name: win32 - sha256: dd8f9344bc305ae2923e3d11a2a911d9a4e2c7dd6fe0ed10626d63211a69676e + sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.4" wkt_parser: dependency: transitive description: diff --git a/plugins/aves_services_huawei/pubspec.lock b/plugins/aves_services_huawei/pubspec.lock index 05680f00c..338b36941 100644 --- a/plugins/aves_services_huawei/pubspec.lock +++ b/plugins/aves_services_huawei/pubspec.lock @@ -102,18 +102,18 @@ packages: dependency: transitive description: name: flutter_map - sha256: "59dfd14267b691bea55760786b47d3172d47cdcc0d79ff930746a5ad123491b8" + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" http: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_parser: dependency: transitive description: @@ -234,14 +234,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - positioned_tap_detector_2: - dependency: transitive - description: - name: positioned_tap_detector_2 - sha256: "52e06863ad3e1f82b058fd05054fc8c9caeeb3b47d5cea7a24bd9320746059c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" proj4dart: dependency: transitive description: diff --git a/plugins/aves_services_none/pubspec.lock b/plugins/aves_services_none/pubspec.lock index 83aa39d6e..a67767953 100644 --- a/plugins/aves_services_none/pubspec.lock +++ b/plugins/aves_services_none/pubspec.lock @@ -95,18 +95,18 @@ packages: dependency: transitive description: name: flutter_map - sha256: "59dfd14267b691bea55760786b47d3172d47cdcc0d79ff930746a5ad123491b8" + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" http: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_parser: dependency: transitive description: @@ -203,14 +203,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - positioned_tap_detector_2: - dependency: transitive - description: - name: positioned_tap_detector_2 - sha256: "52e06863ad3e1f82b058fd05054fc8c9caeeb3b47d5cea7a24bd9320746059c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" proj4dart: dependency: transitive description: diff --git a/pubspec.lock b/pubspec.lock index a4731aacd..65252036e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "6a0ad72b2bcdb461749e40c01c478212a78db848dfcb2f10f2a461988bc5fb29" + sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" analyzer: dependency: transitive description: @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: args - sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" async: dependency: transitive description: @@ -349,42 +349,42 @@ packages: dependency: transitive description: name: firebase_core - sha256: "239e4ac688674a7e7b5476fd16b0d8e2b5a453d464f32091af3ce1df4ebb7316" + sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0 url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "0df0a064ab0cad7f8836291ca6f3272edd7b83ad5b3540478ee46a0849d8022b" + sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48 url: "https://pub.dev" source: hosted - version: "4.6.0" + version: "4.7.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: "347351a8f0518f3343d79a9a0690fa67ad232fc32e2ea270677791949eac792b" + sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444 url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.0" firebase_crashlytics: dependency: transitive description: name: firebase_crashlytics - sha256: "02ce958507138d938b4611e3a4910667a44b969b0c20a810bbc97bbf967ba0d7" + sha256: e8424f75c0fd466a6ae4d069b313ec84133ef275c00a5a3a416b75b99fb3e831 url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.2.0" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: b9c7b8498c877a2901ad323fc92c10f672be1597bc82d08f121f6228f321a7e0 + sha256: "381e28f33d5255a698ac7755c3c4fdff42382be0154f375564e6852aa46f9d8f" url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.5.0" flex_color_picker: dependency: "direct main" description: @@ -468,10 +468,10 @@ packages: dependency: "direct main" description: name: flutter_map - sha256: "59dfd14267b691bea55760786b47d3172d47cdcc0d79ff930746a5ad123491b8" + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "4.0.0" flutter_markdown: dependency: "direct main" description: @@ -484,10 +484,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "8ffe990dac54a4a5492747added38571a5ab474c8e5d196809ea08849c69b1bb" + sha256: "96af49aa6b57c10a312106ad6f71deed5a754029c24789bbf620ba784f0bd0b0" url: "https://pub.dev" source: hosted - version: "2.0.13" + version: "2.0.14" flutter_staggered_animations: dependency: "direct main" description: @@ -523,10 +523,10 @@ packages: dependency: "direct main" description: name: get_it - sha256: f9982979e3d2f286a957c04d2c3a98f55b0f0a06ffd6c5c4abbb96f06937f463 + sha256: "43133b45f32f1d96bbaeb43ea35a50ce854981baa80f47c3e26ee2ad23bef113" url: "https://pub.dev" source: hosted - version: "7.3.0" + version: "7.5.0" glob: dependency: transitive description: @@ -563,10 +563,10 @@ packages: dependency: transitive description: name: google_maps_flutter - sha256: "24392ef192f3b00bcd93151375676805a9933574423a5bd5509a0ead2e8a4215" + sha256: "0a7e0bd1dfe594bc86892d2e69062e3f80b267e378042d82e6b87a8efc798013" url: "https://pub.dev" source: hosted - version: "2.2.5" + version: "2.2.6" google_maps_flutter_android: dependency: transitive description: @@ -603,10 +603,10 @@ packages: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_multi_server: dependency: transitive description: @@ -627,10 +627,10 @@ packages: dependency: transitive description: name: image - sha256: "73964e3609fb96e01e69b0924b939967c556e46c7ff05db2ea9e31019000f4ef" + sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf url: "https://pub.dev" source: hosted - version: "4.0.16" + version: "4.0.17" intl: dependency: "direct main" description: @@ -691,10 +691,10 @@ packages: dependency: transitive description: name: local_auth_android - sha256: e2b785a47b1b1dfb93147409199973c98f668ff447ccfa5543be6dd0820c537a + sha256: c5e48c4a67fc0e5dd9b5725cc8766b67e2da9a54155c82c6e2ea4a0d1cf9ef93 url: "https://pub.dev" source: hosted - version: "1.0.27" + version: "1.0.28" local_auth_ios: dependency: transitive description: @@ -731,10 +731,10 @@ packages: dependency: transitive description: name: markdown - sha256: d95a9d12954aafc97f984ca29baaa7690ed4d9ec4140a23ad40580bcdb6c87f5 + sha256: "8e332924094383133cee218b676871f42db2514f1f6ac617b6cf6152a7faab8e" url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "7.1.0" matcher: dependency: transitive description: @@ -1017,14 +1017,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" - positioned_tap_detector_2: - dependency: transitive - description: - name: positioned_tap_detector_2 - sha256: "52e06863ad3e1f82b058fd05054fc8c9caeeb3b47d5cea7a24bd9320746059c1" - url: "https://pub.dev" - source: hosted - version: "1.0.4" printing: dependency: "direct main" description: @@ -1061,10 +1053,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" qr: dependency: transitive description: @@ -1181,34 +1173,34 @@ packages: dependency: transitive description: name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - sha256: aef74dc9195746a384843102142ab65b6a4735bb3beea791e63527b88cc83306 + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" shelf_static: dependency: transitive description: name: shelf_static - sha256: e792b76b96a36d4a41b819da593aff4bdd413576b3ba6150df5d8d9996d2e74c + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" sky_engine: dependency: transitive description: flutter @@ -1250,10 +1242,10 @@ packages: dependency: "direct main" description: name: sqflite - sha256: "8453780d1f703ead201a39673deb93decf85d543f359f750e2afc4908b55533f" + sha256: acf091c6e55c50d00b30b8532b2dd23e393cf775861665ebd0f15cdd6ebfb079 url: "https://pub.dev" source: hosted - version: "2.2.8" + version: "2.2.8+1" sqflite_common: dependency: transitive description: @@ -1507,10 +1499,10 @@ packages: dependency: transitive description: name: win32 - sha256: dd8f9344bc305ae2923e3d11a2a911d9a4e2c7dd6fe0ed10626d63211a69676e + sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.4" wkt_parser: dependency: transitive description: @@ -1539,10 +1531,10 @@ packages: dependency: transitive description: name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" sdks: dart: ">=2.19.6 <3.0.0" flutter: ">=3.7.12" diff --git a/pubspec.yaml b/pubspec.yaml index 1db6cfc65..8353b9c41 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,9 +16,6 @@ environment: flutter: 3.7.12 sdk: ">=2.19.6 <3.0.0" -# following https://github.blog/2021-09-01-improving-git-protocol-security-github/ -# dependency GitHub repos should be referenced via `https://`, not `git://` - # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor dependencies: flutter: @@ -98,11 +95,7 @@ dependencies: proj4dart: provider: screen_brightness: - # as of `shared_preferences` v2.0.18, upgrading packages downgrades `shared_preferences` to v0.5.4+6 - # because its dependency `shared_preferences_windows` v2.1.4 gets removed - # because its dependency `path_provider_windows` v2.1.4 gets removed - # so that the transitive `win32` gets upgraded to v4.x.x - shared_preferences: ">=2.0.0" + shared_preferences: smooth_page_indicator: sqflite: streams_channel: From ef2d0eefb0ba327a82ecec1bd75b851bb3bff557 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 00:00:38 +0200 Subject: [PATCH 06/35] removed pre-kitkat code --- .../deckers/thibault/aves/MainActivity.kt | 34 ++++++++++++------- .../channel/calls/AccessibilityHandler.kt | 12 +++---- .../aves/channel/calls/AppAdapterHandler.kt | 9 +---- .../aves/channel/calls/DeviceHandler.kt | 1 - .../channel/calls/MetadataFetchHandler.kt | 26 +++++++------- .../streams/ActivityResultStreamHandler.kt | 15 +------- .../streams/SettingsChangeStreamHandler.kt | 23 +++++-------- .../metadata/MediaMetadataRetrieverHelper.kt | 10 +++--- .../thibault/aves/metadata/MultiPage.kt | 6 +--- .../thibault/aves/model/SourceEntry.kt | 7 +--- .../thibault/aves/utils/PermissionManager.kt | 7 +--- lib/model/device.dart | 5 +-- .../viewer/action/entry_action_delegate.dart | 2 +- 13 files changed, 58 insertions(+), 99 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt index b9b327b9a..06fec0e9f 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -142,6 +142,7 @@ open class MainActivity : FlutterFragmentActivity() { result.success(intentDataMap) intentDataMap.clear() } + "submitPickedItems" -> submitPickedItems(call) "submitPickedCollectionFilters" -> submitPickedCollectionFilters(call) } @@ -204,8 +205,10 @@ open class MainActivity : FlutterFragmentActivity() { DOCUMENT_TREE_ACCESS_REQUEST -> onDocumentTreeAccessResult(requestCode, resultCode, data) DELETE_SINGLE_PERMISSION_REQUEST, MEDIA_WRITE_BULK_PERMISSION_REQUEST -> onScopedStoragePermissionResult(resultCode) + CREATE_FILE_REQUEST, OPEN_FILE_REQUEST -> onStorageAccessResult(requestCode, data?.data) + PICK_COLLECTION_FILTERS_REQUEST -> onCollectionFiltersPickResult(resultCode, data) } } @@ -222,19 +225,17 @@ open class MainActivity : FlutterFragmentActivity() { return } - @SuppressLint("WrongConstant", "ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - val canPersist = (intent.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0 - if (canPersist) { - // save access permissions across reboots - val takeFlags = (intent.flags - and (Intent.FLAG_GRANT_READ_URI_PERMISSION - or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) - try { - contentResolver.takePersistableUriPermission(treeUri, takeFlags) - } catch (e: SecurityException) { - Log.w(LOG_TAG, "failed to take persistable URI permission for uri=$treeUri", e) - } + val canPersist = (intent.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0 + @SuppressLint("WrongConstant") + if (canPersist) { + // save access permissions across reboots + val takeFlags = (intent.flags + and (Intent.FLAG_GRANT_READ_URI_PERMISSION + or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) + try { + contentResolver.takePersistableUriPermission(treeUri, takeFlags) + } catch (e: SecurityException) { + Log.w(LOG_TAG, "failed to take persistable URI permission for uri=$treeUri", e) } } @@ -264,6 +265,7 @@ open class MainActivity : FlutterFragmentActivity() { ) } } + Intent.ACTION_VIEW, Intent.ACTION_SEND, "com.android.camera.action.REVIEW" -> { (intent.data ?: intent.getParcelableExtraCompat(Intent.EXTRA_STREAM))?.let { uri -> // MIME type is optional @@ -275,6 +277,7 @@ open class MainActivity : FlutterFragmentActivity() { ) } } + Intent.ACTION_GET_CONTENT, Intent.ACTION_PICK -> { return hashMapOf( INTENT_DATA_KEY_ACTION to INTENT_ACTION_PICK_ITEMS, @@ -282,6 +285,7 @@ open class MainActivity : FlutterFragmentActivity() { INTENT_DATA_KEY_ALLOW_MULTIPLE to (intent.extras?.getBoolean(Intent.EXTRA_ALLOW_MULTIPLE) ?: false), ) } + Intent.ACTION_SEARCH -> { val viewUri = intent.dataString return if (viewUri != null) hashMapOf( @@ -293,6 +297,7 @@ open class MainActivity : FlutterFragmentActivity() { INTENT_DATA_KEY_QUERY to intent.getStringExtra(SearchManager.QUERY), ) } + INTENT_ACTION_PICK_COLLECTION_FILTERS -> { val initialFilters = extractFiltersFromIntent(intent) return hashMapOf( @@ -300,6 +305,7 @@ open class MainActivity : FlutterFragmentActivity() { INTENT_DATA_KEY_FILTERS to initialFilters, ) } + INTENT_ACTION_WIDGET_OPEN -> { val widgetId = intent.getIntExtra(EXTRA_KEY_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID) if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { @@ -309,9 +315,11 @@ open class MainActivity : FlutterFragmentActivity() { ) } } + Intent.ACTION_RUN -> { // flutter run } + else -> { Log.w(LOG_TAG, "unhandled intent action=${intent?.action}") } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt index d44a5ed29..248fdcce1 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.channel.calls -import android.annotation.SuppressLint import android.content.Context import android.content.ContextWrapper import android.content.res.Configuration @@ -27,13 +26,10 @@ class AccessibilityHandler(private val contextWrapper: ContextWrapper) : MethodC private fun areAnimationsRemoved(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { var removed = false - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - try { - removed = Settings.Global.getFloat(contextWrapper.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) == 0f - } catch (e: Exception) { - Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) - } + try { + removed = Settings.Global.getFloat(contextWrapper.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) == 0f + } catch (e: Exception) { + Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) } result.success(removed) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt index 18921bfe6..e7c572270 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.channel.calls -import android.annotation.SuppressLint import android.content.* import android.content.pm.ApplicationInfo import android.content.res.Configuration @@ -69,13 +68,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { // apps tend to use their name in English when creating directories // so we get their names in English as well as the current locale val englishConfig = Configuration().apply { - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - setLocale(Locale.ENGLISH) - } else { - @Suppress("deprecation") - locale = Locale.ENGLISH - } + setLocale(Locale.ENGLISH) } val pm = context.packageManager diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt index 8a6a0b8d3..30348d57b 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt @@ -40,7 +40,6 @@ class DeviceHandler(private val context: Context) : MethodCallHandler { hashMapOf( "canGrantDirectoryAccess" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP), "canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context), - "canPrint" to (sdkInt >= Build.VERSION_CODES.KITKAT), "canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.M), "canRenderSubdivisionFlagEmojis" to (sdkInt >= Build.VERSION_CODES.O), "canRequestManageMedia" to (sdkInt >= Build.VERSION_CODES.S), diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt index feda79f93..8145c71cc 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.channel.calls -import android.annotation.SuppressLint import android.content.Context import android.media.MediaMetadataRetriever import android.net.Uri @@ -28,20 +27,30 @@ import com.drew.metadata.png.PngDirectory import com.drew.metadata.webp.WebpDirectory import com.drew.metadata.xmp.XmpDirectory import deckers.thibault.aves.channel.calls.Coresult.Companion.safe -import deckers.thibault.aves.metadata.* +import deckers.thibault.aves.metadata.ExifGeoTiffTags import deckers.thibault.aves.metadata.ExifInterfaceHelper.describeAll import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDateMillis import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDouble import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeInt import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeRational +import deckers.thibault.aves.metadata.ExifTags +import deckers.thibault.aves.metadata.GSpherical +import deckers.thibault.aves.metadata.GeoTiffKeys +import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeDateMillis import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeDescription import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeInt +import deckers.thibault.aves.metadata.Metadata import deckers.thibault.aves.metadata.Metadata.DIR_DNG import deckers.thibault.aves.metadata.Metadata.DIR_EXIF_GEOTIFF import deckers.thibault.aves.metadata.Metadata.DIR_PNG_TEXTUAL_DATA import deckers.thibault.aves.metadata.Metadata.getRotationDegreesForExifCode import deckers.thibault.aves.metadata.Metadata.isFlippedForExifCode +import deckers.thibault.aves.metadata.Mp4ParserHelper +import deckers.thibault.aves.metadata.MultiPage +import deckers.thibault.aves.metadata.PixyMetaHelper +import deckers.thibault.aves.metadata.QuickTimeMetadata +import deckers.thibault.aves.metadata.XMP import deckers.thibault.aves.metadata.XMP.doesPropExist import deckers.thibault.aves.metadata.XMP.getPropArrayItemValues import deckers.thibault.aves.metadata.XMP.getSafeDateMillis @@ -84,7 +93,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import org.json.JSONObject -import java.nio.charset.Charset import java.nio.charset.StandardCharsets import java.text.DecimalFormat import java.text.ParseException @@ -305,12 +313,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { val key = kv.key // `PNG-iTXt` uses UTF-8, contrary to `PNG-tEXt` and `PNG-zTXt` using Latin-1 / ISO-8859-1 val charset = if (baseDirName == PNG_ITXT_DIR_NAME) { - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - StandardCharsets.UTF_8 - } else { - Charset.forName("UTF-8") - } + StandardCharsets.UTF_8 } else { kv.value.charset } @@ -747,10 +750,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { var flags = (metadataMap[KEY_FLAGS] ?: 0) as Int try { - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { metadataMap[KEY_ROTATION_DEGREES] = it } - } + retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { metadataMap[KEY_ROTATION_DEGREES] = it } if (!metadataMap.containsKey(KEY_DATE_MILLIS)) { retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { metadataMap[KEY_DATE_MILLIS] = it } } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt index c5f319dd2..01fa3fa68 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.channel.streams -import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.net.Uri @@ -77,7 +76,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any private fun requestMediaFileAccess() { val uris = (args["uris"] as List<*>?)?.mapNotNull { if (it is String) Uri.parse(it) else null } val mimeTypes = (args["mimeTypes"] as List<*>?)?.mapNotNull { if (it is String) it else null } - if (uris == null || uris.isEmpty() || mimeTypes == null || mimeTypes.size != uris.size) { + if (uris.isNullOrEmpty() || mimeTypes == null || mimeTypes.size != uris.size) { error("requestMediaFileAccess-args", "missing arguments", null) return } @@ -112,12 +111,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any } private suspend fun createFile() { - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - error("createFile-sdk", "unsupported SDK version=${Build.VERSION.SDK_INT}", null) - return - } - val name = args["name"] as String? val mimeType = args["mimeType"] as String? val bytes = args["bytes"] as ByteArray? @@ -155,12 +148,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any } private suspend fun openFile() { - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - error("openFile-sdk", "unsupported SDK version=${Build.VERSION.SDK_INT}", null) - return - } - val mimeType = args["mimeType"] as String? // optional fun onGranted(uri: Uri) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt index 77a753bfc..dd1c94e19 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt @@ -34,14 +34,12 @@ class SettingsChangeStreamHandler(private val context: Context) : EventChannel.S override fun onChange(selfChange: Boolean, uri: Uri?) { if (update()) { - val settings: FieldMap = hashMapOf( - Settings.System.ACCELEROMETER_ROTATION to accelerometerRotation, + success( + hashMapOf( + Settings.System.ACCELEROMETER_ROTATION to accelerometerRotation, + Settings.Global.TRANSITION_ANIMATION_SCALE to transitionAnimationScale, + ) ) - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - settings[Settings.Global.TRANSITION_ANIMATION_SCALE] = transitionAnimationScale - } - success(settings) } } @@ -53,13 +51,10 @@ class SettingsChangeStreamHandler(private val context: Context) : EventChannel.S accelerometerRotation = newAccelerometerRotation changed = true } - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - val newTransitionAnimationScale = Settings.Global.getFloat(context.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) - if (transitionAnimationScale != newTransitionAnimationScale) { - transitionAnimationScale = newTransitionAnimationScale - changed = true - } + val newTransitionAnimationScale = Settings.Global.getFloat(context.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) + if (transitionAnimationScale != newTransitionAnimationScale) { + transitionAnimationScale = newTransitionAnimationScale + changed = true } } catch (e: Exception) { Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MediaMetadataRetrieverHelper.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MediaMetadataRetrieverHelper.kt index cfde73855..2c2616177 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MediaMetadataRetrieverHelper.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MediaMetadataRetrieverHelper.kt @@ -1,11 +1,12 @@ package deckers.thibault.aves.metadata -import android.annotation.SuppressLint import android.media.MediaFormat import android.media.MediaMetadataRetriever import android.os.Build import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale +import java.util.TimeZone object MediaMetadataRetrieverHelper { val allKeys = hashMapOf( @@ -31,11 +32,8 @@ object MediaMetadataRetrieverHelper { MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH to "Video Width", MediaMetadataRetriever.METADATA_KEY_WRITER to "Writer", MediaMetadataRetriever.METADATA_KEY_YEAR to "Year", + MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION to "Video Rotation", ).apply { - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - put(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION, "Video Rotation") - } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { put(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE, "Capture Framerate") } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt index 1693c4bab..25f1bab85 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.metadata -import android.annotation.SuppressLint import android.content.Context import android.media.MediaExtractor import android.media.MediaFormat @@ -63,10 +62,7 @@ object MultiPage { format.getSafeInt(MediaFormat.KEY_WIDTH) { track[KEY_WIDTH] = it } format.getSafeInt(MediaFormat.KEY_HEIGHT) { track[KEY_HEIGHT] = it } - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - format.getSafeInt(MediaFormat.KEY_IS_DEFAULT) { track[KEY_IS_DEFAULT] = it != 0 } - } + format.getSafeInt(MediaFormat.KEY_IS_DEFAULT) { track[KEY_IS_DEFAULT] = it != 0 } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { format.getSafeInt(MediaFormat.KEY_ROTATION) { track[KEY_ROTATION_DEGREES] = it } } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt index e858c03e4..3fbb68b33 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/SourceEntry.kt @@ -1,12 +1,10 @@ package deckers.thibault.aves.model -import android.annotation.SuppressLint import android.content.ContentResolver import android.content.Context import android.graphics.BitmapFactory import android.media.MediaMetadataRetriever import android.net.Uri -import android.os.Build import androidx.exifinterface.media.ExifInterface import com.drew.metadata.avi.AviDirectory import com.drew.metadata.exif.ExifIFD0Directory @@ -147,10 +145,7 @@ class SourceEntry { retriever.getSafeLong(MediaMetadataRetriever.METADATA_KEY_DURATION) { durationMillis = it } retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { sourceDateTakenMillis = it } retriever.getSafeString(MediaMetadataRetriever.METADATA_KEY_TITLE) { title = it } - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { sourceRotationDegrees = it } - } + retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { sourceRotationDegrees = it } } catch (e: Exception) { // ignore } finally { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt index 6863489fd..91e5dd4d5 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/PermissionManager.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.utils -import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.content.Intent @@ -177,14 +176,10 @@ object PermissionManager { val accessibleDirs = HashSet(getGrantedDirs(context)) accessibleDirs.addAll(context.getExternalFilesDirs(null).filterNotNull().map { it.path }) - // until API 18 / Android 4.3 / Jelly Bean MR2, removable storage is accessible by default like primary storage // from API 19 / Android 4.4 / KitKat, removable storage requires access permission, at the file level // from API 21 / Android 5.0 / Lollipop, removable storage requires access permission, but directory access grant is possible // from API 30 / Android 11 / R, any storage requires access permission - @SuppressLint("ObsoleteSdkInt") - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) { - accessibleDirs.addAll(StorageUtils.getVolumePaths(context)) - } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { accessibleDirs.add(StorageUtils.getPrimaryVolumePath(context)) } return accessibleDirs diff --git a/lib/model/device.dart b/lib/model/device.dart index 2b431ac87..c70c1d8ed 100644 --- a/lib/model/device.dart +++ b/lib/model/device.dart @@ -9,7 +9,7 @@ final Device device = Device._private(); class Device { late final String _userAgent; - late final bool _canAuthenticateUser, _canGrantDirectoryAccess, _canPinShortcut, _canPrint; + late final bool _canAuthenticateUser, _canGrantDirectoryAccess, _canPinShortcut; late final bool _canRenderFlagEmojis, _canRenderSubdivisionFlagEmojis, _canRequestManageMedia, _canSetLockScreenWallpaper, _canUseCrypto; late final bool _hasGeocoder, _isDynamicColorAvailable, _isTelevision, _showPinShortcutFeedback, _supportEdgeToEdgeUIMode, _supportPictureInPicture; @@ -21,8 +21,6 @@ class Device { bool get canPinShortcut => _canPinShortcut; - bool get canPrint => _canPrint; - bool get canRenderFlagEmojis => _canRenderFlagEmojis; bool get canRenderSubdivisionFlagEmojis => _canRenderSubdivisionFlagEmojis; @@ -71,7 +69,6 @@ class Device { final capabilities = await deviceService.getCapabilities(); _canGrantDirectoryAccess = capabilities['canGrantDirectoryAccess'] ?? false; _canPinShortcut = capabilities['canPinShortcut'] ?? false; - _canPrint = capabilities['canPrint'] ?? false; _canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false; _canRenderSubdivisionFlagEmojis = capabilities['canRenderSubdivisionFlagEmojis'] ?? false; _canRequestManageMedia = capabilities['canRequestManageMedia'] ?? false; diff --git a/lib/widgets/viewer/action/entry_action_delegate.dart b/lib/widgets/viewer/action/entry_action_delegate.dart index 3f8812c78..d4e099a93 100644 --- a/lib/widgets/viewer/action/entry_action_delegate.dart +++ b/lib/widgets/viewer/action/entry_action_delegate.dart @@ -82,7 +82,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix case EntryAction.convert: return canWrite && !targetEntry.isVideo; case EntryAction.print: - return device.canPrint && !targetEntry.isVideo; + return !targetEntry.isVideo; case EntryAction.openMap: return !settings.useTvLayout && targetEntry.hasGps; case EntryAction.viewSource: From 3a5c19f7d6e429b17471fd4ad7f1763bdfc4e37e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 00:45:22 +0200 Subject: [PATCH 07/35] android: cleanup --- .../aves/channel/calls/AnalysisHandler.kt | 2 - .../aves/channel/calls/GeocodingHandler.kt | 28 ++--------- .../aves/channel/calls/GlobalSearchHandler.kt | 7 +-- .../channel/calls/fetchers/RegionFetcher.kt | 10 +--- .../deckers/thibault/aves/utils/Compat.kt | 46 +++++++++++++++++++ 5 files changed, 57 insertions(+), 36 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt index f0f020287..e44d0e5b8 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt @@ -1,6 +1,5 @@ package deckers.thibault.aves.channel.calls -import android.annotation.SuppressLint import android.app.Activity import android.content.ComponentName import android.content.Context @@ -32,7 +31,6 @@ class AnalysisHandler(private val activity: Activity, private val onAnalysisComp } } - @SuppressLint("CommitPrefEdits") private fun registerCallback(call: MethodCall, result: MethodChannel.Result) { val callbackHandle = call.argument("callbackHandle")?.toLong() if (callbackHandle == null) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt index 7fac5c664..6af0642e2 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt @@ -3,8 +3,8 @@ package deckers.thibault.aves.channel.calls import android.content.Context import android.location.Address import android.location.Geocoder -import android.os.Build import deckers.thibault.aves.channel.calls.Coresult.Companion.safe +import deckers.thibault.aves.utils.getFromLocationCompat import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler @@ -12,8 +12,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch -import java.io.IOException -import java.util.* +import java.util.Locale // as of 2021/03/10, geocoding packages exist but: // - `geocoder` is unmaintained @@ -76,26 +75,9 @@ class GeocodingHandler(private val context: Context) : MethodCallHandler { } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - geocoder!!.getFromLocation(latitude, longitude, maxResults, object : Geocoder.GeocodeListener { - override fun onGeocode(addresses: List) = processAddresses(addresses.filterNotNull()) - - override fun onError(errorMessage: String?) { - result.error("getAddress-asyncerror", "failed to get address", errorMessage) - } - }) - } else { - try { - @Suppress("deprecation") - val addresses = geocoder!!.getFromLocation(latitude, longitude, maxResults) ?: ArrayList() - processAddresses(addresses) - } catch (e: IOException) { - // `grpc failed`, etc. - result.error("getAddress-network", "failed to get address because of network issues", e.message) - } catch (e: Exception) { - result.error("getAddress-exception", "failed to get address", e.message) - } - } + geocoder!!.getFromLocationCompat( + latitude, longitude, maxResults, ::processAddresses, + ) { code, message, details -> result.error(code, message, details) } } companion object { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt index d0d7767e9..c614ab6ea 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt @@ -1,13 +1,15 @@ package deckers.thibault.aves.channel.calls -import android.annotation.SuppressLint import android.content.Context import deckers.thibault.aves.SearchSuggestionsProvider import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch class GlobalSearchHandler(private val context: Context) : MethodCallHandler { private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) @@ -19,7 +21,6 @@ class GlobalSearchHandler(private val context: Context) : MethodCallHandler { } } - @SuppressLint("CommitPrefEdits") private fun registerCallback(call: MethodCall, result: MethodChannel.Result) { val callbackHandle = call.argument("callbackHandle")?.toLong() if (callbackHandle == null) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt index a022bfd8d..60276c136 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt @@ -6,12 +6,12 @@ import android.graphics.BitmapFactory import android.graphics.BitmapRegionDecoder import android.graphics.Rect import android.net.Uri -import android.os.Build import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import deckers.thibault.aves.decoder.MultiTrackImage +import deckers.thibault.aves.utils.BitmapRegionDecoderCompat import deckers.thibault.aves.utils.BitmapUtils.getBytes import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.StorageUtils @@ -68,13 +68,7 @@ class RegionFetcher internal constructor( try { if (currentDecoderRef == null) { val newDecoder = StorageUtils.openInputStream(context, uri)?.use { input -> - @Suppress("BlockingMethodInNonBlockingContext") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - BitmapRegionDecoder.newInstance(input) - } else { - @Suppress("deprecation") - BitmapRegionDecoder.newInstance(input, false) - } + BitmapRegionDecoderCompat.newInstance(input) } if (newDecoder == null) { result.error("getRegion-read-null", "failed to open file for mimeType=$mimeType uri=$uri regionRect=$regionRect", null) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/Compat.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/Compat.kt index 4aa362a1b..fb75f47ff 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/Compat.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/Compat.kt @@ -5,9 +5,14 @@ import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.content.pm.ResolveInfo +import android.graphics.BitmapRegionDecoder +import android.location.Address +import android.location.Geocoder import android.os.Build import android.os.Parcelable import android.view.Display +import java.io.IOException +import java.io.InputStream inline fun Intent.getParcelableExtraCompat(name: String): T? { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { @@ -44,3 +49,44 @@ fun PackageManager.queryIntentActivitiesCompat(intent: Intent, flags: Int): List queryIntentActivities(intent, flags) } } + +fun Geocoder.getFromLocationCompat( + latitude: Double, + longitude: Double, + maxResults: Int, + processAddresses: (addresses: List
) -> Unit, + onError: (errorCode: String, errorMessage: String?, errorDetails: Any?) -> Unit, +) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + getFromLocation(latitude, longitude, maxResults, object : Geocoder.GeocodeListener { + override fun onGeocode(addresses: List) = processAddresses(addresses.filterNotNull()) + + override fun onError(errorMessage: String?) { + onError("getAddress-asyncerror", "failed to get address", errorMessage) + } + }) + } else { + try { + @Suppress("deprecation") + val addresses = getFromLocation(latitude, longitude, maxResults) ?: ArrayList() + processAddresses(addresses) + } catch (e: IOException) { + // `grpc failed`, etc. + onError("getAddress-network", "failed to get address because of network issues", e.message) + } catch (e: Exception) { + onError("getAddress-exception", "failed to get address", e.message) + } + } +} + +object BitmapRegionDecoderCompat { + @Throws(IOException::class) + fun newInstance(input: InputStream): BitmapRegionDecoder? { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + BitmapRegionDecoder.newInstance(input) + } else { + @Suppress("deprecation") + BitmapRegionDecoder.newInstance(input, false) + } + } +} From 17ac257f0c588050c49dc1d4a18e459dba3211d9 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 01:14:29 +0200 Subject: [PATCH 08/35] android: cleanup --- .../thibault/aves/channel/calls/AppAdapterHandler.kt | 5 +++-- .../thibault/aves/channel/calls/EmbeddedDataHandler.kt | 1 - .../aves/channel/streams/ActivityResultStreamHandler.kt | 1 - .../aves/channel/streams/ImageByteStreamHandler.kt | 7 +++---- .../deckers/thibault/aves/model/provider/ImageProvider.kt | 8 ++++---- .../aves/model/provider/MediaStoreImageProvider.kt | 2 -- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt index e7c572270..2ec3c761e 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt @@ -39,6 +39,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.io.File import java.util.* import kotlin.math.roundToInt @@ -162,8 +163,8 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { .submit(size, size) try { - @Suppress("BlockingMethodInNonBlockingContext") - data = target.get()?.getBytes(canHaveAlpha = true, recycle = false) + val bitmap = withContext(Dispatchers.IO) { target.get() } + data = bitmap?.getBytes(canHaveAlpha = true, recycle = false) } catch (e: Exception) { Log.w(LOG_TAG, "failed to decode app icon for packageName=$packageName", e) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt index d42e5ea50..028d4fec3 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt @@ -64,7 +64,6 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { if (canReadWithExifInterface(mimeType)) { try { Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input -> - @Suppress("BlockingMethodInNonBlockingContext") val exif = ExifInterface(input) val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) exif.thumbnailBitmap?.let { bitmap -> diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt index 01fa3fa68..e9301a1f9 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt @@ -206,7 +206,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any } } - @Suppress("SameParameterValue") private fun error(errorCode: String, errorMessage: String, errorDetails: Any?) { handler.post { try { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt index 2cf3654cc..c140996d2 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt @@ -28,6 +28,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.io.InputStream class ImageByteStreamHandler(private val context: Context, private val arguments: Any?) : EventChannel.StreamHandler { @@ -144,8 +145,7 @@ class ImageByteStreamHandler(private val context: Context, private val arguments .load(model) .submit() try { - @Suppress("BlockingMethodInNonBlockingContext") - var bitmap = target.get() + var bitmap = withContext(Dispatchers.IO) { target.get() } if (needRotationAfterGlide(mimeType)) { bitmap = applyExifOrientation(context, bitmap, rotationDegrees, isFlipped) } @@ -173,8 +173,7 @@ class ImageByteStreamHandler(private val context: Context, private val arguments .load(VideoThumbnail(context, uri)) .submit() try { - @Suppress("BlockingMethodInNonBlockingContext") - val bitmap = target.get() + val bitmap = withContext(Dispatchers.IO) { target.get() } if (bitmap != null) { val bytes = bitmap.getBytes(canHaveAlpha = false, recycle = false) if (MemoryUtils.canAllocate(sizeBytes)) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt index f6c00b475..c6b825258 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt @@ -45,6 +45,8 @@ import deckers.thibault.aves.utils.MimeTypes.canReadWithPixyMeta import deckers.thibault.aves.utils.MimeTypes.canRemoveMetadata import deckers.thibault.aves.utils.MimeTypes.extensionFor import deckers.thibault.aves.utils.MimeTypes.isVideo +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import pixy.meta.meta.Metadata import pixy.meta.meta.MetadataType import java.io.* @@ -308,8 +310,7 @@ abstract class ImageProvider { .apply(glideOptions) .load(model) .submit(targetWidthPx, targetHeightPx) - @Suppress("BlockingMethodInNonBlockingContext") - var bitmap = target.get() + var bitmap = withContext(Dispatchers.IO) { target.get() } if (MimeTypes.needRotationAfterGlide(sourceMimeType)) { bitmap = BitmapUtils.applyExifOrientation(activity, bitmap, sourceEntry.rotationDegrees, sourceEntry.isFlipped) } @@ -457,7 +458,6 @@ abstract class ImageProvider { editableFile.delete() } - @Suppress("BlockingMethodInNonBlockingContext") suspend fun captureFrame( contextWrapper: ContextWrapper, desiredNameWithoutExtension: String, @@ -512,7 +512,7 @@ abstract class ImageProvider { output.write(bytes) } } else { - val editableFile = File.createTempFile("aves", null).apply { + val editableFile = withContext(Dispatchers.IO) { File.createTempFile("aves", null) }.apply { deleteOnExit() transferFrom(ByteArrayInputStream(bytes), bytes.size.toLong()) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt index 3983ff52e..1dd700ebf 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/MediaStoreImageProvider.kt @@ -328,7 +328,6 @@ class MediaStoreImageProvider : ImageProvider() { Log.d(LOG_TAG, "delete [permission:doc, file exists after content delete] document at uri=$uri path=$path") val df = StorageUtils.getDocumentFile(contextWrapper, path, uri) - @Suppress("BlockingMethodInNonBlockingContext") if (df != null && df.delete()) { scanObsoletePath(contextWrapper, uri, path, mimeType) return @@ -726,7 +725,6 @@ class MediaStoreImageProvider : ImageProvider() { val df = StorageUtils.getDocumentFile(activity, oldPath, oldMediaUri) df ?: throw Exception("failed to get document at path=$oldPath") - @Suppress("BlockingMethodInNonBlockingContext") val renamed = df.renameTo(newFile.name) if (!renamed) { throw Exception("failed to rename document at path=$oldPath") From 1f0c46db074244d8448e4bf0ca90162a28c19fa6 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 01:45:24 +0200 Subject: [PATCH 09/35] android: cleanup --- .../calls/window/ActivityWindowHandler.kt | 6 +++--- .../calls/window/ServiceWindowHandler.kt | 4 ++-- .../channel/calls/window/WindowHandler.kt | 2 +- .../streams/SettingsChangeStreamHandler.kt | 2 -- .../aves/metadata/GoogleDeviceContainer.kt | 2 +- .../metadataextractor/SafeMp4BoxHandler.kt | 4 +--- .../SafePngMetadataReader.kt | 21 +++++++++++++++---- .../metadataextractor/SafeXmpReader.kt | 4 +--- 8 files changed, 26 insertions(+), 19 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt index 1f6590dd6..bf4c37bcd 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ActivityWindowHandler.kt @@ -8,7 +8,7 @@ import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel class ActivityWindowHandler(private val activity: Activity) : WindowHandler(activity) { - override fun isActivity(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { + override fun isActivity(call: MethodCall, result: MethodChannel.Result) { result.success(true) } @@ -49,11 +49,11 @@ class ActivityWindowHandler(private val activity: Activity) : WindowHandler(acti result.success(true) } - override fun isCutoutAware(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { + override fun isCutoutAware(call: MethodCall, result: MethodChannel.Result) { result.success(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) } - override fun getCutoutInsets(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { + override fun getCutoutInsets(call: MethodCall, result: MethodChannel.Result) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { result.error("getCutoutInsets-sdk", "unsupported SDK version=${Build.VERSION.SDK_INT}", null) return diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ServiceWindowHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ServiceWindowHandler.kt index 3a50fd324..1332bbb9a 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ServiceWindowHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/ServiceWindowHandler.kt @@ -5,7 +5,7 @@ import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel class ServiceWindowHandler(service: Service) : WindowHandler(service) { - override fun isActivity(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { + override fun isActivity(call: MethodCall, result: MethodChannel.Result) { result.success(false) } @@ -21,7 +21,7 @@ class ServiceWindowHandler(service: Service) : WindowHandler(service) { result.success(false) } - override fun isCutoutAware(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { + override fun isCutoutAware(call: MethodCall, result: MethodChannel.Result) { result.success(false) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/WindowHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/WindowHandler.kt index 492c6deeb..11472d6a5 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/WindowHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/window/WindowHandler.kt @@ -40,7 +40,7 @@ abstract class WindowHandler(private val contextWrapper: ContextWrapper) : Metho abstract fun requestOrientation(call: MethodCall, result: MethodChannel.Result) - abstract fun isCutoutAware(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) + abstract fun isCutoutAware(call: MethodCall, result: MethodChannel.Result) abstract fun getCutoutInsets(call: MethodCall, result: MethodChannel.Result) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt index dd1c94e19..b29b8d4f2 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt @@ -1,10 +1,8 @@ package deckers.thibault.aves.channel.streams -import android.annotation.SuppressLint import android.content.Context import android.database.ContentObserver import android.net.Uri -import android.os.Build import android.os.Handler import android.os.Looper import android.provider.Settings diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/GoogleDeviceContainer.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/GoogleDeviceContainer.kt index a481c94e4..60b74a507 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/GoogleDeviceContainer.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/GoogleDeviceContainer.kt @@ -81,4 +81,4 @@ class GoogleDeviceContainer { fun itemMimeType(index: Int) = item(index)?.mimeType } -class GoogleDeviceContainerItem(val mimeType: String, val length: Long, val dataUri: String) {} +class GoogleDeviceContainerItem(val mimeType: String, val length: Long, val dataUri: String) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeMp4BoxHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeMp4BoxHandler.kt index 2e6bebb3b..b4e83772c 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeMp4BoxHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeMp4BoxHandler.kt @@ -1,8 +1,6 @@ package deckers.thibault.aves.metadata.metadataextractor import com.drew.imaging.mp4.Mp4Handler -import com.drew.lang.annotations.NotNull -import com.drew.lang.annotations.Nullable import com.drew.metadata.Metadata import com.drew.metadata.mp4.Mp4BoxHandler import com.drew.metadata.mp4.Mp4BoxTypes @@ -11,7 +9,7 @@ import java.io.IOException class SafeMp4BoxHandler(metadata: Metadata) : Mp4BoxHandler(metadata) { @Throws(IOException::class) - override fun processBox(@NotNull type: String, @Nullable payload: ByteArray?, boxSize: Long, context: Mp4Context?): Mp4Handler<*>? { + override fun processBox(type: String, payload: ByteArray?, boxSize: Long, context: Mp4Context?): Mp4Handler<*>? { if (payload != null && type == Mp4BoxTypes.BOX_USER_DEFINED) { val userBoxHandler = SafeMp4UuidBoxHandler(metadata) userBoxHandler.processBox(type, payload, boxSize, context) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt index 1f2cc1dd5..1012a6477 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt @@ -1,11 +1,24 @@ package deckers.thibault.aves.metadata.metadataextractor import android.util.Log -import com.drew.imaging.png.* +import com.drew.imaging.png.PngChromaticities +import com.drew.imaging.png.PngChunk +import com.drew.imaging.png.PngChunkReader +import com.drew.imaging.png.PngChunkType +import com.drew.imaging.png.PngHeader +import com.drew.imaging.png.PngProcessingException import com.drew.imaging.tiff.TiffProcessingException import com.drew.imaging.tiff.TiffReader -import com.drew.lang.* -import com.drew.lang.annotations.NotNull +import com.drew.lang.ByteArrayReader +import com.drew.lang.ByteConvert +import com.drew.lang.Charsets +import com.drew.lang.DateUtil +import com.drew.lang.KeyValuePair +import com.drew.lang.RandomAccessStreamReader +import com.drew.lang.SequentialByteArrayReader +import com.drew.lang.SequentialReader +import com.drew.lang.StreamReader +import com.drew.lang.StreamUtil import com.drew.metadata.ErrorDirectory import com.drew.metadata.Metadata import com.drew.metadata.StringValue @@ -64,7 +77,7 @@ object SafePngMetadataReader { } @Throws(PngProcessingException::class, IOException::class) - private fun processChunk(@NotNull metadata: Metadata, @NotNull chunk: PngChunk) { + private fun processChunk(metadata: Metadata, chunk: PngChunk) { val chunkType = chunk.type val bytes = chunk.bytes diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt index ac07d9967..8eb67202e 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt @@ -10,8 +10,6 @@ import com.adobe.internal.xmp.properties.XMPPropertyInfo import com.drew.imaging.jpeg.JpegSegmentType import com.drew.lang.SequentialByteArrayReader import com.drew.lang.SequentialReader -import com.drew.lang.annotations.NotNull -import com.drew.lang.annotations.Nullable import com.drew.metadata.Directory import com.drew.metadata.Metadata import com.drew.metadata.xmp.XmpDirectory @@ -63,7 +61,7 @@ class SafeXmpReader : XmpReader() { } // adapted from `XmpReader` to provide different parsing options - override fun extract(@NotNull xmpBytes: ByteArray, offset: Int, length: Int, @NotNull metadata: Metadata, @Nullable parentDirectory: Directory?) { + override fun extract(xmpBytes: ByteArray, offset: Int, length: Int, metadata: Metadata, parentDirectory: Directory?) { val directory = XmpDirectory() if (parentDirectory != null) directory.parent = parentDirectory From 7f57a5172e7b81207846d1166f920b6ee6110757 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 12:43:33 +0200 Subject: [PATCH 10/35] android: strict mode fixes --- android/app/src/main/AndroidManifest.xml | 16 ++++++++++++--- lib/model/app/dependencies.dart | 20 +++++++++---------- .../AvesScreenStatePlugin.kt | 4 ++-- pubspec.lock | 4 ++-- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 5b85aa256..67d85efed 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -19,14 +19,18 @@ This change eventually prevents building the app with Flutter v3.7.11. android:required="false" /> + + @@ -245,7 +254,8 @@ This change eventually prevents building the app with Flutter v3.7.11. + android:exported="false" + android:foregroundServiceType="dataSync" /> Date: Mon, 8 May 2023 14:00:08 +0200 Subject: [PATCH 11/35] #539 viewer: adjusted spring stiffness for vertical pager --- lib/widgets/viewer/entry_vertical_pager.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/viewer/entry_vertical_pager.dart b/lib/widgets/viewer/entry_vertical_pager.dart index f03de1f69..f48286da9 100644 --- a/lib/widgets/viewer/entry_vertical_pager.dart +++ b/lib/widgets/viewer/entry_vertical_pager.dart @@ -41,7 +41,7 @@ class ViewerVerticalPageView extends StatefulWidget { // critically damped spring a bit stiffer than `ScrollPhysics._kDefaultSpring` static final spring = SpringDescription.withDampingRatio( mass: 0.5, - stiffness: 200.0, + stiffness: 140.0, ratio: 1.0, ); From c94fc7245ee0198dd7b23e3925dcfd511137f66e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 18:42:18 +0200 Subject: [PATCH 12/35] minor --- android/app/build.gradle | 32 +++---- android/build.gradle | 9 +- plugins/aves_magnifier/pubspec.yaml | 2 +- plugins/aves_map/pubspec.yaml | 2 +- plugins/aves_model/pubspec.yaml | 2 +- plugins/aves_platform_meta/pubspec.yaml | 2 +- plugins/aves_report/pubspec.yaml | 2 +- plugins/aves_report_console/pubspec.yaml | 2 +- plugins/aves_report_crashlytics/pubspec.yaml | 2 +- plugins/aves_screen_state/.gitignore | 2 +- plugins/aves_screen_state/pubspec.lock | 87 ++++++++++++++++++++ plugins/aves_screen_state/pubspec.yaml | 2 +- plugins/aves_services/pubspec.yaml | 2 +- plugins/aves_services_google/pubspec.yaml | 2 +- plugins/aves_services_huawei/pubspec.yaml | 2 +- plugins/aves_services_none/pubspec.yaml | 2 +- plugins/aves_ui/pubspec.yaml | 2 +- plugins/aves_utils/pubspec.yaml | 2 +- plugins/aves_video/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 20 files changed, 126 insertions(+), 36 deletions(-) create mode 100644 plugins/aves_screen_state/pubspec.lock diff --git a/android/app/build.gradle b/android/app/build.gradle index 575f5c986..95b53c724 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -36,12 +36,12 @@ if (keystorePropertiesFile.exists()) { // for release using credentials in environment variables set up by GitHub Actions // warning: in property file, single quotes should be escaped with a backslash // but they should not be escaped when stored in env variables - keystoreProperties['storeFile'] = System.getenv('AVES_STORE_FILE') ?: '' - keystoreProperties['storePassword'] = System.getenv('AVES_STORE_PASSWORD') ?: '' - keystoreProperties['keyAlias'] = System.getenv('AVES_KEY_ALIAS') ?: '' - keystoreProperties['keyPassword'] = System.getenv('AVES_KEY_PASSWORD') ?: '' - keystoreProperties['googleApiKey'] = System.getenv('AVES_GOOGLE_API_KEY') ?: '' - keystoreProperties['huaweiApiKey'] = System.getenv('AVES_HUAWEI_API_KEY') ?: '' + keystoreProperties["storeFile"] = System.getenv("AVES_STORE_FILE") ?: "" + keystoreProperties["storePassword"] = System.getenv("AVES_STORE_PASSWORD") ?: "" + keystoreProperties["keyAlias"] = System.getenv("AVES_KEY_ALIAS") ?: "" + keystoreProperties["keyPassword"] = System.getenv("AVES_KEY_PASSWORD") ?: "" + keystoreProperties["googleApiKey"] = System.getenv("AVES_GOOGLE_API_KEY") ?: "" + keystoreProperties["huaweiApiKey"] = System.getenv("AVES_HUAWEI_API_KEY") ?: "" } android { @@ -80,21 +80,21 @@ android { targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName - manifestPlaceholders = [googleApiKey: keystoreProperties['googleApiKey'] ?: '', - huaweiApiKey: keystoreProperties['huaweiApiKey'] ?: ''] + manifestPlaceholders = [googleApiKey: keystoreProperties["googleApiKey"] ?: "", + huaweiApiKey: keystoreProperties["huaweiApiKey"] ?: ""] multiDexEnabled true } signingConfigs { release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] + keyAlias keystoreProperties["keyAlias"] + keyPassword keystoreProperties["keyPassword"] + storeFile keystoreProperties["storeFile"] ? file(keystoreProperties["storeFile"]) : null + storePassword keystoreProperties["storePassword"] } } - flavorDimensions "store" + flavorDimensions = ["store"] productFlavors { play { @@ -208,7 +208,7 @@ dependencies { implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.commonsware.cwac:document:0.5.0' implementation 'com.drewnoakes:metadata-extractor:2.18.0' - implementation 'com.github.bumptech.glide:glide:4.15.1' + implementation "com.github.bumptech.glide:glide:$glide_version" // SLF4J implementation for `mp4parser` implementation 'org.slf4j:slf4j-simple:2.0.7' @@ -222,10 +222,10 @@ dependencies { implementation 'com.github.deckerst:pixymeta-android:706bd73d6e' // huawei flavor only - huaweiImplementation 'com.huawei.agconnect:agconnect-core:1.8.0.300' + huaweiImplementation "com.huawei.agconnect:agconnect-core:$huawei_agconnect_version" kapt 'androidx.annotation:annotation:1.6.0' - kapt 'com.github.bumptech.glide:compiler:4.15.1' + kapt "com.github.bumptech.glide:compiler:$glide_version" compileOnly rootProject.findProject(':streams_channel') } diff --git a/android/build.gradle b/android/build.gradle index c9ccd0367..d06c9b9c7 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,6 +1,9 @@ buildscript { ext { kotlin_version = '1.8.0' + agp_version = '7.4.2' + glide_version = '4.15.1' + huawei_agconnect_version = '1.8.0.300' abiCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3, 'x86_64': 4] useCrashlytics = gradle.startParameter.taskNames.any { task -> task.containsIgnoreCase("play") } useHms = gradle.startParameter.taskNames.any { task -> task.containsIgnoreCase("huawei") } @@ -17,7 +20,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath "com.android.tools.build:gradle:$agp_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" if (useCrashlytics) { @@ -28,7 +31,7 @@ buildscript { if (useHms) { // HMS (used by some flavors only) - classpath 'com.huawei.agconnect:agcp:1.8.0.300' + classpath "com.huawei.agconnect:agcp:$huawei_agconnect_version" } } } @@ -57,6 +60,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register('clean', Delete) { delete rootProject.buildDir } diff --git a/plugins/aves_magnifier/pubspec.yaml b/plugins/aves_magnifier/pubspec.yaml index 14f197fcd..a45d38ae6 100644 --- a/plugins/aves_magnifier/pubspec.yaml +++ b/plugins/aves_magnifier/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_map/pubspec.yaml b/plugins/aves_map/pubspec.yaml index 8f325c421..25099293f 100644 --- a/plugins/aves_map/pubspec.yaml +++ b/plugins/aves_map/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_model/pubspec.yaml b/plugins/aves_model/pubspec.yaml index e07e9d4d0..4ce8c1284 100644 --- a/plugins/aves_model/pubspec.yaml +++ b/plugins/aves_model/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: '>=2.19.6 <3.0.0' + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_platform_meta/pubspec.yaml b/plugins/aves_platform_meta/pubspec.yaml index 67620cb1d..7bfc472b6 100644 --- a/plugins/aves_platform_meta/pubspec.yaml +++ b/plugins/aves_platform_meta/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_report/pubspec.yaml b/plugins/aves_report/pubspec.yaml index 14de85cf7..638daa043 100644 --- a/plugins/aves_report/pubspec.yaml +++ b/plugins/aves_report/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_report_console/pubspec.yaml b/plugins/aves_report_console/pubspec.yaml index 93fde45cf..337e24999 100644 --- a/plugins/aves_report_console/pubspec.yaml +++ b/plugins/aves_report_console/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_report_crashlytics/pubspec.yaml b/plugins/aves_report_crashlytics/pubspec.yaml index 1740651b8..2a4875ff3 100644 --- a/plugins/aves_report_crashlytics/pubspec.yaml +++ b/plugins/aves_report_crashlytics/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_screen_state/.gitignore b/plugins/aves_screen_state/.gitignore index 96486fd93..28124a571 100644 --- a/plugins/aves_screen_state/.gitignore +++ b/plugins/aves_screen_state/.gitignore @@ -23,7 +23,7 @@ migrate_working_dir/ # Flutter/Dart/Pub related # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. -/pubspec.lock +#/pubspec.lock **/doc/api/ .dart_tool/ .packages diff --git a/plugins/aves_screen_state/pubspec.lock b/plugins/aves_screen_state/pubspec.lock new file mode 100644 index 000000000..10b974b12 --- /dev/null +++ b/plugins/aves_screen_state/pubspec.lock @@ -0,0 +1,87 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" + source: hosted + version: "2.0.1" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + lints: + dependency: transitive + description: + name: lints + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + plugin_platform_interface: + dependency: "direct main" + description: + name: plugin_platform_interface + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" +sdks: + dart: ">=2.19.6 <3.0.0" diff --git a/plugins/aves_screen_state/pubspec.yaml b/plugins/aves_screen_state/pubspec.yaml index fda5d6290..16d083441 100644 --- a/plugins/aves_screen_state/pubspec.yaml +++ b/plugins/aves_screen_state/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: '>=2.19.6 <3.0.0' + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services/pubspec.yaml b/plugins/aves_services/pubspec.yaml index cb818794f..02ad742fe 100644 --- a/plugins/aves_services/pubspec.yaml +++ b/plugins/aves_services/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services_google/pubspec.yaml b/plugins/aves_services_google/pubspec.yaml index 08a713a60..dc926c15b 100644 --- a/plugins/aves_services_google/pubspec.yaml +++ b/plugins/aves_services_google/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services_huawei/pubspec.yaml b/plugins/aves_services_huawei/pubspec.yaml index 148a85401..8043804ce 100644 --- a/plugins/aves_services_huawei/pubspec.yaml +++ b/plugins/aves_services_huawei/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services_none/pubspec.yaml b/plugins/aves_services_none/pubspec.yaml index 4d4d7651b..8ef4e9ad0 100644 --- a/plugins/aves_services_none/pubspec.yaml +++ b/plugins/aves_services_none/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_ui/pubspec.yaml b/plugins/aves_ui/pubspec.yaml index b7efcbcc0..526345b23 100644 --- a/plugins/aves_ui/pubspec.yaml +++ b/plugins/aves_ui/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_utils/pubspec.yaml b/plugins/aves_utils/pubspec.yaml index bdd6c1210..65152ff34 100644 --- a/plugins/aves_utils/pubspec.yaml +++ b/plugins/aves_utils/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: '>=2.19.6 <3.0.0' + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_video/pubspec.yaml b/plugins/aves_video/pubspec.yaml index 7bde43cf3..51a036afd 100644 --- a/plugins/aves_video/pubspec.yaml +++ b/plugins/aves_video/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: '>=2.19.6 <3.0.0' + sdk: ">=2.19.6 <4.0.0" dependencies: flutter: diff --git a/pubspec.yaml b/pubspec.yaml index 8353b9c41..e1cf79658 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper flutter: 3.7.12 - sdk: ">=2.19.6 <3.0.0" + sdk: ">=2.19.6 <4.0.0" # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor dependencies: From 01d2e21369a6de1c781fca91abeadb5fa5b15e9e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 8 May 2023 23:06:31 +0200 Subject: [PATCH 13/35] android 14: use work manager instead of foreground service as datasync --- android/app/build.gradle | 1 + android/app/src/main/AndroidManifest.xml | 11 - .../deckers/thibault/aves/AnalysisService.kt | 258 ------------------ .../deckers/thibault/aves/AnalysisWorker.kt | 173 ++++++++++++ .../deckers/thibault/aves/MainActivity.kt | 1 - .../aves/channel/calls/AnalysisHandler.kt | 100 +++---- .../app/src/main/res/values-ar/strings.xml | 1 - .../app/src/main/res/values-ckb/strings.xml | 1 - .../app/src/main/res/values-cs/strings.xml | 1 - .../app/src/main/res/values-de/strings.xml | 1 - .../app/src/main/res/values-el/strings.xml | 1 - .../app/src/main/res/values-es/strings.xml | 1 - .../app/src/main/res/values-eu/strings.xml | 1 - .../app/src/main/res/values-fa/strings.xml | 1 - .../app/src/main/res/values-fr/strings.xml | 1 - .../app/src/main/res/values-gl/strings.xml | 1 - .../app/src/main/res/values-hi/strings.xml | 1 - .../app/src/main/res/values-hu/strings.xml | 1 - .../app/src/main/res/values-id/strings.xml | 1 - .../app/src/main/res/values-it/strings.xml | 1 - .../app/src/main/res/values-iw/strings.xml | 1 - .../app/src/main/res/values-ja/strings.xml | 1 - .../app/src/main/res/values-ko/strings.xml | 1 - .../app/src/main/res/values-lt/strings.xml | 1 - .../src/main/res/values-nb-rNO/strings.xml | 1 - .../app/src/main/res/values-nl/strings.xml | 1 - .../app/src/main/res/values-nn/strings.xml | 1 - .../app/src/main/res/values-pl/strings.xml | 1 - .../app/src/main/res/values-pt/strings.xml | 1 - .../app/src/main/res/values-ro/strings.xml | 1 - .../app/src/main/res/values-ru/strings.xml | 1 - .../app/src/main/res/values-sk/strings.xml | 1 - .../app/src/main/res/values-th/strings.xml | 1 - .../app/src/main/res/values-tr/strings.xml | 1 - .../app/src/main/res/values-uk/strings.xml | 1 - .../src/main/res/values-zh-rTW/strings.xml | 1 - .../app/src/main/res/values-zh/strings.xml | 1 - android/app/src/main/res/values/strings.xml | 1 - android/build.gradle | 2 +- lib/services/analysis_service.dart | 11 +- .../aves_screen_state/android/build.gradle | 2 +- 41 files changed, 214 insertions(+), 377 deletions(-) delete mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/AnalysisService.kt create mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt diff --git a/android/app/build.gradle b/android/app/build.gradle index 95b53c724..7f038fe1a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -204,6 +204,7 @@ dependencies { implementation 'androidx.media:media:1.6.0' implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.security:security-crypto:1.1.0-alpha06' + implementation 'androidx.work:work-runtime-ktx:2.8.1' implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.commonsware.cwac:document:0.5.0' diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 67d85efed..09b752faf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -40,11 +40,6 @@ This change eventually prevents building the app with Flutter v3.7.11. - @@ -251,12 +246,6 @@ This change eventually prevents building the app with Flutter v3.7.11. - - - msg.arg1 = startId - msg.data = msgData - serviceHandler?.sendMessage(msg) - } - - return START_NOT_STICKY - } - - private fun detachAndStop() { - analysisServiceBinder.detach() - stopSelf() - } - - private fun initChannels(context: Context) { - val engine = flutterEngine - engine ?: throw Exception("Flutter engine is not initialized") - - val messenger = engine.dartExecutor - - // channels for analysis - - // dart -> platform -> dart - // - need Context - MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(context)) - MethodChannel(messenger, GeocodingHandler.CHANNEL).setMethodCallHandler(GeocodingHandler(context)) - MethodChannel(messenger, MediaStoreHandler.CHANNEL).setMethodCallHandler(MediaStoreHandler(context)) - MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(context)) - MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(context)) - - // result streaming: dart -> platform ->->-> dart - // - need Context - StreamsChannel(messenger, ImageByteStreamHandler.CHANNEL).setStreamHandlerFactory { args -> ImageByteStreamHandler(context, args) } - StreamsChannel(messenger, MediaStoreStreamHandler.CHANNEL).setStreamHandlerFactory { args -> MediaStoreStreamHandler(context, args) } - - // channel for service management - backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL).apply { - setMethodCallHandler { call, result -> onMethodCall(call, result) } - } - } - - private fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { - when (call.method) { - "initialized" -> { - Log.d(LOG_TAG, "background channel is ready") - result.success(null) - } - "updateNotification" -> { - val title = call.argument("title") - val message = call.argument("message") - val notification = buildNotification(title, message) - NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification) - result.success(null) - } - "refreshApp" -> { - analysisServiceBinder.refreshApp() - result.success(null) - } - "stop" -> { - detachAndStop() - result.success(null) - } - else -> result.notImplemented() - } - } - - private fun buildNotification(title: String? = null, message: String? = null): Notification { - val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - } else { - PendingIntent.FLAG_UPDATE_CURRENT - } - val stopServiceIntent = Intent(this, AnalysisService::class.java).let { - it.putExtra(KEY_COMMAND, COMMAND_STOP) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - PendingIntent.getForegroundService(this, STOP_SERVICE_REQUEST, it, pendingIntentFlags) - } else { - PendingIntent.getService(this, STOP_SERVICE_REQUEST, it, pendingIntentFlags) - } - } - val openAppIntent = Intent(this, MainActivity::class.java).let { - PendingIntent.getActivity(this, OPEN_FROM_ANALYSIS_SERVICE, it, pendingIntentFlags) - } - val stopAction = NotificationCompat.Action.Builder( - R.drawable.ic_outline_stop_24, - getString(R.string.analysis_notification_action_stop), - stopServiceIntent - ).build() - val icon = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) R.drawable.ic_notification else R.mipmap.ic_launcher_round - return NotificationCompat.Builder(this, CHANNEL_ANALYSIS) - .setContentTitle(title ?: getText(R.string.analysis_notification_default_title)) - .setContentText(message) - .setBadgeIconType(NotificationCompat.BADGE_ICON_NONE) - .setSmallIcon(icon) - .setContentIntent(openAppIntent) - .setPriority(NotificationCompat.PRIORITY_LOW) - .addAction(stopAction) - .build() - } - - private inner class ServiceHandler(looper: Looper) : Handler(looper) { - override fun handleMessage(msg: Message) { - val data = msg.data - when (data.getString(KEY_COMMAND)) { - COMMAND_START -> { - runBlocking { - FlutterUtils.runOnUiThread { - val entryIds = data.getIntArray(KEY_ENTRY_IDS)?.toList() - backgroundChannel?.invokeMethod( - "start", hashMapOf( - "entryIds" to entryIds, - "force" to data.getBoolean(KEY_FORCE), - ) - ) - } - } - } - COMMAND_STOP -> { - // unconditionally stop the service - runBlocking { - FlutterUtils.runOnUiThread { - backgroundChannel?.invokeMethod("stop", null) - } - } - detachAndStop() - } - else -> { - } - } - } - } - - companion object { - private val LOG_TAG = LogUtils.createTag() - private const val BACKGROUND_CHANNEL = "deckers.thibault/aves/analysis_service_background" - const val SHARED_PREFERENCES_KEY = "analysis_service" - const val CALLBACK_HANDLE_KEY = "callback_handle" - - const val NOTIFICATION_ID = 1 - const val STOP_SERVICE_REQUEST = 1 - const val CHANNEL_ANALYSIS = "analysis" - - const val KEY_COMMAND = "command" - const val COMMAND_START = "start" - const val COMMAND_STOP = "stop" - const val KEY_ENTRY_IDS = "entry_ids" - const val KEY_FORCE = "force" - } -} - -class AnalysisServiceBinder : Binder() { - private val listeners = hashSetOf() - - fun startListening(listener: AnalysisServiceListener) = listeners.add(listener) - - fun stopListening(listener: AnalysisServiceListener) = listeners.remove(listener) - - fun refreshApp() { - val localListeners = listeners.toSet() - for (listener in localListeners) { - try { - listener.refreshApp() - } catch (e: Exception) { - Log.e(LOG_TAG, "failed to notify listener=$listener", e) - } - } - } - - fun detach() { - val localListeners = listeners.toSet() - for (listener in localListeners) { - try { - listener.detachFromActivity() - } catch (e: Exception) { - Log.e(LOG_TAG, "failed to detach listener=$listener", e) - } - } - } - - companion object { - private val LOG_TAG = LogUtils.createTag() - } -} - -interface AnalysisServiceListener { - fun refreshApp() - fun detachFromActivity() -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt b/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt new file mode 100644 index 000000000..ec8ffb8ef --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt @@ -0,0 +1,173 @@ +package deckers.thibault.aves + +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +import androidx.core.app.NotificationChannelCompat +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.work.CoroutineWorker +import androidx.work.ForegroundInfo +import androidx.work.WorkManager +import androidx.work.WorkerParameters +import app.loup.streams_channel.StreamsChannel +import deckers.thibault.aves.channel.calls.DeviceHandler +import deckers.thibault.aves.channel.calls.GeocodingHandler +import deckers.thibault.aves.channel.calls.MediaStoreHandler +import deckers.thibault.aves.channel.calls.MetadataFetchHandler +import deckers.thibault.aves.channel.calls.StorageHandler +import deckers.thibault.aves.channel.streams.ImageByteStreamHandler +import deckers.thibault.aves.channel.streams.MediaStoreStreamHandler +import deckers.thibault.aves.utils.FlutterUtils +import deckers.thibault.aves.utils.LogUtils +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import kotlinx.coroutines.runBlocking +import kotlin.coroutines.Continuation +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +class AnalysisWorker(context: Context, parameters: WorkerParameters) : CoroutineWorker(context, parameters) { + private var workCont: Continuation? = null + private var flutterEngine: FlutterEngine? = null + private var backgroundChannel: MethodChannel? = null + + override suspend fun doWork(): Result { + createNotificationChannel() + setForeground(createForegroundInfo()) + suspendCoroutine { cont -> + workCont = cont + onStart() + } + return Result.success() + } + + private fun onStart() { + Log.i(LOG_TAG, "Start analysis worker") + runBlocking { + FlutterUtils.initFlutterEngine(applicationContext, SHARED_PREFERENCES_KEY, CALLBACK_HANDLE_KEY) { + flutterEngine = it + } + } + + try { + initChannels(applicationContext) + + runBlocking { + FlutterUtils.runOnUiThread { + backgroundChannel?.invokeMethod( + "start", hashMapOf( + "entryIds" to inputData.getIntArray(KEY_ENTRY_IDS)?.toList(), + "force" to inputData.getBoolean(KEY_FORCE, false), + ) + ) + } + } + } catch (e: Exception) { + Log.e(LOG_TAG, "failed to initialize worker", e) + workCont?.resumeWithException(e) + } + } + + private fun initChannels(context: Context) { + val engine = flutterEngine + engine ?: throw Exception("Flutter engine is not initialized") + + val messenger = engine.dartExecutor + + // channels for analysis + + // dart -> platform -> dart + // - need Context + MethodChannel(messenger, DeviceHandler.CHANNEL).setMethodCallHandler(DeviceHandler(context)) + MethodChannel(messenger, GeocodingHandler.CHANNEL).setMethodCallHandler(GeocodingHandler(context)) + MethodChannel(messenger, MediaStoreHandler.CHANNEL).setMethodCallHandler(MediaStoreHandler(context)) + MethodChannel(messenger, MetadataFetchHandler.CHANNEL).setMethodCallHandler(MetadataFetchHandler(context)) + MethodChannel(messenger, StorageHandler.CHANNEL).setMethodCallHandler(StorageHandler(context)) + + // result streaming: dart -> platform ->->-> dart + // - need Context + StreamsChannel(messenger, ImageByteStreamHandler.CHANNEL).setStreamHandlerFactory { args -> ImageByteStreamHandler(context, args) } + StreamsChannel(messenger, MediaStoreStreamHandler.CHANNEL).setStreamHandlerFactory { args -> MediaStoreStreamHandler(context, args) } + + // channel for service management + backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL).apply { + setMethodCallHandler { call, result -> onMethodCall(call, result) } + } + } + + private fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { + when (call.method) { + "initialized" -> { + Log.d(LOG_TAG, "Analysis background channel is ready") + result.success(null) + } + + "updateNotification" -> { + val title = call.argument("title") + val message = call.argument("message") + setForegroundAsync(createForegroundInfo(title, message)) + result.success(null) + } + + "stop" -> { + workCont?.resume(null) + result.success(null) + } + + else -> result.notImplemented() + } + } + + private fun createNotificationChannel() { + val channel = NotificationChannelCompat.Builder(NOTIFICATION_CHANNEL, NotificationManagerCompat.IMPORTANCE_LOW) + .setName(applicationContext.getText(R.string.analysis_channel_name)) + .setShowBadge(false) + .build() + NotificationManagerCompat.from(applicationContext).createNotificationChannel(channel) + } + + private fun createForegroundInfo(title: String? = null, message: String? = null): ForegroundInfo { + val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + } else { + PendingIntent.FLAG_UPDATE_CURRENT + } + val openAppIntent = Intent(applicationContext, MainActivity::class.java).let { + PendingIntent.getActivity(applicationContext, MainActivity.OPEN_FROM_ANALYSIS_SERVICE, it, pendingIntentFlags) + } + val stopAction = NotificationCompat.Action.Builder( + R.drawable.ic_outline_stop_24, + applicationContext.getString(R.string.analysis_notification_action_stop), + WorkManager.getInstance(applicationContext).createCancelPendingIntent(id) + ).build() + val icon = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) R.drawable.ic_notification else R.mipmap.ic_launcher_round + val notification = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL) + .setContentTitle(title ?: applicationContext.getText(R.string.analysis_notification_default_title)) + .setContentText(message) + .setBadgeIconType(NotificationCompat.BADGE_ICON_NONE) + .setSmallIcon(icon) + .setContentIntent(openAppIntent) + .setPriority(NotificationCompat.PRIORITY_LOW) + .addAction(stopAction) + .build() + return ForegroundInfo(NOTIFICATION_ID, notification) + } + + companion object { + private val LOG_TAG = LogUtils.createTag() + private const val BACKGROUND_CHANNEL = "deckers.thibault/aves/analysis_service_background" + const val SHARED_PREFERENCES_KEY = "analysis_service" + const val CALLBACK_HANDLE_KEY = "callback_handle" + + const val NOTIFICATION_CHANNEL = "analysis" + const val NOTIFICATION_ID = 1 + + const val KEY_ENTRY_IDS = "entry_ids" + const val KEY_FORCE = "force" + } +} diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt index 06fec0e9f..2e46d64d2 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -170,7 +170,6 @@ open class MainActivity : FlutterFragmentActivity() { override fun onStop() { Log.i(LOG_TAG, "onStop") - analysisHandler.detachFromActivity() super.onStop() } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt index e44d0e5b8..ade45f3c5 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt @@ -1,32 +1,30 @@ package deckers.thibault.aves.channel.calls -import android.app.Activity -import android.content.ComponentName import android.content.Context -import android.content.Intent -import android.content.ServiceConnection -import android.os.Build -import android.os.IBinder -import android.util.Log -import deckers.thibault.aves.AnalysisService -import deckers.thibault.aves.AnalysisServiceBinder -import deckers.thibault.aves.AnalysisServiceListener -import deckers.thibault.aves.utils.ContextUtils.isMyServiceRunning -import deckers.thibault.aves.utils.LogUtils +import androidx.core.app.ComponentActivity +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkInfo +import androidx.work.WorkManager +import androidx.work.workDataOf +import deckers.thibault.aves.AnalysisWorker +import deckers.thibault.aves.utils.FlutterUtils import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking -class AnalysisHandler(private val activity: Activity, private val onAnalysisCompleted: () -> Unit) : MethodChannel.MethodCallHandler, AnalysisServiceListener { + +class AnalysisHandler(private val activity: ComponentActivity, private val onAnalysisCompleted: () -> Unit) : MethodChannel.MethodCallHandler { private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { "registerCallback" -> ioScope.launch { Coresult.safe(call, result, ::registerCallback) } - "startService" -> Coresult.safe(call, result, ::startAnalysis) + "startAnalysis" -> Coresult.safe(call, result, ::startAnalysis) else -> result.notImplemented() } } @@ -38,9 +36,9 @@ class AnalysisHandler(private val activity: Activity, private val onAnalysisComp return } - activity.getSharedPreferences(AnalysisService.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) + activity.getSharedPreferences(AnalysisWorker.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) .edit() - .putLong(AnalysisService.CALLBACK_HANDLE_KEY, callbackHandle) + .putLong(AnalysisWorker.CALLBACK_HANDLE_KEY, callbackHandle) .apply() result.success(true) } @@ -55,20 +53,18 @@ class AnalysisHandler(private val activity: Activity, private val onAnalysisComp // can be null or empty val entryIds = call.argument>("entryIds") - if (!activity.isMyServiceRunning(AnalysisService::class.java)) { - val intent = Intent(activity, AnalysisService::class.java) - .putExtra(AnalysisService.KEY_COMMAND, AnalysisService.COMMAND_START) - .putExtra(AnalysisService.KEY_ENTRY_IDS, entryIds?.toIntArray()) - .putExtra(AnalysisService.KEY_FORCE, force) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // Foreground services cannot start from background, but the service here may start fine - // while the current lifecycle state (via `ProcessLifecycleOwner.get().lifecycle.currentState`) - // is only `INITIALIZED`, so we should not preemptively return when the state is below `STARTED`. - activity.startForegroundService(intent) - } else { - activity.startService(intent) - } - } + WorkManager.getInstance(activity).enqueueUniqueWork( + ANALYSIS_WORK_NAME, + ExistingWorkPolicy.KEEP, + OneTimeWorkRequestBuilder().apply { + setInputData( + workDataOf( + AnalysisWorker.KEY_ENTRY_IDS to entryIds?.toIntArray(), + AnalysisWorker.KEY_FORCE to force, + ) + ) + }.build() + ) attachToActivity() result.success(null) } @@ -76,44 +72,22 @@ class AnalysisHandler(private val activity: Activity, private val onAnalysisComp private var attached = false fun attachToActivity() { - if (activity.isMyServiceRunning(AnalysisService::class.java)) { - val intent = Intent(activity, AnalysisService::class.java) - activity.bindService(intent, connection, Context.BIND_AUTO_CREATE) + if (!attached) { attached = true - } - } - - override fun detachFromActivity() { - if (attached) { - attached = false - activity.unbindService(connection) - } - } - - override fun refreshApp() { - if (attached) { - onAnalysisCompleted() - } - } - - private val connection = object : ServiceConnection { - var binder: AnalysisServiceBinder? = null - - override fun onServiceConnected(name: ComponentName, service: IBinder) { - Log.i(LOG_TAG, "Analysis service connected") - binder = service as AnalysisServiceBinder - binder?.startListening(this@AnalysisHandler) - } - - override fun onServiceDisconnected(name: ComponentName) { - Log.i(LOG_TAG, "Analysis service disconnected") - binder?.stopListening(this@AnalysisHandler) - binder = null + WorkManager.getInstance(activity).getWorkInfosForUniqueWorkLiveData(ANALYSIS_WORK_NAME).observe(activity) { list -> + if (list.any { it.state == WorkInfo.State.SUCCEEDED }) { + runBlocking { + FlutterUtils.runOnUiThread { + onAnalysisCompleted() + } + } + } + } } } companion object { - private val LOG_TAG = LogUtils.createTag() const val CHANNEL = "deckers.thibault/aves/analysis" + private const val ANALYSIS_WORK_NAME = "analysis_work" } } diff --git a/android/app/src/main/res/values-ar/strings.xml b/android/app/src/main/res/values-ar/strings.xml index d55481fb9..a5e1a1c3b 100644 --- a/android/app/src/main/res/values-ar/strings.xml +++ b/android/app/src/main/res/values-ar/strings.xml @@ -5,7 +5,6 @@ البحث الفيديوهات فحص الوسائط - فحص الصور والفيديوهات يتم فحص الوسائط إيقاف \ No newline at end of file diff --git a/android/app/src/main/res/values-ckb/strings.xml b/android/app/src/main/res/values-ckb/strings.xml index 13c4df775..fb8b36a87 100644 --- a/android/app/src/main/res/values-ckb/strings.xml +++ b/android/app/src/main/res/values-ckb/strings.xml @@ -6,7 +6,6 @@ گەڕان ڤیدیۆ گەڕان بۆ فایل - گەڕان بۆ وێنە و ڤیدیۆ گەڕان بۆ فایلەکان وەستاندن \ No newline at end of file diff --git a/android/app/src/main/res/values-cs/strings.xml b/android/app/src/main/res/values-cs/strings.xml index 02638c56a..556ce9d94 100644 --- a/android/app/src/main/res/values-cs/strings.xml +++ b/android/app/src/main/res/values-cs/strings.xml @@ -5,7 +5,6 @@ Hledat Videa Prohledat média - Prohledat obrázky a videa Prohledávání médií Zastavit Fotorámeček diff --git a/android/app/src/main/res/values-de/strings.xml b/android/app/src/main/res/values-de/strings.xml index 1ecb251c5..67f33df47 100644 --- a/android/app/src/main/res/values-de/strings.xml +++ b/android/app/src/main/res/values-de/strings.xml @@ -6,7 +6,6 @@ Suche Videos Analyse von Medien - Bilder & Videos scannen Medien scannen Abbrechen Sicherer Modus diff --git a/android/app/src/main/res/values-el/strings.xml b/android/app/src/main/res/values-el/strings.xml index 2635a337b..0e29952cc 100644 --- a/android/app/src/main/res/values-el/strings.xml +++ b/android/app/src/main/res/values-el/strings.xml @@ -6,7 +6,6 @@ Αναζήτηση Βίντεο Σάρωση πολυμέσων - Σάρωση εικόνων & Βίντεο Σάρωση στοιχείων Διακοπή \ No newline at end of file diff --git a/android/app/src/main/res/values-es/strings.xml b/android/app/src/main/res/values-es/strings.xml index b2364e4dd..9fbcf09b4 100644 --- a/android/app/src/main/res/values-es/strings.xml +++ b/android/app/src/main/res/values-es/strings.xml @@ -6,7 +6,6 @@ Búsqueda Vídeos Explorar medios - Explorar imágenes & videos Explorando medios Anular Modo seguro diff --git a/android/app/src/main/res/values-eu/strings.xml b/android/app/src/main/res/values-eu/strings.xml index 92a69bac7..732dd1c98 100644 --- a/android/app/src/main/res/values-eu/strings.xml +++ b/android/app/src/main/res/values-eu/strings.xml @@ -3,7 +3,6 @@ Bilatu Bideoak Argazki-markoa - Irudiak eta bideoak eskaneatu Horma-papera Media eskaneatu Gelditu diff --git a/android/app/src/main/res/values-fa/strings.xml b/android/app/src/main/res/values-fa/strings.xml index 5b1e2f8ea..e69a7f2b5 100644 --- a/android/app/src/main/res/values-fa/strings.xml +++ b/android/app/src/main/res/values-fa/strings.xml @@ -2,7 +2,6 @@ ویدئو ها کنکاش رسانه - کنکاش تصاویر و ویدئو ها جستجو کاغذدیواری در حال کنکاش رسانه‌ها diff --git a/android/app/src/main/res/values-fr/strings.xml b/android/app/src/main/res/values-fr/strings.xml index 0243698d8..fa821f4ea 100644 --- a/android/app/src/main/res/values-fr/strings.xml +++ b/android/app/src/main/res/values-fr/strings.xml @@ -6,7 +6,6 @@ Recherche Vidéos Analyse des images - Analyse des images & vidéos Analyse des images Annuler Mode sans échec diff --git a/android/app/src/main/res/values-gl/strings.xml b/android/app/src/main/res/values-gl/strings.xml index 6be7c113e..1049c3728 100644 --- a/android/app/src/main/res/values-gl/strings.xml +++ b/android/app/src/main/res/values-gl/strings.xml @@ -6,7 +6,6 @@ Procura Vídeos Escaneo multimedia - Escanealas imaxes e os vídeos Escaneando medios Pare \ No newline at end of file diff --git a/android/app/src/main/res/values-hi/strings.xml b/android/app/src/main/res/values-hi/strings.xml index 615529ee1..0447c8eb1 100644 --- a/android/app/src/main/res/values-hi/strings.xml +++ b/android/app/src/main/res/values-hi/strings.xml @@ -8,5 +8,4 @@ मीडिया जाँचे ऐवीज वीडियो - छवि & वीडियो जाँचे \ No newline at end of file diff --git a/android/app/src/main/res/values-hu/strings.xml b/android/app/src/main/res/values-hu/strings.xml index 5d4734530..4475c608f 100644 --- a/android/app/src/main/res/values-hu/strings.xml +++ b/android/app/src/main/res/values-hu/strings.xml @@ -8,6 +8,5 @@ Fotó keret Biztonsági üzemmód Tartalom keresése - Képek és videók keresése Média beolvasása \ No newline at end of file diff --git a/android/app/src/main/res/values-id/strings.xml b/android/app/src/main/res/values-id/strings.xml index c8067fc0e..29fc0d54c 100644 --- a/android/app/src/main/res/values-id/strings.xml +++ b/android/app/src/main/res/values-id/strings.xml @@ -6,7 +6,6 @@ Cari Video Pindai media - Pindai gambar & video Memindai media Berhenti Mode aman diff --git a/android/app/src/main/res/values-it/strings.xml b/android/app/src/main/res/values-it/strings.xml index 1f254b126..ac62cd864 100644 --- a/android/app/src/main/res/values-it/strings.xml +++ b/android/app/src/main/res/values-it/strings.xml @@ -6,7 +6,6 @@ Ricerca Video Scansione media - Scansione immagini & videos Scansione in corso Annulla Modalità provvisoria diff --git a/android/app/src/main/res/values-iw/strings.xml b/android/app/src/main/res/values-iw/strings.xml index fa2bc3053..8cee373a7 100644 --- a/android/app/src/main/res/values-iw/strings.xml +++ b/android/app/src/main/res/values-iw/strings.xml @@ -6,7 +6,6 @@ חיפוש סרטים סריקת מדיה - סרוק תמונות וסרטים סורק מדיה הפסק \ No newline at end of file diff --git a/android/app/src/main/res/values-ja/strings.xml b/android/app/src/main/res/values-ja/strings.xml index 7204d99c5..d5f7e4ed4 100644 --- a/android/app/src/main/res/values-ja/strings.xml +++ b/android/app/src/main/res/values-ja/strings.xml @@ -6,7 +6,6 @@ 検索 動画 メディアスキャン - 画像と動画をスキャン メディアをスキャン中 停止 セーフモード diff --git a/android/app/src/main/res/values-ko/strings.xml b/android/app/src/main/res/values-ko/strings.xml index 0c064c633..9f19c1398 100644 --- a/android/app/src/main/res/values-ko/strings.xml +++ b/android/app/src/main/res/values-ko/strings.xml @@ -6,7 +6,6 @@ 검색 동영상 미디어 분석 - 사진과 동영상 분석 미디어 분석 취소 안전 모드 diff --git a/android/app/src/main/res/values-lt/strings.xml b/android/app/src/main/res/values-lt/strings.xml index b1ce60a3c..d20202da5 100644 --- a/android/app/src/main/res/values-lt/strings.xml +++ b/android/app/src/main/res/values-lt/strings.xml @@ -1,6 +1,5 @@ - Nuskaityti paveikslėlius ir vaizdo įrašus Ekrano paveikslėlis Vaizdo įrašai Aves diff --git a/android/app/src/main/res/values-nb-rNO/strings.xml b/android/app/src/main/res/values-nb-rNO/strings.xml index d1759646b..f9ec90655 100644 --- a/android/app/src/main/res/values-nb-rNO/strings.xml +++ b/android/app/src/main/res/values-nb-rNO/strings.xml @@ -3,7 +3,6 @@ Aves Videoer Mediaskanning - Skann bilder og videoer Skanning av media Bilderamme Bakgrunnsbilde diff --git a/android/app/src/main/res/values-nl/strings.xml b/android/app/src/main/res/values-nl/strings.xml index b8015ce4f..aae728ba9 100644 --- a/android/app/src/main/res/values-nl/strings.xml +++ b/android/app/src/main/res/values-nl/strings.xml @@ -6,7 +6,6 @@ Zoeken Video’s Media indexeren - Indexeren van afdbeeldingen & video’s Indexeren van media Stop \ No newline at end of file diff --git a/android/app/src/main/res/values-nn/strings.xml b/android/app/src/main/res/values-nn/strings.xml index 8f62f5869..615c9eb6b 100644 --- a/android/app/src/main/res/values-nn/strings.xml +++ b/android/app/src/main/res/values-nn/strings.xml @@ -6,7 +6,6 @@ Søk Videoar Mediasøking - Søk igjennom bilete og videoar Søkjer igjennom media Stogg \ No newline at end of file diff --git a/android/app/src/main/res/values-pl/strings.xml b/android/app/src/main/res/values-pl/strings.xml index ed2f0b129..f88e6931e 100644 --- a/android/app/src/main/res/values-pl/strings.xml +++ b/android/app/src/main/res/values-pl/strings.xml @@ -4,7 +4,6 @@ Szukaj Wideo Przeskanuj multimedia - Przeskanuj obrazy oraz wideo Skanowanie multimediów Zatrzymaj Aves diff --git a/android/app/src/main/res/values-pt/strings.xml b/android/app/src/main/res/values-pt/strings.xml index 17abf2439..0e887b1bb 100644 --- a/android/app/src/main/res/values-pt/strings.xml +++ b/android/app/src/main/res/values-pt/strings.xml @@ -6,7 +6,6 @@ Procurar Vídeos Digitalização de mídia - Digitalizar imagens & vídeos Digitalizando mídia Pare \ No newline at end of file diff --git a/android/app/src/main/res/values-ro/strings.xml b/android/app/src/main/res/values-ro/strings.xml index bb3475bf8..e498222a8 100644 --- a/android/app/src/main/res/values-ro/strings.xml +++ b/android/app/src/main/res/values-ro/strings.xml @@ -5,7 +5,6 @@ Tapet Videoclipuri Scanare media - Scanați imagini și videoclipuri Scanarea suporturilor Stop Căutare diff --git a/android/app/src/main/res/values-ru/strings.xml b/android/app/src/main/res/values-ru/strings.xml index 84259422b..a0e991e96 100644 --- a/android/app/src/main/res/values-ru/strings.xml +++ b/android/app/src/main/res/values-ru/strings.xml @@ -6,7 +6,6 @@ Поиск Видео Сканировать медия - Сканировать изображения и видео Сканирование медиа Стоп Безопасный режим diff --git a/android/app/src/main/res/values-sk/strings.xml b/android/app/src/main/res/values-sk/strings.xml index 08fd7dbe9..9a8ac434a 100644 --- a/android/app/src/main/res/values-sk/strings.xml +++ b/android/app/src/main/res/values-sk/strings.xml @@ -7,6 +7,5 @@ Videá Zastaviť Skenovanie médií - Skenovanie obrázkov & videí Skenovanie média \ No newline at end of file diff --git a/android/app/src/main/res/values-th/strings.xml b/android/app/src/main/res/values-th/strings.xml index b582dd0f7..2ac92953e 100644 --- a/android/app/src/main/res/values-th/strings.xml +++ b/android/app/src/main/res/values-th/strings.xml @@ -6,7 +6,6 @@ ค้นหา วิดีโอ สแกนสื่อบันเทิง - สแกนรูปภาพและวิดีโอ กำลังสแกนสื่อบันเทิง หยุด \ No newline at end of file diff --git a/android/app/src/main/res/values-tr/strings.xml b/android/app/src/main/res/values-tr/strings.xml index a358643e8..e516cc30b 100644 --- a/android/app/src/main/res/values-tr/strings.xml +++ b/android/app/src/main/res/values-tr/strings.xml @@ -6,7 +6,6 @@ Arama Videolar Medya tarama - Görüntüleri ve videoları tarayın Medya taranıyor Durdur \ No newline at end of file diff --git a/android/app/src/main/res/values-uk/strings.xml b/android/app/src/main/res/values-uk/strings.xml index b6c0c0a68..71b3f03aa 100644 --- a/android/app/src/main/res/values-uk/strings.xml +++ b/android/app/src/main/res/values-uk/strings.xml @@ -5,7 +5,6 @@ Пошук Відео Сканувати медіа - Сканувати зображення та відео Стоп Фоторамка Сканування медіа diff --git a/android/app/src/main/res/values-zh-rTW/strings.xml b/android/app/src/main/res/values-zh-rTW/strings.xml index 8071ccad2..7de20ea26 100644 --- a/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/android/app/src/main/res/values-zh-rTW/strings.xml @@ -7,6 +7,5 @@ 相框 搜尋 媒體掃描 - 掃描圖片和影片 停止 \ No newline at end of file diff --git a/android/app/src/main/res/values-zh/strings.xml b/android/app/src/main/res/values-zh/strings.xml index 7b454e26b..e6ed4d076 100644 --- a/android/app/src/main/res/values-zh/strings.xml +++ b/android/app/src/main/res/values-zh/strings.xml @@ -6,7 +6,6 @@ 搜索 视频 媒体扫描 - 扫描图像 & 视频 正在扫描媒体库 停止 \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index f0f317c96..e77df79e1 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -7,7 +7,6 @@ Search Videos Media scan - Scan images & videos Scanning media Stop \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index d06c9b9c7..8a5a133bb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,6 +1,6 @@ buildscript { ext { - kotlin_version = '1.8.0' + kotlin_version = '1.8.21' agp_version = '7.4.2' glide_version = '4.15.1' huawei_agconnect_version = '1.8.0.300' diff --git a/lib/services/analysis_service.dart b/lib/services/analysis_service.dart index dde0d5675..50fea1499 100644 --- a/lib/services/analysis_service.dart +++ b/lib/services/analysis_service.dart @@ -31,7 +31,7 @@ class AnalysisService { static Future startService({required bool force, List? entryIds}) async { await reportService.log('Start analysis service${entryIds != null ? ' for ${entryIds.length} items' : ''}'); try { - await _platform.invokeMethod('startService', { + await _platform.invokeMethod('startAnalysis', { 'entryIds': entryIds, 'force': force, }); @@ -155,7 +155,6 @@ class Analyzer { void _onSourceStateChanged() { if (_source.isReady) { - _refreshApp(); _serviceStateNotifier.value = AnalyzerState.stopping; } } @@ -179,14 +178,6 @@ class Analyzer { } } - Future _refreshApp() async { - try { - await _channel.invokeMethod('refreshApp'); - } on PlatformException catch (e, stack) { - await reportService.recordError(e, stack); - } - } - Future _stopPlatformService() async { try { await _channel.invokeMethod('stop'); diff --git a/plugins/aves_screen_state/android/build.gradle b/plugins/aves_screen_state/android/build.gradle index 31eaba649..4aae7446c 100644 --- a/plugins/aves_screen_state/android/build.gradle +++ b/plugins/aves_screen_state/android/build.gradle @@ -2,7 +2,7 @@ group 'deckers.thibault.aves.aves_screen_state' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.8.0' + ext.kotlin_version = '1.8.21' repositories { google() mavenCentral() From 28973ec32218fe1a3e717fb486974695b4b83d56 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sat, 13 May 2023 17:39:39 +0200 Subject: [PATCH 14/35] upgraded Flutter to stable v3.10.0, agp 8, dart 3, use media query aspects --- .flutter | 2 +- CHANGELOG.md | 2 + android/app/build.gradle | 21 +- android/app/src/main/AndroidManifest.xml | 1 - android/build.gradle | 2 +- android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../app_icon_image_provider.dart | 4 +- lib/image_providers/region_provider.dart | 4 +- lib/image_providers/thumbnail_provider.dart | 4 +- lib/image_providers/uri_image_provider.dart | 4 +- lib/model/db/db_metadata_sqflite_upgrade.dart | 10 - lib/model/entry/extensions/catalog.dart | 2 +- .../entry/extensions/metadata_edition.dart | 5 - lib/model/filters/album.dart | 1 - lib/model/filters/aspect_ratio.dart | 3 - lib/model/filters/date.dart | 6 - lib/model/filters/location.dart | 4 - lib/model/filters/missing.dart | 3 - lib/model/filters/placeholder.dart | 4 - lib/model/filters/query.dart | 10 - lib/model/filters/type.dart | 6 - lib/model/geotiff.dart | 241 +++++----- lib/model/naming_pattern.dart | 6 - .../enums/display_refresh_rate_mode.dart | 3 - lib/model/settings/settings.dart | 8 +- lib/model/source/album.dart | 3 - lib/model/source/collection_lens.dart | 14 - lib/model/source/collection_source.dart | 10 - lib/model/video/metadata.dart | 38 -- lib/model/video/profiles/h264.dart | 13 - lib/model/video/profiles/hevc.dart | 4 - lib/ref/poi.dart | 2 +- lib/services/analysis_service.dart | 2 - lib/services/media/media_session_service.dart | 6 - .../metadata/svg_metadata_service.dart | 2 +- lib/services/window_service.dart | 3 - lib/theme/text.dart | 2 +- lib/utils/diff_match.dart | 17 - lib/utils/xmp_utils.dart | 2 +- lib/widget_common.dart | 2 - lib/widgets/about/app_ref.dart | 3 +- lib/widgets/about/bug_report.dart | 2 +- lib/widgets/about/tv_license_page.dart | 73 ++- lib/widgets/aves_app.dart | 79 ++-- lib/widgets/collection/app_bar.dart | 12 +- lib/widgets/collection/collection_grid.dart | 18 +- .../collection/entry_set_action_delegate.dart | 24 - lib/widgets/collection/grid/headers/any.dart | 1 - lib/widgets/collection/grid/list_details.dart | 2 +- lib/widgets/collection/grid/tile.dart | 4 - lib/widgets/collection/query_bar.dart | 2 +- .../quick_choosers/common/menu.dart | 8 +- .../quick_choosers/common/route_layout.dart | 2 - .../common/action_mixins/entry_storage.dart | 3 - .../action_mixins/overlay_snack_bar.dart | 226 ++++++++-- .../common/action_mixins/size_aware.dart | 2 - .../common/action_mixins/vault_aware.dart | 8 - lib/widgets/common/app_bar/app_bar_title.dart | 4 +- .../common/basic/font_size_icon_theme.dart | 3 +- lib/widgets/common/basic/insets.dart | 8 +- .../basic/list_tiles/reselectable_radio.dart | 2 - .../common/basic/markdown_container.dart | 2 +- lib/widgets/common/basic/scaffold.dart | 3 +- lib/widgets/common/basic/text/outlined.dart | 70 +-- lib/widgets/common/basic/wheel.dart | 5 +- .../eager_scale_gesture_recognizer.dart | 132 ++++-- lib/widgets/common/behaviour/intents.dart | 2 - .../known_extent_scroll_physics.dart | 6 +- .../behaviour/springy_scroll_physics.dart | 1 - lib/widgets/common/fx/borders.dart | 12 +- lib/widgets/common/fx/transition_image.dart | 175 +++++++- lib/widgets/common/grid/item_tracker.dart | 15 +- lib/widgets/common/grid/scaling.dart | 10 +- .../common/grid/sections/fixed/row.dart | 2 +- .../grid/sections/fixed/scale_grid.dart | 2 - .../grid/sections/fixed/scale_overlay.dart | 3 +- .../common/grid/sections/mosaic/row.dart | 2 +- lib/widgets/common/identity/aves_app_bar.dart | 113 +++-- .../common/identity/aves_filter_chip.dart | 10 +- lib/widgets/common/identity/aves_logo.dart | 2 +- .../identity/buttons/overlay_button.dart | 2 +- lib/widgets/common/map/buttons/panel.dart | 2 - lib/widgets/common/map/geo_map.dart | 26 +- .../common/map/leaflet/scale_layer.dart | 2 - .../common/map/leaflet/tile_layers.dart | 7 +- .../common/map/map_action_delegate.dart | 3 - lib/widgets/common/search/page.dart | 2 - lib/widgets/common/thumbnail/decorated.dart | 6 +- lib/widgets/common/thumbnail/image.dart | 20 +- lib/widgets/debug/app_debug_page.dart | 5 - lib/widgets/debug/settings.dart | 2 +- lib/widgets/dialogs/add_shortcut_dialog.dart | 3 +- .../dialogs/aves_confirmation_dialog.dart | 4 - lib/widgets/dialogs/aves_dialog.dart | 3 +- lib/widgets/dialogs/convert_entry_dialog.dart | 6 - .../entry_editors/edit_date_dialog.dart | 6 +- .../entry_editors/edit_location_dialog.dart | 17 +- .../entry_editors/edit_rating_dialog.dart | 5 - .../entry_editors/rename_entry_set_page.dart | 100 ++--- .../cover_selection_dialog.dart | 5 +- .../filter_editors/pattern_dialog.dart | 3 +- lib/widgets/dialogs/item_picker.dart | 1 + .../dialogs/pick_dialogs/album_pick_page.dart | 3 - .../pick_dialogs/location_pick_page.dart | 15 +- lib/widgets/dialogs/tile_view_dialog.dart | 5 +- lib/widgets/filter_grids/albums_page.dart | 3 - .../common/action_delegates/album_set.dart | 6 - .../common/action_delegates/chip.dart | 6 - .../common/action_delegates/chip_set.dart | 13 - .../common/action_delegates/country_set.dart | 1 - .../common/action_delegates/tag_set.dart | 1 - lib/widgets/filter_grids/common/app_bar.dart | 4 +- .../common/covered_filter_chip.dart | 26 +- .../filter_grids/common/filter_grid_page.dart | 177 ++++---- .../filter_grids/common/filter_nav_page.dart | 4 - .../filter_grids/common/filter_tile.dart | 2 - .../filter_grids/common/list_details.dart | 2 +- .../filter_grids/common/query_bar.dart | 2 +- lib/widgets/home_page.dart | 16 - lib/widgets/map/address_row.dart | 4 +- lib/widgets/map/date_row.dart | 3 +- lib/widgets/map/info_row.dart | 11 +- lib/widgets/map/map_page.dart | 3 +- lib/widgets/map/scroller.dart | 46 +- lib/widgets/navigation/drawer/app_drawer.dart | 7 +- lib/widgets/navigation/nav_bar/floating.dart | 2 - lib/widgets/settings/app_export/items.dart | 3 - .../common/quick_actions/editor_page.dart | 3 - .../privacy/file_picker/file_picker_page.dart | 1 - .../settings/settings_mobile_page.dart | 2 - lib/widgets/settings/thumbnails/overlay.dart | 5 +- lib/widgets/stats/date/histogram.dart | 6 - .../viewer/action/entry_action_delegate.dart | 37 +- .../action/entry_info_action_delegate.dart | 12 +- .../viewer/action/video_action_delegate.dart | 9 - .../viewer/entry_horizontal_pager.dart | 3 +- lib/widgets/viewer/entry_vertical_pager.dart | 6 +- lib/widgets/viewer/entry_viewer_stack.dart | 14 +- lib/widgets/viewer/info/basic_section.dart | 5 +- .../info/embedded/embedded_data_opener.dart | 4 - lib/widgets/viewer/info/info_page.dart | 57 ++- lib/widgets/viewer/info/location_section.dart | 1 + .../info/metadata/metadata_dir_tile.dart | 3 - .../info/metadata/metadata_thumbnail.dart | 3 +- lib/widgets/viewer/overlay/bottom.dart | 12 +- lib/widgets/viewer/overlay/details/date.dart | 3 +- .../viewer/overlay/details/details.dart | 134 +++--- .../viewer/overlay/details/rating_tags.dart | 3 - .../viewer/overlay/video/progress_bar.dart | 11 +- .../viewer/overlay/viewer_buttons.dart | 21 - .../viewer/overlay/wallpaper_buttons.dart | 6 - lib/widgets/viewer/panorama_page.dart | 2 - lib/widgets/viewer/slideshow_page.dart | 3 - lib/widgets/viewer/video/fijkplayer.dart | 11 +- .../viewer/video/flutter_vlc_player.dart | 2 +- .../viewer/visual/entry_page_view.dart | 20 +- lib/widgets/viewer/visual/vector.dart | 28 +- lib/widgets/viewer/visual/video/cover.dart | 1 + .../visual/video/subtitle/ass_parser.dart | 36 -- .../visual/video/subtitle/subtitle.dart | 421 +++++++++--------- .../viewer/visual/video/swipe_action.dart | 2 - lib/widgets/welcome_page.dart | 2 +- plugins/aves_magnifier/lib/src/core/core.dart | 3 +- .../lib/src/core/gesture_detector.dart | 3 +- .../src/core/scale_gesture_recognizer.dart | 2 - .../lib/src/scale/scale_boundaries.dart | 8 +- plugins/aves_magnifier/pubspec.lock | 22 +- plugins/aves_magnifier/pubspec.yaml | 2 +- .../aves_map/lib/src/marker/generator.dart | 27 +- plugins/aves_map/pubspec.lock | 26 +- plugins/aves_map/pubspec.yaml | 2 +- plugins/aves_model/pubspec.lock | 22 +- plugins/aves_model/pubspec.yaml | 2 +- .../aves_platform_meta/android/build.gradle | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/src/main/AndroidManifest.xml | 4 +- plugins/aves_platform_meta/pubspec.lock | 22 +- plugins/aves_platform_meta/pubspec.yaml | 2 +- plugins/aves_report/pubspec.lock | 22 +- plugins/aves_report/pubspec.yaml | 2 +- plugins/aves_report_console/pubspec.lock | 22 +- plugins/aves_report_console/pubspec.yaml | 2 +- plugins/aves_report_crashlytics/pubspec.lock | 64 +-- plugins/aves_report_crashlytics/pubspec.yaml | 2 +- .../aves_screen_state/android/build.gradle | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/src/main/AndroidManifest.xml | 4 +- plugins/aves_screen_state/pubspec.lock | 22 +- plugins/aves_screen_state/pubspec.yaml | 2 +- plugins/aves_services/pubspec.lock | 26 +- plugins/aves_services/pubspec.yaml | 2 +- plugins/aves_services_google/lib/src/map.dart | 1 - plugins/aves_services_google/pubspec.lock | 46 +- plugins/aves_services_google/pubspec.yaml | 2 +- plugins/aves_services_huawei/pubspec.lock | 26 +- plugins/aves_services_huawei/pubspec.yaml | 2 +- plugins/aves_services_none/pubspec.lock | 26 +- plugins/aves_services_none/pubspec.yaml | 2 +- plugins/aves_ui/pubspec.lock | 22 +- plugins/aves_ui/pubspec.yaml | 2 +- plugins/aves_utils/pubspec.lock | 22 +- plugins/aves_utils/pubspec.yaml | 2 +- plugins/aves_video/pubspec.lock | 22 +- plugins/aves_video/pubspec.yaml | 2 +- pubspec.lock | 291 ++++++------ pubspec.yaml | 68 ++- shaders.sksl.json | 2 +- 208 files changed, 1905 insertions(+), 1988 deletions(-) diff --git a/.flutter b/.flutter index 4d9e56e69..84a1e904f 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf +Subproject commit 84a1e904f44f9b0e9c4510138010edcc653163f8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 34eed96ef..7c35f01c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,12 @@ All notable changes to this project will be documented in this file. ### Added - option to set the Tags page as home +- support for animated PNG ### Changed - remember whether to show the title filter when picking albums +- upgraded Flutter to stable v3.10.0 ## [v1.8.6] - 2023-04-30 diff --git a/android/app/build.gradle b/android/app/build.gradle index 7f038fe1a..bf19c8257 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id 'com.android.application' id 'kotlin-android' @@ -46,7 +48,7 @@ if (keystorePropertiesFile.exists()) { android { namespace 'deckers.thibault.aves' - compileSdkVersion 33 + compileSdk 33 ndkVersion flutter.ndkVersion compileOptions { @@ -60,10 +62,6 @@ android { disable 'InvalidPackage' } - kotlinOptions { - jvmTarget = '1.8' - } - sourceSets { main.java.srcDirs += 'src/main/kotlin' } @@ -174,6 +172,15 @@ android { } } +tasks.withType(KotlinCompile).configureEach { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + + kotlinOptions { + jvmTarget = '1.8' + } +} + flutter { source '../..' } @@ -195,10 +202,10 @@ repositories { } dependencies { - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1' implementation "androidx.appcompat:appcompat:1.6.1" - implementation 'androidx.core:core-ktx:1.10.0' + implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.exifinterface:exifinterface:1.3.6' implementation 'androidx.lifecycle:lifecycle-process:2.6.1' implementation 'androidx.media:media:1.6.0' diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 09b752faf..eec888a79 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -8,7 +8,6 @@ This change eventually prevents building the app with Flutter v3.7.11. --> { } @override - ImageStreamCompleter loadBuffer(AppIconImageKey key, DecoderBufferCallback decode) { + ImageStreamCompleter loadImage(AppIconImageKey key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), scale: key.scale, @@ -37,7 +37,7 @@ class AppIconImage extends ImageProvider { ); } - Future _loadAsync(AppIconImageKey key, DecoderBufferCallback decode) async { + Future _loadAsync(AppIconImageKey key, ImageDecoderCallback decode) async { try { final bytes = await appService.getAppIcon(key.packageName, key.size); final buffer = await ui.ImmutableBuffer.fromUint8List(bytes.isEmpty ? kTransparentImage : bytes); diff --git a/lib/image_providers/region_provider.dart b/lib/image_providers/region_provider.dart index 135215324..dc85ccaa1 100644 --- a/lib/image_providers/region_provider.dart +++ b/lib/image_providers/region_provider.dart @@ -18,7 +18,7 @@ class RegionProvider extends ImageProvider { } @override - ImageStreamCompleter loadBuffer(RegionProviderKey key, DecoderBufferCallback decode) { + ImageStreamCompleter loadImage(RegionProviderKey key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), scale: 1.0, @@ -28,7 +28,7 @@ class RegionProvider extends ImageProvider { ); } - Future _loadAsync(RegionProviderKey key, DecoderBufferCallback decode) async { + Future _loadAsync(RegionProviderKey key, ImageDecoderCallback decode) async { final uri = key.uri; final mimeType = key.mimeType; final pageId = key.pageId; diff --git a/lib/image_providers/thumbnail_provider.dart b/lib/image_providers/thumbnail_provider.dart index bf13c32bc..33f05fec4 100644 --- a/lib/image_providers/thumbnail_provider.dart +++ b/lib/image_providers/thumbnail_provider.dart @@ -19,7 +19,7 @@ class ThumbnailProvider extends ImageProvider { } @override - ImageStreamCompleter loadBuffer(ThumbnailProviderKey key, DecoderBufferCallback decode) { + ImageStreamCompleter loadImage(ThumbnailProviderKey key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), scale: 1.0, @@ -30,7 +30,7 @@ class ThumbnailProvider extends ImageProvider { ); } - Future _loadAsync(ThumbnailProviderKey key, DecoderBufferCallback decode) async { + Future _loadAsync(ThumbnailProviderKey key, ImageDecoderCallback decode) async { final uri = key.uri; final mimeType = key.mimeType; final pageId = key.pageId; diff --git a/lib/image_providers/uri_image_provider.dart b/lib/image_providers/uri_image_provider.dart index ffcb622f7..38842e742 100644 --- a/lib/image_providers/uri_image_provider.dart +++ b/lib/image_providers/uri_image_provider.dart @@ -32,7 +32,7 @@ class UriImage extends ImageProvider with EquatableMixin { } @override - ImageStreamCompleter loadBuffer(UriImage key, DecoderBufferCallback decode) { + ImageStreamCompleter loadImage(UriImage key, ImageDecoderCallback decode) { final chunkEvents = StreamController(); return MultiFrameImageStreamCompleter( @@ -45,7 +45,7 @@ class UriImage extends ImageProvider with EquatableMixin { ); } - Future _loadAsync(UriImage key, DecoderBufferCallback decode, StreamController chunkEvents) async { + Future _loadAsync(UriImage key, ImageDecoderCallback decode, StreamController chunkEvents) async { assert(key == this); try { diff --git a/lib/model/db/db_metadata_sqflite_upgrade.dart b/lib/model/db/db_metadata_sqflite_upgrade.dart index f2840e2ee..ef0b66074 100644 --- a/lib/model/db/db_metadata_sqflite_upgrade.dart +++ b/lib/model/db/db_metadata_sqflite_upgrade.dart @@ -21,34 +21,24 @@ class MetadataDbUpgrader { switch (oldVersion) { case 1: await _upgradeFrom1(db); - break; case 2: await _upgradeFrom2(db); - break; case 3: await _upgradeFrom3(db); - break; case 4: await _upgradeFrom4(db); - break; case 5: await _upgradeFrom5(db); - break; case 6: await _upgradeFrom6(db); - break; case 7: await _upgradeFrom7(db); - break; case 8: await _upgradeFrom8(db); - break; case 9: await _upgradeFrom9(db); - break; case 10: await _upgradeFrom10(db); - break; } oldVersion++; } diff --git a/lib/model/entry/extensions/catalog.dart b/lib/model/entry/extensions/catalog.dart index 6a7aa331e..73ee03ac6 100644 --- a/lib/model/entry/extensions/catalog.dart +++ b/lib/model/entry/extensions/catalog.dart @@ -39,7 +39,7 @@ extension ExtraAvesEntryCatalog on AvesEntry { if (isGeotiff && !hasGps) { final info = await metadataFetchService.getGeoTiffInfo(this); if (info != null) { - final center = MappedGeoTiff( + final center = GeoTiffCoordinateConverter( info: info, entry: this, ).center; diff --git a/lib/model/entry/extensions/metadata_edition.dart b/lib/model/entry/extensions/metadata_edition.dart index 9d1f2f7c3..c28c26d8d 100644 --- a/lib/model/entry/extensions/metadata_edition.dart +++ b/lib/model/entry/extensions/metadata_edition.dart @@ -52,7 +52,6 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry { case DateEditAction.copyItem: case DateEditAction.extractFromTitle: editCreateDateXmp(descriptions, appliedModifier.setDateTime); - break; case DateEditAction.shift: final xmpDate = XMP.getString(descriptions, XmpAttributes.xmpCreateDate, namespace: XmpNamespaces.xmp); if (xmpDate != null) { @@ -65,10 +64,8 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry { reportService.recordError('failed to parse XMP date=$xmpDate', null); } } - break; case DateEditAction.remove: editCreateDateXmp(descriptions, null); - break; } return true; }), @@ -541,10 +538,8 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry { } } } on FileSystemException catch (_) {} - break; default: date = await metadataFetchService.getDate(this, source.toMetadataField()!); - break; } } return date != null ? DateModifier.setCustom(mainMetadataDate(), date) : null; diff --git a/lib/model/filters/album.dart b/lib/model/filters/album.dart index 7f5f8aa77..34e4ab626 100644 --- a/lib/model/filters/album.dart +++ b/lib/model/filters/album.dart @@ -78,7 +78,6 @@ class AlbumFilter extends CoveredCollectionFilter { case AlbumType.app: final appColor = colors.appColor(album); if (appColor != null) return appColor; - break; case AlbumType.camera: return SynchronousFuture(colors.albumCamera); case AlbumType.download: diff --git a/lib/model/filters/aspect_ratio.dart b/lib/model/filters/aspect_ratio.dart index 92ee97279..f21f48280 100644 --- a/lib/model/filters/aspect_ratio.dart +++ b/lib/model/filters/aspect_ratio.dart @@ -21,13 +21,10 @@ class AspectRatioFilter extends CollectionFilter { switch (op) { case QueryFilter.opEqual: _test = (entry) => entry.displayAspectRatio == threshold; - break; case QueryFilter.opLower: _test = (entry) => entry.displayAspectRatio < threshold; - break; case QueryFilter.opGreater: _test = (entry) => entry.displayAspectRatio > threshold; - break; } } diff --git a/lib/model/filters/date.dart b/lib/model/filters/date.dart index 3c82ae15c..4749fcd4d 100644 --- a/lib/model/filters/date.dart +++ b/lib/model/filters/date.dart @@ -25,13 +25,10 @@ class DateFilter extends CollectionFilter { switch (level) { case DateLevel.y: _test = (entry) => entry.bestDate?.isAtSameYearAs(_effectiveDate) ?? false; - break; case DateLevel.ym: _test = (entry) => entry.bestDate?.isAtSameMonthAs(_effectiveDate) ?? false; - break; case DateLevel.ymd: _test = (entry) => entry.bestDate?.isAtSameDayAs(_effectiveDate) ?? false; - break; case DateLevel.md: final month = _effectiveDate.month; final day = _effectiveDate.day; @@ -39,15 +36,12 @@ class DateFilter extends CollectionFilter { final bestDate = entry.bestDate; return bestDate != null && bestDate.month == month && bestDate.day == day; }; - break; case DateLevel.m: final month = _effectiveDate.month; _test = (entry) => entry.bestDate?.month == month; - break; case DateLevel.d: final day = _effectiveDate.day; _test = (entry) => entry.bestDate?.day == day; - break; } } diff --git a/lib/model/filters/location.dart b/lib/model/filters/location.dart index 0c547defd..3a22391b5 100644 --- a/lib/model/filters/location.dart +++ b/lib/model/filters/location.dart @@ -29,13 +29,10 @@ class LocationFilter extends CoveredCollectionFilter { switch (level) { case LocationLevel.country: _test = (entry) => entry.addressDetails?.countryCode == _code; - break; case LocationLevel.state: _test = (entry) => entry.addressDetails?.stateCode == _code; - break; case LocationLevel.place: _test = (entry) => entry.addressDetails?.place == _location; - break; } } } @@ -57,7 +54,6 @@ class LocationFilter extends CoveredCollectionFilter { if (_code != null) { location = _nameAndCode; } - break; case LocationLevel.place: break; } diff --git a/lib/model/filters/missing.dart b/lib/model/filters/missing.dart index 6060d3f36..9128d1eb1 100644 --- a/lib/model/filters/missing.dart +++ b/lib/model/filters/missing.dart @@ -26,15 +26,12 @@ class MissingFilter extends CollectionFilter { case _date: _test = (entry) => (entry.catalogMetadata?.dateMillis ?? 0) == 0; _icon = AIcons.dateUndated; - break; case _fineAddress: _test = (entry) => entry.hasGps && !entry.hasFineAddress; _icon = AIcons.locationUnlocated; - break; case _title: _test = (entry) => (entry.catalogMetadata?.xmpTitle ?? '').isEmpty; _icon = AIcons.descriptionUntitled; - break; } } diff --git a/lib/model/filters/placeholder.dart b/lib/model/filters/placeholder.dart index 32f22b1f4..bbeab3bed 100644 --- a/lib/model/filters/placeholder.dart +++ b/lib/model/filters/placeholder.dart @@ -28,13 +28,10 @@ class PlaceholderFilter extends CollectionFilter { switch (placeholder) { case _country: _icon = AIcons.country; - break; case _state: _icon = AIcons.state; - break; case _place: _icon = AIcons.place; - break; } } @@ -74,7 +71,6 @@ class PlaceholderFilter extends CollectionFilter { case _place: return address.place; } - break; } return null; } diff --git a/lib/model/filters/query.dart b/lib/model/filters/query.dart index 523a1b156..2c1689551 100644 --- a/lib/model/filters/query.dart +++ b/lib/model/filters/query.dart @@ -117,7 +117,6 @@ class QueryFilter extends CollectionFilter { if (op == opEqual) { return (entry) => entry.contentId == valueInt; } - break; case keyContentYear: if (valueInt == null) return null; switch (op) { @@ -128,7 +127,6 @@ class QueryFilter extends CollectionFilter { case opGreater: return (entry) => (entry.bestDate?.year ?? 0) > valueInt; } - break; case keyContentMonth: if (valueInt == null) return null; switch (op) { @@ -139,7 +137,6 @@ class QueryFilter extends CollectionFilter { case opGreater: return (entry) => (entry.bestDate?.month ?? 0) > valueInt; } - break; case keyContentDay: if (valueInt == null) return null; switch (op) { @@ -150,7 +147,6 @@ class QueryFilter extends CollectionFilter { case opGreater: return (entry) => (entry.bestDate?.day ?? 0) > valueInt; } - break; case keyContentWidth: if (valueInt == null) return null; switch (op) { @@ -161,7 +157,6 @@ class QueryFilter extends CollectionFilter { case opGreater: return (entry) => entry.displaySize.width > valueInt; } - break; case keyContentHeight: if (valueInt == null) return null; switch (op) { @@ -172,7 +167,6 @@ class QueryFilter extends CollectionFilter { case opGreater: return (entry) => entry.displaySize.height > valueInt; } - break; case keyContentSize: match = _fileSizePattern.firstMatch(valueString); if (match == null) return null; @@ -187,13 +181,10 @@ class QueryFilter extends CollectionFilter { switch (multiplierString) { case 'K': bytes *= kilo; - break; case 'M': bytes *= mega; - break; case 'G': bytes *= giga; - break; } switch (op) { @@ -204,7 +195,6 @@ class QueryFilter extends CollectionFilter { case opGreater: return (entry) => (entry.sizeBytes ?? 0) > bytes; } - break; } return null; diff --git a/lib/model/filters/type.dart b/lib/model/filters/type.dart index 9eafa93b3..b94dcb6ac 100644 --- a/lib/model/filters/type.dart +++ b/lib/model/filters/type.dart @@ -37,27 +37,21 @@ class TypeFilter extends CollectionFilter { case _animated: _test = (entry) => entry.isAnimated; _icon = AIcons.animated; - break; case _geotiff: _test = (entry) => entry.isGeotiff; _icon = AIcons.geo; - break; case _motionPhoto: _test = (entry) => entry.isMotionPhoto; _icon = AIcons.motionPhoto; - break; case _panorama: _test = (entry) => entry.isImage && entry.is360; _icon = AIcons.panorama; - break; case _raw: _test = (entry) => entry.isRaw; _icon = AIcons.raw; - break; case _sphericalVideo: _test = (entry) => entry.isVideo && entry.is360; _icon = AIcons.sphericalVideo; - break; } } diff --git a/lib/model/geotiff.dart b/lib/model/geotiff.dart index efa6afb46..d549cd29d 100644 --- a/lib/model/geotiff.dart +++ b/lib/model/geotiff.dart @@ -8,8 +8,7 @@ import 'package:aves/ref/metadata/geotiff.dart'; import 'package:aves/utils/math_utils.dart'; import 'package:aves_map/aves_map.dart'; import 'package:equatable/equatable.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/painting.dart'; +import 'package:flutter/widgets.dart'; import 'package:latlong2/latlong.dart'; import 'package:proj4dart/proj4dart.dart' as proj4; @@ -42,19 +41,145 @@ class GeoTiffInfo extends Equatable { class MappedGeoTiff with MapOverlay { final AvesEntry entry; - late LatLng? Function(Point pixel) pointToLatLng; - late Point? Function(Point smPoint) epsg3857ToPoint; - static final mapServiceTileSize = (256 * ui.window.devicePixelRatio).round(); - static final mapServiceHelper = MapServiceHelper(mapServiceTileSize); - static final tileImagePaint = Paint(); - static final tileMissingPaint = Paint() + late final GeoTiffCoordinateConverter _converter; + late final int _mapServiceTileSize; + late final MapServiceHelper _mapServiceHelper; + + static final _tileImagePaint = Paint(); + static final _tileMissingPaint = Paint() ..style = PaintingStyle.fill ..color = const Color(0xFF000000); MappedGeoTiff({ required GeoTiffInfo info, required this.entry, + required double devicePixelRatio, + }) { + _converter = GeoTiffCoordinateConverter(info: info, entry: entry); + _mapServiceTileSize = (256 * devicePixelRatio).round(); + _mapServiceHelper = MapServiceHelper(_mapServiceTileSize); + } + + @override + Future getTile(int tx, int ty, int? zoomLevel) async { + zoomLevel ??= 0; + + // global projected coordinates in meters (EPSG:3857 Spherical Mercator) + final tileTopLeft3857 = _mapServiceHelper.tileTopLeft(tx, ty, zoomLevel); + final tileBottomRight3857 = _mapServiceHelper.tileTopLeft(tx + 1, ty + 1, zoomLevel); + + // image region coordinates in pixels + final tileTopLeftPx = _converter.epsg3857ToPoint(tileTopLeft3857); + final tileBottomRightPx = _converter.epsg3857ToPoint(tileBottomRight3857); + if (tileTopLeftPx == null || tileBottomRightPx == null) return null; + + final tileLeft = tileTopLeftPx.x; + final tileRight = tileBottomRightPx.x; + final tileTop = tileTopLeftPx.y; + final tileBottom = tileBottomRightPx.y; + + final width = entry.width; + final height = entry.height; + + final regionLeft = tileLeft.clamp(0, width); + final regionRight = tileRight.clamp(0, width); + final regionTop = tileTop.clamp(0, height); + final regionBottom = tileBottom.clamp(0, height); + + final regionWidth = regionRight - regionLeft; + final regionHeight = regionBottom - regionTop; + if (regionWidth == 0 || regionHeight == 0) return null; + + final tileXScale = (tileRight - tileLeft) / _mapServiceTileSize; + final sampleSize = max(1, highestPowerOf2(tileXScale)); + final region = entry.getRegion( + sampleSize: sampleSize, + region: Rectangle(regionLeft, regionTop, regionWidth, regionHeight), + ); + + final imageInfoCompleter = Completer(); + final imageStream = region.resolve(ImageConfiguration.empty); + final imageStreamListener = ImageStreamListener((image, synchronousCall) { + imageInfoCompleter.complete(image); + }, onError: imageInfoCompleter.completeError); + imageStream.addListener(imageStreamListener); + ImageInfo? regionImageInfo; + try { + regionImageInfo = await imageInfoCompleter.future; + } catch (error) { + debugPrint('failed to get image for region=$region with error=$error'); + } + imageStream.removeListener(imageStreamListener); + + final imageOffset = Offset( + regionLeft > tileLeft ? (regionLeft - tileLeft).toDouble() : 0, + regionTop > tileTop ? (regionTop - tileTop).toDouble() : 0, + ); + final tileImageScaleX = (tileRight - tileLeft) / _mapServiceTileSize; + final tileImageScaleY = (tileBottom - tileTop) / _mapServiceTileSize; + + final recorder = ui.PictureRecorder(); + final canvas = Canvas(recorder); + canvas.scale(1 / tileImageScaleX, 1 / tileImageScaleY); + if (regionImageInfo != null) { + final s = sampleSize.toDouble(); + canvas.scale(s, s); + canvas.drawImage(regionImageInfo.image, imageOffset / s, _tileImagePaint); + canvas.scale(1 / s, 1 / s); + } else { + // fallback to show area + canvas.drawRect( + Rect.fromLTWH( + imageOffset.dx, + imageOffset.dy, + regionWidth.toDouble(), + regionHeight.toDouble(), + ), + _tileMissingPaint, + ); + } + canvas.scale(tileImageScaleX, tileImageScaleY); + + final picture = recorder.endRecording(); + final tileImage = await picture.toImage(_mapServiceTileSize, _mapServiceTileSize); + final byteData = await tileImage.toByteData(format: ui.ImageByteFormat.png); + if (byteData == null) return null; + + return MapTile( + width: tileImage.width, + height: tileImage.height, + data: byteData.buffer.asUint8List(), + ); + } + + @override + String get id => entry.uri; + + @override + ImageProvider get imageProvider => entry.uriImage; + + @override + bool get canOverlay => center != null; + + LatLng? get center => _converter.center; + + @override + LatLng? get topLeft => _converter.topLeft; + + @override + LatLng? get bottomRight => _converter.bottomRight; +} + +class GeoTiffCoordinateConverter { + final AvesEntry entry; + + late LatLng? Function(Point pixel) pointToLatLng; + late Point? Function(Point smPoint) epsg3857ToPoint; + + GeoTiffCoordinateConverter({ + required GeoTiffInfo info, + required this.entry, }) { pointToLatLng = (_) => null; epsg3857ToPoint = (_) => null; @@ -129,113 +254,13 @@ class MappedGeoTiff with MapOverlay { }; } - @override - Future getTile(int tx, int ty, int? zoomLevel) async { - zoomLevel ??= 0; - - // global projected coordinates in meters (EPSG:3857 Spherical Mercator) - final tileTopLeft3857 = mapServiceHelper.tileTopLeft(tx, ty, zoomLevel); - final tileBottomRight3857 = mapServiceHelper.tileTopLeft(tx + 1, ty + 1, zoomLevel); - - // image region coordinates in pixels - final tileTopLeftPx = epsg3857ToPoint(tileTopLeft3857); - final tileBottomRightPx = epsg3857ToPoint(tileBottomRight3857); - if (tileTopLeftPx == null || tileBottomRightPx == null) return null; - - final tileLeft = tileTopLeftPx.x; - final tileRight = tileBottomRightPx.x; - final tileTop = tileTopLeftPx.y; - final tileBottom = tileBottomRightPx.y; - - final regionLeft = tileLeft.clamp(0, width); - final regionRight = tileRight.clamp(0, width); - final regionTop = tileTop.clamp(0, height); - final regionBottom = tileBottom.clamp(0, height); - - final regionWidth = regionRight - regionLeft; - final regionHeight = regionBottom - regionTop; - if (regionWidth == 0 || regionHeight == 0) return null; - - final tileXScale = (tileRight - tileLeft) / mapServiceTileSize; - final sampleSize = max(1, highestPowerOf2(tileXScale)); - final region = entry.getRegion( - sampleSize: sampleSize, - region: Rectangle(regionLeft, regionTop, regionWidth, regionHeight), - ); - - final imageInfoCompleter = Completer(); - final imageStream = region.resolve(ImageConfiguration.empty); - final imageStreamListener = ImageStreamListener((image, synchronousCall) { - imageInfoCompleter.complete(image); - }, onError: imageInfoCompleter.completeError); - imageStream.addListener(imageStreamListener); - ImageInfo? regionImageInfo; - try { - regionImageInfo = await imageInfoCompleter.future; - } catch (error) { - debugPrint('failed to get image for region=$region with error=$error'); - } - imageStream.removeListener(imageStreamListener); - - final imageOffset = Offset( - regionLeft > tileLeft ? (regionLeft - tileLeft).toDouble() : 0, - regionTop > tileTop ? (regionTop - tileTop).toDouble() : 0, - ); - final tileImageScaleX = (tileRight - tileLeft) / mapServiceTileSize; - final tileImageScaleY = (tileBottom - tileTop) / mapServiceTileSize; - - final recorder = ui.PictureRecorder(); - final canvas = Canvas(recorder); - canvas.scale(1 / tileImageScaleX, 1 / tileImageScaleY); - if (regionImageInfo != null) { - final s = sampleSize.toDouble(); - canvas.scale(s, s); - canvas.drawImage(regionImageInfo.image, imageOffset / s, tileImagePaint); - canvas.scale(1 / s, 1 / s); - } else { - // fallback to show area - canvas.drawRect( - Rect.fromLTWH( - imageOffset.dx, - imageOffset.dy, - regionWidth.toDouble(), - regionHeight.toDouble(), - ), - tileMissingPaint, - ); - } - canvas.scale(tileImageScaleX, tileImageScaleY); - - final picture = recorder.endRecording(); - final tileImage = await picture.toImage(mapServiceTileSize, mapServiceTileSize); - final byteData = await tileImage.toByteData(format: ui.ImageByteFormat.png); - if (byteData == null) return null; - - return MapTile( - width: tileImage.width, - height: tileImage.height, - data: byteData.buffer.asUint8List(), - ); - } - - @override - String get id => entry.uri; - - @override - ImageProvider get imageProvider => entry.uriImage; - int get width => entry.width; int get height => entry.height; - @override - bool get canOverlay => center != null; - LatLng? get center => pointToLatLng(Point((width / 2).round(), (height / 2).round())); - @override LatLng? get topLeft => pointToLatLng(const Point(0, 0)); - @override LatLng? get bottomRight => pointToLatLng(Point(width, height)); } diff --git a/lib/model/naming_pattern.dart b/lib/model/naming_pattern.dart index 2fd502291..e5eee02d4 100644 --- a/lib/model/naming_pattern.dart +++ b/lib/model/naming_pattern.dart @@ -38,10 +38,8 @@ class NamingPattern { if (processorOptions != null) { processors.add(DateNamingProcessor(processorOptions.trim())); } - break; case NameNamingProcessor.key: processors.add(const NameNamingProcessor()); - break; case CounterNamingProcessor.key: int? start, padding; _applyProcessorOptions(processorOptions, (key, value) { @@ -50,18 +48,14 @@ class NamingPattern { switch (key) { case CounterNamingProcessor.optionStart: start = valueInt; - break; case CounterNamingProcessor.optionPadding: padding = valueInt; - break; } } }); processors.add(CounterNamingProcessor(start: start ?? defaultCounterStart, padding: padding ?? defaultCounterPadding)); - break; default: debugPrint('unsupported naming processor: ${match.group(0)}'); - break; } index = end; }); diff --git a/lib/model/settings/enums/display_refresh_rate_mode.dart b/lib/model/settings/enums/display_refresh_rate_mode.dart index 942d901b9..32d1cd28b 100644 --- a/lib/model/settings/enums/display_refresh_rate_mode.dart +++ b/lib/model/settings/enums/display_refresh_rate_mode.dart @@ -15,13 +15,10 @@ extension ExtraDisplayRefreshRateMode on DisplayRefreshRateMode { switch (this) { case DisplayRefreshRateMode.auto: await FlutterDisplayMode.setPreferredMode(DisplayMode.auto); - break; case DisplayRefreshRateMode.highest: await FlutterDisplayMode.setHighRefreshRate(); - break; case DisplayRefreshRateMode.lowest: await FlutterDisplayMode.setLowRefreshRate(); - break; } } } diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index b9a0ea3c8..966b545db 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -375,7 +375,7 @@ class Settings extends ChangeNotifier { if (_locale != null) { preferredLocales.add(_locale); } else { - preferredLocales.addAll(WidgetsBinding.instance.window.locales); + preferredLocales.addAll(WidgetsBinding.instance.platformDispatcher.locales); if (preferredLocales.isEmpty) { // the `window` locales may be empty in a window-less service context preferredLocales.addAll(_systemLocalesFallback); @@ -1022,7 +1022,6 @@ class Settings extends ChangeNotifier { if (value is num) { isRotationLocked = value == 0; } - break; case platformTransitionAnimationScaleKey: if (value is num) { areAnimationsRemoved = value == 0; @@ -1080,7 +1079,6 @@ class Settings extends ChangeNotifier { } else { debugPrint('failed to import key=$key, value=$newValue is not an int'); } - break; case subtitleFontSizeKey: case infoMapZoomKey: if (newValue is double) { @@ -1088,7 +1086,6 @@ class Settings extends ChangeNotifier { } else { debugPrint('failed to import key=$key, value=$newValue is not a double'); } - break; case isInstalledAppAccessAllowedKey: case isErrorReportingAllowedKey: case enableDynamicColorKey: @@ -1144,7 +1141,6 @@ class Settings extends ChangeNotifier { } else { debugPrint('failed to import key=$key, value=$newValue is not a bool'); } - break; case localeKey: case displayRefreshRateModeKey: case themeBrightnessKey: @@ -1187,7 +1183,6 @@ class Settings extends ChangeNotifier { } else { debugPrint('failed to import key=$key, value=$newValue is not a string'); } - break; case drawerTypeBookmarksKey: case drawerAlbumBookmarksKey: case drawerPageBookmarksKey: @@ -1203,7 +1198,6 @@ class Settings extends ChangeNotifier { } else { debugPrint('failed to import key=$key, value=$newValue is not a list'); } - break; } } if (oldValue != newValue) { diff --git a/lib/model/source/album.dart b/lib/model/source/album.dart index e4524418e..809086b97 100644 --- a/lib/model/source/album.dart +++ b/lib/model/source/album.dart @@ -47,13 +47,10 @@ mixin AlbumMixin on SourceBase { switch (androidFileUtils.getAlbumType(album)) { case AlbumType.regular: regularAlbums.add(album); - break; case AlbumType.app: appAlbums.add(album); - break; default: specialAlbums.add(album); - break; } } return Map.fromEntries([...specialAlbums, ...appAlbums, ...regularAlbums].map((album) => MapEntry( diff --git a/lib/model/source/collection_lens.dart b/lib/model/source/collection_lens.dart index 44b37f548..dfc922a3b 100644 --- a/lib/model/source/collection_lens.dart +++ b/lib/model/source/collection_lens.dart @@ -68,10 +68,8 @@ class CollectionLens with ChangeNotifier { case MoveType.move: case MoveType.fromBin: refresh(); - break; case MoveType.toBin: _onEntryRemoved(e.entries); - break; } })); _subscriptions.add(sourceEvents.on().listen((e) => refresh())); @@ -213,16 +211,12 @@ class CollectionLens with ChangeNotifier { switch (sortFactor) { case EntrySortFactor.date: _filteredSortedEntries.sort(AvesEntrySort.compareByDate); - break; case EntrySortFactor.name: _filteredSortedEntries.sort(AvesEntrySort.compareByName); - break; case EntrySortFactor.rating: _filteredSortedEntries.sort(AvesEntrySort.compareByRating); - break; case EntrySortFactor.size: _filteredSortedEntries.sort(AvesEntrySort.compareBySize); - break; } if (sortReverse) { _filteredSortedEntries = _filteredSortedEntries.reversed.toList(); @@ -240,33 +234,25 @@ class CollectionLens with ChangeNotifier { switch (sectionFactor) { case EntryGroupFactor.album: sections = groupBy(_filteredSortedEntries, (entry) => EntryAlbumSectionKey(entry.directory)); - break; case EntryGroupFactor.month: sections = groupBy(_filteredSortedEntries, (entry) => EntryDateSectionKey(entry.monthTaken)); - break; case EntryGroupFactor.day: sections = groupBy(_filteredSortedEntries, (entry) => EntryDateSectionKey(entry.dayTaken)); - break; case EntryGroupFactor.none: sections = Map.fromEntries([ MapEntry(const SectionKey(), _filteredSortedEntries), ]); - break; } - break; case EntrySortFactor.name: final byAlbum = groupBy(_filteredSortedEntries, (entry) => EntryAlbumSectionKey(entry.directory)); final compare = sortReverse ? (a, b) => source.compareAlbumsByName(b.directory!, a.directory!) : (a, b) => source.compareAlbumsByName(a.directory!, b.directory!); sections = SplayTreeMap>.of(byAlbum, compare); - break; case EntrySortFactor.rating: sections = groupBy(_filteredSortedEntries, (entry) => EntryRatingSectionKey(entry.rating)); - break; case EntrySortFactor.size: sections = Map.fromEntries([ MapEntry(const SectionKey(), _filteredSortedEntries), ]); - break; } } sections = Map.unmodifiable(sections); diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index ec7d49304..5464e6774 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -221,18 +221,14 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place switch (key) { case 'contentId': entry.contentId = newValue as int?; - break; case 'dateModifiedSecs': // `dateModifiedSecs` changes when moving entries to another directory, // but it does not change when renaming the containing directory entry.dateModifiedSecs = newValue as int?; - break; case 'path': entry.path = newValue as String?; - break; case 'title': entry.sourceTitle = newValue as String?; - break; case 'trashed': final trashed = newValue as bool; entry.trashed = trashed; @@ -243,13 +239,10 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place dateMillis: DateTime.now().millisecondsSinceEpoch, ) : null; - break; case 'uri': entry.uri = newValue as String; - break; case 'origin': entry.origin = newValue as int; - break; } }); if (entry.trashed) { @@ -371,16 +364,13 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place switch (moveType) { case MoveType.copy: addEntries(movedEntries); - break; case MoveType.move: case MoveType.export: cleanEmptyAlbums(fromAlbums.whereNotNull().toSet()); addDirectories(albums: destinationAlbums); - break; case MoveType.toBin: case MoveType.fromBin: updateDerivedFilters(movedEntries); - break; } invalidateAlbumFilterSummary(directories: fromAlbums); _invalidate(entries: movedEntries); diff --git a/lib/model/video/metadata.dart b/lib/model/video/metadata.dart index eab4c5031..25593eb39 100644 --- a/lib/model/video/metadata.dart +++ b/lib/model/video/metadata.dart @@ -210,38 +210,29 @@ class VideoMetadataFormatter { case Keys.androidCaptureFramerate: final captureFps = double.parse(value); save('Capture Frame Rate', '${roundToPrecision(captureFps, decimals: 3).toString()} FPS'); - break; case Keys.androidManufacturer: save('Android Manufacturer', value); - break; case Keys.androidModel: save('Android Model', value); - break; case Keys.androidVersion: save('Android Version', value); - break; case Keys.bitrate: case Keys.bps: save('Bit Rate', _formatMetric(value, 'b/s')); - break; case Keys.byteCount: save('Size', _formatFilesize(value)); - break; case Keys.channelLayout: save('Channel Layout', _formatChannelLayout(value)); - break; case Keys.codecName: if (value != 'none') { save('Format', _formatCodecName(value)); } - break; case Keys.codecPixelFormat: if (streamType == MediaStreamTypes.video) { // this is just a short name used by FFmpeg // user-friendly descriptions for related enums are defined in libavutil/pixfmt.h save('Pixel Format', (value as String).toUpperCase()); } - break; case Keys.codecProfileId: { final profile = int.tryParse(value); @@ -260,18 +251,14 @@ class VideoMetadataFormatter { profileString = Hevc.formatProfile(profile, level); } } - break; } case Codecs.aac: profileString = AAC.formatProfile(profile); - break; default: profileString = profile.toString(); - break; } save('Format Profile', profileString); } - break; } case Keys.compatibleBrands: final formattedBrands = RegExp(r'.{4}').allMatches(value).map((m) { @@ -279,52 +266,37 @@ class VideoMetadataFormatter { return _formatBrand(brand); }).join(', '); save('Compatible Brands', formattedBrands); - break; case Keys.creationTime: save('Creation Time', _formatDate(value)); - break; case Keys.date: if (value is String && value != '0') { final charCount = value.length; save(charCount == 4 ? 'Year' : 'Date', value); } - break; case Keys.duration: save('Duration', _formatDuration(value)); - break; case Keys.durationMicros: if (value != 0) save('Duration', formatPreciseDuration(Duration(microseconds: value))); - break; case Keys.fpsDen: save('Frame Rate', '${roundToPrecision(info[Keys.fpsNum] / info[Keys.fpsDen], decimals: 3).toString()} FPS'); - break; case Keys.frameCount: save('Frame Count', value); - break; case Keys.height: save('Height', '$value pixels'); - break; case Keys.language: if (value != 'und') save('Language', _formatLanguage(value)); - break; case Keys.location: save('Location', _formatLocation(value)); - break; case Keys.majorBrand: save('Major Brand', _formatBrand(value)); - break; case Keys.mediaFormat: save('Format', (value as String).splitMapJoin(',', onMatch: (s) => ', ', onNonMatch: _formatCodecName)); - break; case Keys.mediaType: save('Media Type', value); - break; case Keys.minorVersion: if (value != '0') save('Minor Version', value); - break; case Keys.quicktimeLocationAccuracyHorizontal: save('QuickTime Location Horizontal Accuracy', value); - break; case Keys.quicktimeCreationDate: case Keys.quicktimeLocationIso6709: case Keys.quicktimeMake: @@ -334,37 +306,27 @@ class VideoMetadataFormatter { break; case Keys.rotate: save('Rotation', '$value°'); - break; case Keys.sampleRate: save('Sample Rate', _formatMetric(value, 'Hz')); - break; case Keys.sarDen: final sarNum = info[Keys.sarNum]; final sarDen = info[Keys.sarDen]; // skip common square pixels (1:1) if (sarNum != sarDen) save('SAR', '$sarNum:$sarDen'); - break; case Keys.sourceOshash: save('Source OSHash', value); - break; case Keys.startMicros: if (value != 0) save('Start', formatPreciseDuration(Duration(microseconds: value))); - break; case Keys.statisticsWritingApp: save('Stats Writing App', value); - break; case Keys.statisticsWritingDateUtc: save('Stats Writing Date', _formatDate(value)); - break; case Keys.track: if (value != '0') save('Track', value); - break; case Keys.width: save('Width', '$value pixels'); - break; case Keys.xiaomiSlowMoment: save('Xiaomi Slow Moment', value); - break; default: save(key.toSentenceCase(), value.toString()); } diff --git a/lib/model/video/profiles/h264.dart b/lib/model/video/profiles/h264.dart index c9fe1dae6..5fb99ace3 100644 --- a/lib/model/video/profiles/h264.dart +++ b/lib/model/video/profiles/h264.dart @@ -28,43 +28,30 @@ class H264 { switch (profileIndex) { case profileBaseline: profile = 'Baseline'; - break; case profileConstrainedBaseline: profile = 'Constrained Baseline'; - break; case profileMain: profile = 'Main'; - break; case profileExtended: profile = 'Extended'; - break; case profileHigh: profile = 'High'; - break; case profileHigh10: profile = 'High 10'; - break; case profileHigh10Intra: profile = 'High 10 Intra'; - break; case profileHigh422: profile = 'High 4:2:2'; - break; case profileHigh422Intra: profile = 'High 4:2:2 Intra'; - break; case profileHigh444: profile = 'High 4:4:4'; - break; case profileHigh444Predictive: profile = 'High 4:4:4 Predictive'; - break; case profileHigh444Intra: profile = 'High 4:4:4 Intra'; - break; case profileCAVLC444: profile = 'CAVLC 4:4:4'; - break; default: return '$profileIndex'; } diff --git a/lib/model/video/profiles/hevc.dart b/lib/model/video/profiles/hevc.dart index 4678fa699..880982eef 100644 --- a/lib/model/video/profiles/hevc.dart +++ b/lib/model/video/profiles/hevc.dart @@ -9,16 +9,12 @@ class Hevc { switch (profileIndex) { case profileMain: profile = 'Main'; - break; case profileMain10: profile = 'Main 10'; - break; case profileMainStillPicture: profile = 'Main Still Picture'; - break; case profileRExt: profile = 'Format Range'; - break; default: return '$profileIndex'; } diff --git a/lib/ref/poi.dart b/lib/ref/poi.dart index 1aebe9aae..951239d39 100644 --- a/lib/ref/poi.dart +++ b/lib/ref/poi.dart @@ -12,4 +12,4 @@ class PointsOfInterest { LatLng(37.637861, 21.63), LatLng(37.949722, 27.363889), ]; -} \ No newline at end of file +} diff --git a/lib/services/analysis_service.dart b/lib/services/analysis_service.dart index 50fea1499..9c656db62 100644 --- a/lib/services/analysis_service.dart +++ b/lib/services/analysis_service.dart @@ -145,11 +145,9 @@ class Analyzer { case AnalyzerState.stopping: await _stopPlatformService(); _serviceStateNotifier.value = AnalyzerState.stopped; - break; case AnalyzerState.stopped: _controller?.stopSignal.value = true; _stopUpdateTimer(); - break; } } diff --git a/lib/services/media/media_session_service.dart b/lib/services/media/media_session_service.dart index 8280965c7..2d287f910 100644 --- a/lib/services/media/media_session_service.dart +++ b/lib/services/media/media_session_service.dart @@ -96,25 +96,19 @@ class PlatformMediaSessionService implements MediaSessionService, Disposable { switch (command) { case 'play': event = const MediaCommandEvent(MediaCommand.play); - break; case 'pause': event = const MediaCommandEvent(MediaCommand.pause); - break; case 'skip_to_next': event = const MediaCommandEvent(MediaCommand.skipToNext); - break; case 'skip_to_previous': event = const MediaCommandEvent(MediaCommand.skipToPrevious); - break; case 'stop': event = const MediaCommandEvent(MediaCommand.stop); - break; case 'seek': final position = fields['position'] as int?; if (position != null) { event = MediaSeekCommandEvent(MediaCommand.stop, position: position); } - break; } if (event != null) { _streamController.add(event); diff --git a/lib/services/metadata/svg_metadata_service.dart b/lib/services/metadata/svg_metadata_service.dart index 677bb97dc..0567b1908 100644 --- a/lib/services/metadata/svg_metadata_service.dart +++ b/lib/services/metadata/svg_metadata_service.dart @@ -80,7 +80,7 @@ class SvgMetadataService { final docDir = Map.fromEntries([ ...root.attributes.where((a) => _attributes.contains(a.name.qualified)).map((a) => MapEntry(formatKey(a.name.qualified), a.value)), ..._textElements.map((name) { - final value = root.getElement(name)?.text; + final value = root.getElement(name)?.innerText; return value != null ? MapEntry(formatKey(name), value) : null; }).whereNotNull(), ]); diff --git a/lib/services/window_service.dart b/lib/services/window_service.dart index 81796bff8..44f9a9d73 100644 --- a/lib/services/window_service.dart +++ b/lib/services/window_service.dart @@ -74,15 +74,12 @@ class PlatformWindowService implements WindowService { case Orientation.landscape: // SCREEN_ORIENTATION_SENSOR_LANDSCAPE orientationCode = 6; - break; case Orientation.portrait: // SCREEN_ORIENTATION_SENSOR_PORTRAIT orientationCode = 7; - break; default: // SCREEN_ORIENTATION_UNSPECIFIED orientationCode = -1; - break; } try { await _platform.invokeMethod('requestOrientation', { diff --git a/lib/theme/text.dart b/lib/theme/text.dart index b7840d33f..27501eb06 100644 --- a/lib/theme/text.dart +++ b/lib/theme/text.dart @@ -4,4 +4,4 @@ class AText { static const separator = ' ${UniChars.bullet} '; static const resolutionSeparator = ' ${UniChars.multiplicationSign} '; static const valueNotAvailable = UniChars.emDash; -} \ No newline at end of file +} diff --git a/lib/utils/diff_match.dart b/lib/utils/diff_match.dart index 29042c4de..4c4a7b9ef 100644 --- a/lib/utils/diff_match.dart +++ b/lib/utils/diff_match.dart @@ -274,11 +274,9 @@ class DiffMatchPatch { case Operation.insert: count_insert++; text_insert.write(diffs[pointer].text); - break; case Operation.delete: count_delete++; text_delete.write(diffs[pointer].text); - break; case Operation.equal: // Upon reaching an equality, check for prior redundancies. if (count_delete >= 1 && count_insert >= 1) { @@ -295,7 +293,6 @@ class DiffMatchPatch { count_delete = 0; text_delete.clear(); text_insert.clear(); - break; } pointer++; } @@ -1013,12 +1010,10 @@ class DiffMatchPatch { count_insert++; text_insert += diffs[pointer].text; pointer++; - break; case Operation.delete: count_delete++; text_delete += diffs[pointer].text; pointer++; - break; case Operation.equal: // Upon reaching an equality, check for prior redundancies. if (count_delete + count_insert > 1) { @@ -1068,7 +1063,6 @@ class DiffMatchPatch { count_delete = 0; text_delete = ''; text_insert = ''; - break; } } if (diffs.last.text.isEmpty) { @@ -1155,17 +1149,14 @@ class DiffMatchPatch { html.write(''); html.write(text); html.write(''); - break; case Operation.delete: html.write(''); html.write(text); html.write(''); - break; case Operation.equal: html.write(''); html.write(text); html.write(''); - break; } } return html.toString(); @@ -1209,16 +1200,13 @@ class DiffMatchPatch { switch (aDiff.operation) { case Operation.insert: insertions += aDiff.text.length; - break; case Operation.delete: deletions += aDiff.text.length; - break; case Operation.equal: // A deletion and an insertion is one substitution. levenshtein += max(insertions, deletions); insertions = 0; deletions = 0; - break; } } levenshtein += max(insertions, deletions); @@ -1239,17 +1227,14 @@ class DiffMatchPatch { text.write('+'); text.write(Uri.encodeFull(aDiff.text)); text.write('\t'); - break; case Operation.delete: text.write('-'); text.write(aDiff.text.length); text.write('\t'); - break; case Operation.equal: text.write('='); text.write(aDiff.text.length); text.write('\t'); - break; } } String delta = text.toString(); @@ -1289,7 +1274,6 @@ class DiffMatchPatch { throw ArgumentError('Illegal escape in diff_fromDelta: $param'); } diffs.add(Diff(Operation.insert, param)); - break; case '-': // Fall through. case '=': @@ -1314,7 +1298,6 @@ class DiffMatchPatch { } else { diffs.add(Diff(Operation.delete, text)); } - break; default: // Anything else is an error. throw ArgumentError('Invalid diff operation in diff_fromDelta: ${token[0]}'); diff --git a/lib/utils/xmp_utils.dart b/lib/utils/xmp_utils.dart index c46274fa7..0953bac31 100644 --- a/lib/utils/xmp_utils.dart +++ b/lib/utils/xmp_utils.dart @@ -26,7 +26,7 @@ class XMP { static const nsXmp = XmpNamespaces.xmp; // for `rdf:Description` node only - static bool _hasMeaningfulChildren(XmlNode node) => node.children.any((v) => v.nodeType != XmlNodeType.TEXT || v.text.trim().isNotEmpty); + static bool _hasMeaningfulChildren(XmlNode node) => node.children.any((v) => v.nodeType != XmlNodeType.TEXT || v.innerText.trim().isNotEmpty); // for `rdf:Description` node only static bool _hasMeaningfulAttributes(XmlNode description) { diff --git a/lib/widget_common.dart b/lib/widget_common.dart index fe14fee12..4ea33f334 100644 --- a/lib/widget_common.dart +++ b/lib/widget_common.dart @@ -79,10 +79,8 @@ Future _getWidgetEntry(int widgetId, bool reuseEntry) async { switch (settings.getWidgetDisplayedItem(widgetId)) { case WidgetDisplayedItem.random: entries.shuffle(); - break; case WidgetDisplayedItem.mostRecent: entries.sort(AvesEntrySort.compareByDate); - break; } final entry = entries.firstOrNull; if (entry != null) { diff --git a/lib/widgets/about/app_ref.dart b/lib/widgets/about/app_ref.dart index 83c6000d0..af20e6d55 100644 --- a/lib/widgets/about/app_ref.dart +++ b/lib/widgets/about/app_ref.dart @@ -94,11 +94,12 @@ class _AppReferenceState extends State { return FutureBuilder( future: _packageInfoLoader, builder: (context, snapshot) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return Row( mainAxisSize: MainAxisSize.min, children: [ AvesLogo( - size: _appTitleStyle.fontSize! * MediaQuery.textScaleFactorOf(context) * 1.3, + size: _appTitleStyle.fontSize! * textScaleFactor * 1.3, ), const SizedBox(width: 8), Text( diff --git a/lib/widgets/about/bug_report.dart b/lib/widgets/about/bug_report.dart index 954146ea2..6cb94eb44 100644 --- a/lib/widgets/about/bug_report.dart +++ b/lib/widgets/about/bug_report.dart @@ -157,7 +157,7 @@ class _BugReportState extends State with FeedbackMixin { 'Device: ${androidInfo.manufacturer} ${androidInfo.model}', 'Geocoder: ${device.hasGeocoder ? 'ready' : 'not available'}', 'Mobile services: ${mobileServices.isServiceAvailable ? 'ready' : 'not available'}', - 'System locales: ${WidgetsBinding.instance.window.locales.join(', ')}', + 'System locales: ${WidgetsBinding.instance.platformDispatcher.locales.join(', ')}', 'Storage volumes: ${storageVolumes.map((v) => v.path).join(', ')}', 'Storage grants: ${storageGrants.join(', ')}', 'Error reporting: ${settings.isErrorReportingAllowed}', diff --git a/lib/widgets/about/tv_license_page.dart b/lib/widgets/about/tv_license_page.dart index fa4e2b7e2..ef229b3e9 100644 --- a/lib/widgets/about/tv_license_page.dart +++ b/lib/widgets/about/tv_license_page.dart @@ -1,7 +1,9 @@ +import 'dart:developer' show Flow, Timeline; + import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/behaviour/intents.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' hide Flow; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; @@ -209,10 +211,21 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { bool _loaded = false; Future _initLicenses() async { + int debugFlowId = -1; + assert(() { + final Flow flow = Flow.begin(); + Timeline.timeSync('_initLicenses()', () {}, flow: flow); + debugFlowId = flow.id; + return true; + }()); for (final LicenseEntry license in widget.licenseEntries) { if (!mounted) { return; } + assert(() { + Timeline.timeSync('_initLicenses()', () {}, flow: Flow.step(debugFlowId)); + return true; + }()); final List paragraphs = await SchedulerBinding.instance.scheduleTask>( license.paragraphs.toList, Priority.animation, @@ -237,6 +250,7 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { ), )); } else { + assert(paragraph.indent >= 0); _licenses.add(Padding( padding: EdgeInsetsDirectional.only(top: 8.0, start: 16.0 * paragraph.indent), child: Text(paragraph.text), @@ -248,16 +262,21 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { setState(() { _loaded = true; }); + assert(() { + Timeline.timeSync('Build scheduled', () {}, flow: Flow.end(debugFlowId)); + return true; + }()); } @override Widget build(BuildContext context) { + assert(debugCheckHasMaterialLocalizations(context)); final MaterialLocalizations localizations = MaterialLocalizations.of(context); final ThemeData theme = Theme.of(context); final String title = widget.packageName; final String subtitle = localizations.licensesPackageDetailText(widget.licenseEntries.length); - const double pad = 24; - const EdgeInsets padding = EdgeInsets.only(left: pad, right: pad, bottom: pad); + final double pad = _getGutterSize(context); + final EdgeInsets padding = EdgeInsets.only(left: pad, right: pad, bottom: pad); final List listWidgets = [ ..._licenses, if (!_loaded) @@ -274,9 +293,11 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { page = Scaffold( appBar: AppBar( title: _PackageLicensePageTitle( - title, - subtitle, - theme.primaryTextTheme, + title: title, + subtitle: subtitle, + theme: theme.useMaterial3 ? theme.textTheme : theme.primaryTextTheme, + titleTextStyle: theme.appBarTheme.titleTextStyle, + foregroundColor: theme.appBarTheme.foregroundColor, ), ), body: Center( @@ -292,7 +313,11 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { // A Scrollbar is built-in below. behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), child: Scrollbar( - child: ListView(padding: padding, children: listWidgets), + child: ListView( + primary: true, + padding: padding, + children: listWidgets, + ), ), ), ), @@ -308,7 +333,12 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { automaticallyImplyLeading: false, pinned: true, backgroundColor: theme.cardColor, - title: _PackageLicensePageTitle(title, subtitle, theme.textTheme), + title: _PackageLicensePageTitle( + title: title, + subtitle: subtitle, + theme: theme.textTheme, + titleTextStyle: theme.textTheme.titleLarge, + ), ), SliverPadding( padding: padding, @@ -334,27 +364,36 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { } class _PackageLicensePageTitle extends StatelessWidget { - const _PackageLicensePageTitle( - this.title, - this.subtitle, - this.theme, - ); + const _PackageLicensePageTitle({ + required this.title, + required this.subtitle, + required this.theme, + this.titleTextStyle, + this.foregroundColor, + }); final String title; final String subtitle; final TextTheme theme; + final TextStyle? titleTextStyle; + final Color? foregroundColor; @override Widget build(BuildContext context) { - final Color? color = Theme.of(context).appBarTheme.foregroundColor; - + final TextStyle? effectiveTitleTextStyle = titleTextStyle ?? theme.titleLarge; return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(title, style: theme.titleLarge?.copyWith(color: color)), - Text(subtitle, style: theme.titleSmall?.copyWith(color: color)), + Text(title, style: effectiveTitleTextStyle?.copyWith(color: foregroundColor)), + Text(subtitle, style: theme.titleSmall?.copyWith(color: foregroundColor)), ], ); } } + +const int _materialGutterThreshold = 720; +const double _wideGutterSize = 24.0; +const double _narrowGutterSize = 12.0; + +double _getGutterSize(BuildContext context) => MediaQuery.sizeOf(context).width >= _materialGutterThreshold ? _wideGutterSize : _narrowGutterSize; diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 01ef95154..d34dfd3a4 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:math'; -import 'dart:ui'; import 'package:aves/app_flavor.dart'; import 'package:aves/app_mode.dart'; @@ -180,8 +179,6 @@ class _AvesAppState extends State with WidgetsBindingObserver { super.initState(); EquatableConfig.stringify = true; _appSetup = _setup(); - // remember screen size to use it later, when `context` and `window` are no longer reliable - _screenSize = _getScreenSize(); _shouldUseBoldFontLoader = AccessibilityService.shouldUseBoldFont(); _dynamicColorPaletteLoader = DynamicColorPlugin.getCorePalette(); _subscriptions.add(_mediaStoreChangeChannel.receiveBroadcastStream().listen((event) => _onMediaStoreChanged(event as String?))); @@ -206,6 +203,9 @@ class _AvesAppState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { + // remember screen size to use it later, when `context` and `window` are no longer reliable + _screenSize ??= _getScreenSize(context); + // place the settings provider above `MaterialApp` // so it can be used during navigation transitions return MultiProvider( @@ -266,38 +266,31 @@ class _AvesAppState extends State with WidgetsBindingObserver { // KEYCODE_ENTER, KEYCODE_BUTTON_A, KEYCODE_NUMPAD_ENTER LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), }, - child: MediaQuery.fromWindow( - child: Builder( - builder: (context) { - return MediaQuery( - data: MediaQuery.of(context).copyWith( - // disable accessible navigation, as it impacts snack bar action timer - // for all users of apps registered as accessibility services, - // even though they are not for accessibility purposes (like TalkBack is) - accessibleNavigation: false, - ), - child: MaterialApp( - navigatorKey: _navigatorKey, - home: home, - navigatorObservers: _navigatorObservers, - builder: (context, child) => _decorateAppChild( - context: context, - initialized: initialized, - child: child, - ), - onGenerateTitle: (context) => context.l10n.appName, - theme: lightTheme, - darkTheme: darkTheme, - themeMode: themeBrightness.appThemeMode, - locale: settingsLocale, - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AvesApp.supportedLocales, - // TODO TLAD remove custom scroll behavior when this is fixed: https://github.com/flutter/flutter/issues/82906 - scrollBehavior: StretchMaterialScrollBehavior(), - useInheritedMediaQuery: true, - ), - ); - }, + child: MediaQuery( + data: MediaQuery.of(context).copyWith( + // disable accessible navigation, as it impacts snack bar action timer + // for all users of apps registered as accessibility services, + // even though they are not for accessibility purposes (like TalkBack is) + accessibleNavigation: false, + ), + child: MaterialApp( + navigatorKey: _navigatorKey, + home: home, + navigatorObservers: _navigatorObservers, + builder: (context, child) => _decorateAppChild( + context: context, + initialized: initialized, + child: child, + ), + onGenerateTitle: (context) => context.l10n.appName, + theme: lightTheme, + darkTheme: darkTheme, + themeMode: themeBrightness.appThemeMode, + locale: settingsLocale, + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AvesApp.supportedLocales, + // TODO TLAD remove custom scroll behavior when this is fixed: https://github.com/flutter/flutter/issues/82906 + scrollBehavior: StretchMaterialScrollBehavior(), ), ), ); @@ -390,7 +383,6 @@ class _AvesAppState extends State with WidgetsBindingObserver { case AppMode.pickSingleMediaExternal: case AppMode.pickMultipleMediaExternal: _saveTopEntries(); - break; case AppMode.pickCollectionFiltersExternal: case AppMode.pickMediaInternal: case AppMode.pickFilterInternal: @@ -400,10 +392,8 @@ class _AvesAppState extends State with WidgetsBindingObserver { case AppMode.view: break; } - break; case AppLifecycleState.resumed: RecentlyAddedFilter.updateNow(); - break; case AppLifecycleState.paused: case AppLifecycleState.detached: break; @@ -421,9 +411,10 @@ class _AvesAppState extends State with WidgetsBindingObserver { Widget _getFirstPage({Map? intentData}) => settings.hasAcceptedTerms ? HomePage(intentData: intentData) : const WelcomePage(); - Size? _getScreenSize() { - final physicalSize = window.physicalSize; - final ratio = window.devicePixelRatio; + Size? _getScreenSize(BuildContext context) { + final view = View.of(context); + final physicalSize = view.physicalSize; + final ratio = view.devicePixelRatio; return physicalSize > Size.zero && ratio > 0 ? physicalSize / ratio : null; } @@ -431,7 +422,7 @@ class _AvesAppState extends State with WidgetsBindingObserver { void _saveTopEntries() { if (!settings.initialized) return; - final screenSize = _screenSize ?? _getScreenSize(); + final screenSize = _screenSize; if (screenSize == null) return; var tileExtent = settings.getTileExtent(CollectionPage.routeName); @@ -525,10 +516,8 @@ class _AvesAppState extends State with WidgetsBindingObserver { case MaxBrightness.never: case MaxBrightness.viewerOnly: ScreenBrightness().resetScreenBrightness(); - break; case MaxBrightness.always: ScreenBrightness().setScreenBrightness(1); - break; } } @@ -586,7 +575,7 @@ class _AvesAppState extends State with WidgetsBindingObserver { : 'debug', 'has_mobile_services': mobileServices.isServiceAvailable, 'is_television': device.isTelevision, - 'locales': WidgetsBinding.instance.window.locales.join(', '), + 'locales': WidgetsBinding.instance.platformDispatcher.locales.join(', '), 'time_zone': '${now.timeZoneName} (${now.timeZoneOffset})', }); await reportService.log('Launch'); diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index f3db7ad22..63a181814 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -224,7 +224,7 @@ class _CollectionAppBarState extends State with SingleTickerPr } double get appBarContentHeight { - final textScaleFactor = context.read().textScaleFactor; + final textScaleFactor = MediaQuery.textScaleFactorOf(context); double height = kToolbarHeight * textScaleFactor; if (settings.useTvLayout) { height += CaptionedButton.getTelevisionButtonHeight(context); @@ -511,16 +511,13 @@ class _CollectionAppBarState extends State with SingleTickerPr queryEnabled: context.read().enabled, isMenuItem: true, ); - break; case EntrySetAction.toggleFavourite: child = FavouriteToggler( entries: _getExpandedSelectedItems(selection), isMenuItem: true, ); - break; default: child = MenuRow(text: action.getText(context), icon: action.getIcon()); - break; } return PopupMenuItem( key: _getActionKey(action), @@ -598,7 +595,7 @@ class _CollectionAppBarState extends State with SingleTickerPr void _onQueryFocusRequest() => _queryBarFocusNode.requestFocus(); void _updateStatusBarHeight() { - _statusBarHeight = context.read().padding.top; + _statusBarHeight = MediaQuery.paddingOf(context).top; _updateAppBarHeight(); } @@ -611,16 +608,12 @@ class _CollectionAppBarState extends State with SingleTickerPr // general case EntrySetAction.configureView: await _configureView(); - break; case EntrySetAction.select: context.read>().select(); - break; case EntrySetAction.selectAll: context.read>().addToSelection(collection.sortedEntries); - break; case EntrySetAction.selectNone: context.read>().clearSelection(); - break; // browsing case EntrySetAction.searchCollection: case EntrySetAction.toggleTitleSearch: @@ -650,7 +643,6 @@ class _CollectionAppBarState extends State with SingleTickerPr case EntrySetAction.editTags: case EntrySetAction.removeMetadata: _actionDelegate.onActionSelected(context, action); - break; } } diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index 23d4c148a..059bd0a63 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -46,7 +46,6 @@ import 'package:aves/widgets/navigation/nav_bar/nav_bar.dart'; import 'package:aves/widgets/viewer/entry_viewer_page.dart'; import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:intl/intl.dart'; @@ -374,6 +373,8 @@ class _CollectionScaler extends StatelessWidget { final tileSpacing = metrics.item1; final horizontalPadding = metrics.item2; final brightness = Theme.of(context).brightness; + final borderColor = DecoratedThumbnail.borderColor; + final borderWidth = DecoratedThumbnail.borderWidth(context); return GridScaleGestureDetector( scrollableKey: scrollableKey, tileLayout: tileLayout, @@ -385,9 +386,9 @@ class _CollectionScaler extends StatelessWidget { tileSize: tileSize, spacing: tileSpacing, horizontalPadding: horizontalPadding, - borderWidth: DecoratedThumbnail.borderWidth, + borderWidth: borderWidth, borderRadius: Radius.zero, - color: DecoratedThumbnail.borderColor, + color: borderColor, textDirection: Directionality.of(context), ), child: child, @@ -404,8 +405,8 @@ class _CollectionScaler extends StatelessWidget { decoration: BoxDecoration( color: ThumbnailImage.computeLoadingBackgroundColor(index * 10, brightness).withOpacity(.9), border: Border.all( - color: DecoratedThumbnail.borderColor, - width: DecoratedThumbnail.borderWidth, + color: borderColor, + width: borderWidth, ), ), ), @@ -489,7 +490,6 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge } }); } - break; } } @@ -573,7 +573,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge physics: collection.isEmpty ? const NeverScrollableScrollPhysics() : SloppyScrollPhysics( - gestureSettings: context.select((mq) => mq.gestureSettings), + gestureSettings: MediaQuery.gestureSettingsOf(context), parent: const AlwaysScrollableScrollPhysics(), ), cacheExtent: context.select((controller) => controller.effectiveExtentMax), @@ -677,7 +677,6 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge switch (collection.sectionFactor) { case EntryGroupFactor.album: addAlbums(collection, sectionLayouts, crumbs); - break; case EntryGroupFactor.month: case EntryGroupFactor.day: final firstKey = sectionLayouts.first.sectionKey; @@ -701,14 +700,11 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> with Widge }); } } - break; case EntryGroupFactor.none: break; } - break; case EntrySortFactor.name: addAlbums(collection, sectionLayouts, crumbs); - break; case EntrySortFactor.rating: case EntrySortFactor.size: break; diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index 908ad0861..2eb7a9bdc 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -173,79 +173,55 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware // browsing case EntrySetAction.searchCollection: _goToSearch(context); - break; case EntrySetAction.toggleTitleSearch: context.read().toggle(); - break; case EntrySetAction.addShortcut: _addShortcut(context); - break; // browsing or selecting case EntrySetAction.map: _goToMap(context); - break; case EntrySetAction.slideshow: _goToSlideshow(context); - break; case EntrySetAction.stats: _goToStats(context); - break; case EntrySetAction.rescan: _rescan(context); - break; // selecting case EntrySetAction.share: _share(context); - break; case EntrySetAction.delete: case EntrySetAction.emptyBin: _delete(context); - break; case EntrySetAction.restore: _move(context, moveType: MoveType.fromBin); - break; case EntrySetAction.copy: _move(context, moveType: MoveType.copy); - break; case EntrySetAction.move: _move(context, moveType: MoveType.move); - break; case EntrySetAction.rename: _rename(context); - break; case EntrySetAction.convert: _convert(context); - break; case EntrySetAction.toggleFavourite: _toggleFavourite(context); - break; case EntrySetAction.rotateCCW: _rotate(context, clockwise: false); - break; case EntrySetAction.rotateCW: _rotate(context, clockwise: true); - break; case EntrySetAction.flip: _flip(context); - break; case EntrySetAction.editDate: editDate(context); - break; case EntrySetAction.editLocation: _editLocation(context); - break; case EntrySetAction.editTitleDescription: _editTitleDescription(context); - break; case EntrySetAction.editRating: _editRating(context); - break; case EntrySetAction.editTags: _editTags(context); - break; case EntrySetAction.removeMetadata: _removeMetadata(context); - break; } } diff --git a/lib/widgets/collection/grid/headers/any.dart b/lib/widgets/collection/grid/headers/any.dart index c99c0c49d..556380fcc 100644 --- a/lib/widgets/collection/grid/headers/any.dart +++ b/lib/widgets/collection/grid/headers/any.dart @@ -57,7 +57,6 @@ class CollectionSectionHeader extends StatelessWidget { case EntryGroupFactor.none: break; } - break; case EntrySortFactor.name: return _buildAlbumHeader(context); case EntrySortFactor.rating: diff --git a/lib/widgets/collection/grid/list_details.dart b/lib/widgets/collection/grid/list_details.dart index 4d680b81d..1175dc0bd 100644 --- a/lib/widgets/collection/grid/list_details.dart +++ b/lib/widgets/collection/grid/list_details.dart @@ -78,7 +78,7 @@ class EntryListDetails extends StatelessWidget { Widget _buildDateRow(BuildContext context, TextStyle style) { final locale = context.l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry.bestDate; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; diff --git a/lib/widgets/collection/grid/tile.dart b/lib/widgets/collection/grid/tile.dart index da346a880..a4e132d0f 100644 --- a/lib/widgets/collection/grid/tile.dart +++ b/lib/widgets/collection/grid/tile.dart @@ -41,17 +41,13 @@ class InteractiveTile extends StatelessWidget { } else { OpenViewerNotification(entry).dispatch(context); } - break; case AppMode.pickSingleMediaExternal: IntentService.submitPickedItems([entry.uri]); - break; case AppMode.pickMultipleMediaExternal: final selection = context.read>(); selection.toggleSelection(entry); - break; case AppMode.pickMediaInternal: Navigator.maybeOf(context)?.pop(entry); - break; case AppMode.pickCollectionFiltersExternal: case AppMode.pickFilterInternal: case AppMode.screenSaver: diff --git a/lib/widgets/collection/query_bar.dart b/lib/widgets/collection/query_bar.dart index 005c7ec02..70a7a43e1 100644 --- a/lib/widgets/collection/query_bar.dart +++ b/lib/widgets/collection/query_bar.dart @@ -52,7 +52,7 @@ class _EntryQueryBarState extends State { @override Widget build(BuildContext context) { - final textScaleFactor = context.select((mq) => mq.textScaleFactor); + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return Container( height: EntryQueryBar.getPreferredHeight(textScaleFactor), alignment: Alignment.topCenter, diff --git a/lib/widgets/common/action_controls/quick_choosers/common/menu.dart b/lib/widgets/common/action_controls/quick_choosers/common/menu.dart index 5beae8e82..aff175503 100644 --- a/lib/widgets/common/action_controls/quick_choosers/common/menu.dart +++ b/lib/widgets/common/action_controls/quick_choosers/common/menu.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:ui'; import 'package:aves/theme/durations.dart'; import 'package:aves/widgets/common/action_controls/quick_choosers/common/quick_chooser.dart'; @@ -51,10 +50,15 @@ class _MenuQuickChooserState extends State> { @override void initState() { super.initState(); - _selectedRowRect.value = Rect.fromLTWH(0, window.physicalSize.height * (reversed ? 1 : -1), 0, 0); _registerWidget(widget); } + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _selectedRowRect.value = Rect.fromLTWH(0, MediaQuery.sizeOf(context).height * (reversed ? 1 : -1), 0, 0); + } + @override void didUpdateWidget(covariant MenuQuickChooser oldWidget) { super.didUpdateWidget(oldWidget); diff --git a/lib/widgets/common/action_controls/quick_choosers/common/route_layout.dart b/lib/widgets/common/action_controls/quick_choosers/common/route_layout.dart index 07a2b4624..835f69107 100644 --- a/lib/widgets/common/action_controls/quick_choosers/common/route_layout.dart +++ b/lib/widgets/common/action_controls/quick_choosers/common/route_layout.dart @@ -33,10 +33,8 @@ class QuickChooserRouteLayout extends SingleChildLayoutDelegate { switch (menuPosition) { case PopupMenuPosition.over: y = triggerRect.top - childSize.height; - break; case PopupMenuPosition.under: y = size.height - triggerRect.bottom; - break; } double x = (triggerRect.left + (size.width - triggerRect.right) - childSize.width) / 2; final wantedPosition = Offset(x, y); diff --git a/lib/widgets/common/action_mixins/entry_storage.dart b/lib/widgets/common/action_mixins/entry_storage.dart index 24ecffa80..c41508ae1 100644 --- a/lib/widgets/common/action_mixins/entry_storage.dart +++ b/lib/widgets/common/action_mixins/entry_storage.dart @@ -309,17 +309,14 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin { ..remove(destinationAlbum) ..insert(0, destinationAlbum); entriesByDestination[destinationAlbum] = entries; - break; case MoveType.toBin: entriesByDestination[AndroidFileUtils.trashDirPath] = entries; - break; case MoveType.fromBin: groupBy(entries, (e) => e.directory).forEach((originAlbum, dirEntries) { if (originAlbum != null) { entriesByDestination[originAlbum] = dirEntries.toSet(); } }); - break; } await doQuickMove( diff --git a/lib/widgets/common/action_mixins/overlay_snack_bar.dart b/lib/widgets/common/action_mixins/overlay_snack_bar.dart index 778654cca..1c212f712 100644 --- a/lib/widgets/common/action_mixins/overlay_snack_bar.dart +++ b/lib/widgets/common/action_mixins/overlay_snack_bar.dart @@ -8,66 +8,82 @@ import 'package:flutter/material.dart'; // This overlay entry is not below a `Scaffold` (which is expected by `SnackBar` // and `SnackBarAction`), and is not dismissed the same way. // This adaptation assumes the `SnackBarBehavior.floating` behavior and no animation. -class OverlaySnackBar extends StatelessWidget { +class OverlaySnackBar extends StatefulWidget { final Widget content; final Widget? action; final DismissDirection dismissDirection; final VoidCallback onDismiss; + final Clip clipBehavior; const OverlaySnackBar({ super.key, required this.content, - required this.action, - required this.dismissDirection, + this.action, + this.dismissDirection = DismissDirection.down, + this.clipBehavior = Clip.hardEdge, required this.onDismiss, }); + @override + State createState() => _OverlaySnackBarState(); +} + +class _OverlaySnackBarState extends State { @override Widget build(BuildContext context) { - final theme = Theme.of(context); - final colorScheme = theme.colorScheme; - final snackBarTheme = theme.snackBarTheme; - final isThemeDark = theme.brightness == Brightness.dark; - final buttonColor = isThemeDark ? colorScheme.primary : colorScheme.secondary; + assert(debugCheckHasMediaQuery(context)); + final ThemeData theme = Theme.of(context); + final ColorScheme colorScheme = theme.colorScheme; + final SnackBarThemeData snackBarTheme = theme.snackBarTheme; + final bool isThemeDark = theme.brightness == Brightness.dark; + final Color buttonColor = isThemeDark ? colorScheme.primary : colorScheme.secondary; + final SnackBarThemeData defaults = theme.useMaterial3 ? _SnackbarDefaultsM3(context) : _SnackbarDefaultsM2(context); - final brightness = isThemeDark ? Brightness.light : Brightness.dark; - final themeBackgroundColor = isThemeDark ? colorScheme.onSurface : Color.alphaBlend(colorScheme.onSurface.withOpacity(0.80), colorScheme.surface); - final inverseTheme = theme.copyWith( - colorScheme: ColorScheme( - primary: colorScheme.onPrimary, - secondary: buttonColor, - surface: colorScheme.onSurface, - background: themeBackgroundColor, - error: colorScheme.onError, - onPrimary: colorScheme.primary, - onSecondary: colorScheme.secondary, - onSurface: colorScheme.surface, - onBackground: colorScheme.background, - onError: colorScheme.error, - brightness: brightness, - ), - ); + // SnackBar uses a theme that is the opposite brightness from + // the surrounding theme. + final Brightness brightness = isThemeDark ? Brightness.light : Brightness.dark; - final contentTextStyle = snackBarTheme.contentTextStyle ?? ThemeData(brightness: brightness).textTheme.titleMedium; + // Invert the theme values for Material 2. Material 3 values are tokenized to pre-inverted values. + final ThemeData effectiveTheme = theme.useMaterial3 + ? theme + : theme.copyWith( + colorScheme: ColorScheme( + primary: colorScheme.onPrimary, + secondary: buttonColor, + surface: colorScheme.onSurface, + background: defaults.backgroundColor!, + error: colorScheme.onError, + onPrimary: colorScheme.primary, + onSecondary: colorScheme.secondary, + onSurface: colorScheme.surface, + onBackground: colorScheme.background, + onError: colorScheme.error, + brightness: brightness, + ), + ); + + final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? defaults.contentTextStyle; final horizontalPadding = FeedbackMixin.snackBarHorizontalPadding(snackBarTheme); - final padding = EdgeInsetsDirectional.only(start: horizontalPadding, end: action != null ? 0 : horizontalPadding); + final padding = EdgeInsetsDirectional.only(start: horizontalPadding, end: widget.action != null ? 0 : horizontalPadding); const singleLineVerticalPadding = 14.0; + final EdgeInsets margin = snackBarTheme.insetPadding ?? defaults.insetPadding!; + Widget snackBar = Padding( padding: padding, child: Row( children: [ Expanded( child: Container( - padding: action != null ? null : const EdgeInsets.symmetric(vertical: singleLineVerticalPadding), + padding: widget.action != null ? null : const EdgeInsets.symmetric(vertical: singleLineVerticalPadding), child: DefaultTextStyle( style: contentTextStyle!, - child: content, + child: widget.content, ), ), ), - if (action != null) + if (widget.action != null) TextButtonTheme( data: TextButtonThemeData( style: TextButton.styleFrom( @@ -75,36 +91,28 @@ class OverlaySnackBar extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: horizontalPadding), ), ), - child: action!, + child: widget.action!, ), ], ), ); - final elevation = snackBarTheme.elevation ?? 6.0; - final backgroundColor = snackBarTheme.backgroundColor ?? inverseTheme.colorScheme.background; - final shape = snackBarTheme.shape ?? const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))); + final double elevation = snackBarTheme.elevation ?? defaults.elevation!; + final Color backgroundColor = snackBarTheme.backgroundColor ?? defaults.backgroundColor!; + final ShapeBorder? shape = snackBarTheme.shape ?? defaults.shape; snackBar = Material( shape: shape, elevation: elevation, color: backgroundColor, child: Theme( - data: inverseTheme, + data: effectiveTheme, child: snackBar, ), ); - const topMargin = 5.0; - const bottomMargin = 10.0; - const horizontalMargin = 15.0; snackBar = Padding( - padding: const EdgeInsets.fromLTRB( - horizontalMargin, - topMargin, - horizontalMargin, - bottomMargin, - ), + padding: margin, child: snackBar, ); @@ -117,16 +125,138 @@ class OverlaySnackBar extends StatelessWidget { snackBar = Semantics( container: true, liveRegion: true, - onDismiss: onDismiss, + onDismiss: widget.onDismiss, child: Dismissible( key: const Key('dismissible'), - direction: dismissDirection, + direction: widget.dismissDirection, resizeDuration: null, - onDismissed: (direction) => onDismiss(), + onDismissed: (direction) => widget.onDismiss(), child: snackBar, ), ); - return snackBar; + final Widget snackBarTransition = snackBar; + + return Hero( + tag: '', + transitionOnUserGestures: true, + child: ClipRect( + clipBehavior: widget.clipBehavior, + child: snackBarTransition, + ), + ); } } + +// Hand coded defaults based on Material Design 2. +class _SnackbarDefaultsM2 extends SnackBarThemeData { + _SnackbarDefaultsM2(BuildContext context) + : _theme = Theme.of(context), + _colors = Theme.of(context).colorScheme, + super(elevation: 6.0); + + late final ThemeData _theme; + late final ColorScheme _colors; + + @override + Color get backgroundColor => _theme.brightness == Brightness.light ? Color.alphaBlend(_colors.onSurface.withOpacity(0.80), _colors.surface) : _colors.onSurface; + + @override + TextStyle? get contentTextStyle => ThemeData(brightness: _theme.brightness == Brightness.light ? Brightness.dark : Brightness.light).textTheme.titleMedium; + + @override + SnackBarBehavior get behavior => SnackBarBehavior.fixed; + + @override + Color get actionTextColor => _colors.secondary; + + @override + Color get disabledActionTextColor => _colors.onSurface.withOpacity(_theme.brightness == Brightness.light ? 0.38 : 0.3); + + @override + ShapeBorder get shape => const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(4.0), + ), + ); + + @override + EdgeInsets get insetPadding => const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 10.0); + + @override + bool get showCloseIcon => false; + + @override + Color get closeIconColor => _colors.onSurface; + + @override + double get actionOverflowThreshold => 0.25; +} + +// BEGIN GENERATED TOKEN PROPERTIES - Snackbar + +// Do not edit by hand. The code between the "BEGIN GENERATED" and +// "END GENERATED" comments are generated from data in the Material +// Design token database by the script: +// dev/tools/gen_defaults/bin/gen_defaults.dart. + +// Token database version: v0_162 + +class _SnackbarDefaultsM3 extends SnackBarThemeData { + _SnackbarDefaultsM3(this.context); + + final BuildContext context; + late final ThemeData _theme = Theme.of(context); + late final ColorScheme _colors = _theme.colorScheme; + + @override + Color get backgroundColor => _colors.inverseSurface; + + @override + Color get actionTextColor => MaterialStateColor.resolveWith((states) { + if (states.contains(MaterialState.disabled)) { + return _colors.inversePrimary; + } + if (states.contains(MaterialState.pressed)) { + return _colors.inversePrimary; + } + if (states.contains(MaterialState.hovered)) { + return _colors.inversePrimary; + } + if (states.contains(MaterialState.focused)) { + return _colors.inversePrimary; + } + return _colors.inversePrimary; + }); + + @override + Color get disabledActionTextColor => _colors.inversePrimary; + + @override + TextStyle get contentTextStyle => Theme.of(context).textTheme.bodyMedium!.copyWith( + color: _colors.onInverseSurface, + ); + + @override + double get elevation => 6.0; + + @override + ShapeBorder get shape => const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))); + + @override + SnackBarBehavior get behavior => SnackBarBehavior.fixed; + + @override + EdgeInsets get insetPadding => const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 10.0); + + @override + bool get showCloseIcon => false; + + @override + Color? get closeIconColor => _colors.onInverseSurface; + + @override + double get actionOverflowThreshold => 0.25; +} + +// END GENERATED TOKEN PROPERTIES - Snackbar diff --git a/lib/widgets/common/action_mixins/size_aware.dart b/lib/widgets/common/action_mixins/size_aware.dart index f8998d308..10723ce6f 100644 --- a/lib/widgets/common/action_mixins/size_aware.dart +++ b/lib/widgets/common/action_mixins/size_aware.dart @@ -35,7 +35,6 @@ mixin SizeAwareMixin { case MoveType.copy: case MoveType.export: needed = selection.fold(0, sumSize); - break; case MoveType.move: case MoveType.toBin: case MoveType.fromBin: @@ -46,7 +45,6 @@ mixin SizeAwareMixin { // and we need at least as much space as the largest entry because individual entries are copied then deleted final largestSingle = selection.fold(0, (largest, entry) => max(largest, entry.sizeBytes ?? 0)); needed = max(fromOtherVolumes, largestSingle); - break; } final hasEnoughSpace = needed < free; diff --git a/lib/widgets/common/action_mixins/vault_aware.dart b/lib/widgets/common/action_mixins/vault_aware.dart index 137591878..d900a3382 100644 --- a/lib/widgets/common/action_mixins/vault_aware.dart +++ b/lib/widgets/common/action_mixins/vault_aware.dart @@ -36,7 +36,6 @@ mixin VaultAwareMixin on FeedbackMixin { await reportService.recordError(e, stack); } } - break; case VaultLockType.pattern: final pattern = await showDialog( context: context, @@ -46,7 +45,6 @@ mixin VaultAwareMixin on FeedbackMixin { if (pattern != null) { confirmed = pattern == await securityService.readValue(details.passKey); } - break; case VaultLockType.pin: final pin = await showDialog( context: context, @@ -56,7 +54,6 @@ mixin VaultAwareMixin on FeedbackMixin { if (pin != null) { confirmed = pin == await securityService.readValue(details.passKey); } - break; case VaultLockType.password: final password = await showDialog( context: context, @@ -66,7 +63,6 @@ mixin VaultAwareMixin on FeedbackMixin { if (password != null) { confirmed = password == await securityService.readValue(details.passKey); } - break; } if (confirmed == null || !confirmed) return false; @@ -120,7 +116,6 @@ mixin VaultAwareMixin on FeedbackMixin { await reportService.recordError(e, stack); } } - break; case VaultLockType.pattern: final pattern = await showDialog( context: context, @@ -130,7 +125,6 @@ mixin VaultAwareMixin on FeedbackMixin { if (pattern != null) { return await securityService.writeValue(details.passKey, pattern); } - break; case VaultLockType.pin: final pin = await showDialog( context: context, @@ -140,7 +134,6 @@ mixin VaultAwareMixin on FeedbackMixin { if (pin != null) { return await securityService.writeValue(details.passKey, pin); } - break; case VaultLockType.password: final password = await showDialog( context: context, @@ -150,7 +143,6 @@ mixin VaultAwareMixin on FeedbackMixin { if (password != null) { return await securityService.writeValue(details.passKey, password); } - break; } return false; } diff --git a/lib/widgets/common/app_bar/app_bar_title.dart b/lib/widgets/common/app_bar/app_bar_title.dart index 19283c9d9..a0274db45 100644 --- a/lib/widgets/common/app_bar/app_bar_title.dart +++ b/lib/widgets/common/app_bar/app_bar_title.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class InteractiveAppBarTitle extends StatelessWidget { final GestureTapCallback? onTap; @@ -13,6 +12,7 @@ class InteractiveAppBarTitle extends StatelessWidget { @override Widget build(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return GestureDetector( onTap: onTap, // use a `Container` with a dummy color to make it expand @@ -20,7 +20,7 @@ class InteractiveAppBarTitle extends StatelessWidget { child: Container( alignment: AlignmentDirectional.centerStart, color: Colors.transparent, - height: kToolbarHeight * context.select((mq) => mq.textScaleFactor), + height: kToolbarHeight * textScaleFactor, child: child, ), ); diff --git a/lib/widgets/common/basic/font_size_icon_theme.dart b/lib/widgets/common/basic/font_size_icon_theme.dart index ea43d4449..7b143fcf8 100644 --- a/lib/widgets/common/basic/font_size_icon_theme.dart +++ b/lib/widgets/common/basic/font_size_icon_theme.dart @@ -11,10 +11,11 @@ class FontSizeIconTheme extends StatelessWidget { @override Widget build(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); final iconTheme = IconTheme.of(context); return IconTheme( data: iconTheme.copyWith( - size: iconTheme.size! * MediaQuery.textScaleFactorOf(context), + size: iconTheme.size! * textScaleFactor, ), child: child, ); diff --git a/lib/widgets/common/basic/insets.dart b/lib/widgets/common/basic/insets.dart index fa1a73d46..106756878 100644 --- a/lib/widgets/common/basic/insets.dart +++ b/lib/widgets/common/basic/insets.dart @@ -22,7 +22,7 @@ class BottomGestureAreaProtector extends StatelessWidget { left: 0, right: 0, bottom: 0, - height: context.select((mq) => mq.systemGestureInsets.bottom), + height: MediaQuery.systemGestureInsetsOf(context).bottom, child: GestureDetector( // absorb vertical gestures only onVerticalDragDown: (details) {}, @@ -42,7 +42,7 @@ class TopGestureAreaProtector extends StatelessWidget { left: 0, top: 0, right: 0, - height: context.select((mq) => mq.systemGestureInsets.top), + height: MediaQuery.systemGestureInsetsOf(context).top, child: GestureDetector( // absorb vertical gestures only onVerticalDragDown: (details) {}, @@ -64,7 +64,7 @@ class SideGestureAreaProtector extends StatelessWidget { textDirection: TextDirection.ltr, children: [ SizedBox( - width: context.select((mq) => mq.systemGestureInsets.left), + width: MediaQuery.systemGestureInsetsOf(context).left, child: GestureDetector( // absorb horizontal gestures only onHorizontalDragDown: (details) {}, @@ -73,7 +73,7 @@ class SideGestureAreaProtector extends StatelessWidget { ), const Spacer(), SizedBox( - width: context.select((mq) => mq.systemGestureInsets.right), + width: MediaQuery.systemGestureInsetsOf(context).right, child: GestureDetector( // absorb horizontal gestures only onHorizontalDragDown: (details) {}, diff --git a/lib/widgets/common/basic/list_tiles/reselectable_radio.dart b/lib/widgets/common/basic/list_tiles/reselectable_radio.dart index b3d456627..f6a33aacf 100644 --- a/lib/widgets/common/basic/list_tiles/reselectable_radio.dart +++ b/lib/widgets/common/basic/list_tiles/reselectable_radio.dart @@ -54,11 +54,9 @@ class ReselectableRadioListTile extends StatelessWidget { case ListTileControlAffinity.platform: leading = control; trailing = secondary; - break; case ListTileControlAffinity.trailing: leading = secondary; trailing = control; - break; } return MergeSemantics( child: ListTileTheme.merge( diff --git a/lib/widgets/common/basic/markdown_container.dart b/lib/widgets/common/basic/markdown_container.dart index 14cd63158..62c054210 100644 --- a/lib/widgets/common/basic/markdown_container.dart +++ b/lib/widgets/common/basic/markdown_container.dart @@ -54,7 +54,7 @@ class MarkdownContainer extends StatelessWidget { margin: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: Theme.of(context).canvasColor, - border: Border.all(color: Theme.of(context).dividerColor, width: AvesBorder.curvedBorderWidth), + border: Border.all(color: Theme.of(context).dividerColor, width: AvesBorder.curvedBorderWidth(context)), borderRadius: const BorderRadius.all(Radius.circular(16)), ), constraints: BoxConstraints(maxWidth: useTvLayout ? double.infinity : mobileMaxWidth), diff --git a/lib/widgets/common/basic/scaffold.dart b/lib/widgets/common/basic/scaffold.dart index e70c0fdda..81058a618 100644 --- a/lib/widgets/common/basic/scaffold.dart +++ b/lib/widgets/common/basic/scaffold.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class AvesScaffold extends StatelessWidget { final PreferredSizeWidget? appBar; @@ -26,7 +25,7 @@ class AvesScaffold extends StatelessWidget { @override Widget build(BuildContext context) { // prevent conflict between drawer drag gesture and Android navigation gestures - final drawerEnableOpenDragGesture = context.select((mq) => mq.systemGestureInsets.horizontal == 0); + final drawerEnableOpenDragGesture = MediaQuery.systemGestureInsetsOf(context).horizontal == 0; return Scaffold( appBar: appBar, diff --git a/lib/widgets/common/basic/text/outlined.dart b/lib/widgets/common/basic/text/outlined.dart index 22630b843..3ccf14529 100644 --- a/lib/widgets/common/basic/text/outlined.dart +++ b/lib/widgets/common/basic/text/outlined.dart @@ -31,44 +31,51 @@ class OutlinedText extends StatelessWidget { @override Widget build(BuildContext context) { // TODO TLAD [subtitles] fix background area for mixed alphabetic-ideographic text - // as of Flutter v2.2.2, the area computed for `backgroundColor` has inconsistent height - // in case of mixed alphabetic-ideographic text. The painted boxes depends on the script. + // as of Flutter v3.10.0, the area computed for `backgroundColor` has inconsistent height + // in case of mixed alphabetic-ideographic text. The painted boxes depend on the script. // Possible workarounds would be to use metrics from: // - `TextPainter.getBoxesForSelection` // - `Paragraph.getBoxesForRange` // and paint the background at the bottom of the `Stack` + final hasOutline = outlineWidth > 0; + + Widget? outline; + if (hasOutline) { + outline = Text.rich( + TextSpan( + children: textSpans.map(_toStrokeSpan).toList(), + ), + textAlign: textAlign, + softWrap: softWrap, + overflow: overflow, + maxLines: maxLines, + ); + if (outlineBlurSigma > 0) { + outline = ImageFiltered( + imageFilter: ImageFilter.blur( + sigmaX: outlineBlurSigma, + sigmaY: outlineBlurSigma, + ), + child: outline, + ); + } + } + + final fill = Text.rich( + TextSpan( + children: hasOutline ? textSpans.map(_toFillSpan).toList() : textSpans, + ), + textAlign: textAlign, + softWrap: softWrap, + overflow: overflow, + maxLines: maxLines, + ); + return Stack( children: [ - if (hasOutline) - ImageFiltered( - imageFilter: outlineBlurSigma > 0 - ? ImageFilter.blur( - sigmaX: outlineBlurSigma, - sigmaY: outlineBlurSigma, - ) - : ImageFilter.matrix( - Matrix4.identity().storage, - ), - child: Text.rich( - TextSpan( - children: textSpans.map(_toStrokeSpan).toList(), - ), - textAlign: textAlign, - softWrap: softWrap, - overflow: overflow, - maxLines: maxLines, - ), - ), - Text.rich( - TextSpan( - children: hasOutline ? textSpans.map(_toFillSpan).toList() : textSpans, - ), - textAlign: textAlign, - softWrap: softWrap, - overflow: overflow, - maxLines: maxLines, - ), + if (outline != null) outline, + fill, ], ); } @@ -89,6 +96,7 @@ class OutlinedText extends StatelessWidget { children: span.children, style: (span.style ?? const TextStyle()).copyWith( backgroundColor: Colors.transparent, + shadows: [], ), ); } diff --git a/lib/widgets/common/basic/wheel.dart b/lib/widgets/common/basic/wheel.dart index b6f190380..1682eb5cb 100644 --- a/lib/widgets/common/basic/wheel.dart +++ b/lib/widgets/common/basic/wheel.dart @@ -46,10 +46,11 @@ class _WheelSelectorState extends State> { @override Widget build(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); const background = Colors.transparent; final foreground = DefaultTextStyle.of(context).style.color!; final transitionDuration = context.select((v) => v.formTransition); - final itemSize = Size.square(40 * context.select((mq) => mq.textScaleFactor)); + final itemSize = Size.square(40 * textScaleFactor); return FocusableActionDetector( shortcuts: const { @@ -138,10 +139,8 @@ class _WheelSelectorState extends State> { switch (intent.type) { case _ValueAdjustmentType.up: delta = -1; - break; case _ValueAdjustmentType.down: delta = 1; - break; } final targetItem = _controller.selectedItem + delta; final duration = context.read().formTransition; diff --git a/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart b/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart index 9149e0b63..ce2b4c682 100644 --- a/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart +++ b/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart @@ -26,20 +26,47 @@ enum _ScaleState { } class _PointerPanZoomData { - _PointerPanZoomData({required this.focalPoint, required this.scale, required this.rotation}); + _PointerPanZoomData.fromStartEvent(this.parent, PointerPanZoomStartEvent event) + : _position = event.position, + _pan = Offset.zero, + _scale = 1, + _rotation = 0; - Offset focalPoint; - double scale; - double rotation; + _PointerPanZoomData.fromUpdateEvent(this.parent, PointerPanZoomUpdateEvent event) + : _position = event.position, + _pan = event.pan, + _scale = event.scale, + _rotation = event.rotation; + + final EagerScaleGestureRecognizer parent; + final Offset _position; + final Offset _pan; + final double _scale; + final double _rotation; + + Offset get focalPoint { + if (parent.trackpadScrollCausesScale) { + return _position; + } + return _position + _pan; + } + + double get scale { + if (parent.trackpadScrollCausesScale) { + return _scale * math.exp((_pan.dx * parent.trackpadScrollToScaleFactor.dx) + (_pan.dy * parent.trackpadScrollToScaleFactor.dy)); + } + return _scale; + } + + double get rotation => _rotation; @override - String toString() => '_PointerPanZoomData(focalPoint: $focalPoint, scale: $scale, angle: $rotation)'; + String toString() => '_PointerPanZoomData(parent: $parent, _position: $_position, _pan: $_pan, _scale: $_scale, _rotation: $_rotation)'; } //////////////////////////////////////////////////////////////////////////////// bool _isFlingGesture(Velocity velocity) { - assert(velocity != null); final double speedSquared = velocity.pixelsPerSecond.distanceSquared; return speedSquared > kMinFlingVelocity * kMinFlingVelocity; } @@ -57,9 +84,7 @@ class _LineBetweenPointers { this.pointerStartId = 0, this.pointerEndLocation = Offset.zero, this.pointerEndId = 1, - }) : assert(pointerStartLocation != null && pointerEndLocation != null), - assert(pointerStartId != null && pointerEndId != null), - assert(pointerStartId != pointerEndId); + }) : assert(pointerStartId != pointerEndId); // The location and the id of the pointer that marks the start of the line. final Offset pointerStartLocation; @@ -74,23 +99,22 @@ class _LineBetweenPointers { /// /// [ScaleGestureRecognizer] tracks the pointers in contact with the screen and /// calculates their focal point, indicated scale, and rotation. When a focal -/// pointer is established, the recognizer calls [onStart]. As the focal point, -/// scale, rotation change, the recognizer calls [onUpdate]. When the pointers -/// are no longer in contact with the screen, the recognizer calls [onEnd]. +/// point is established, the recognizer calls [onStart]. As the focal point, +/// scale, and rotation change, the recognizer calls [onUpdate]. When the +/// pointers are no longer in contact with the screen, the recognizer calls +/// [onEnd]. class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { /// Create a gesture recognizer for interactions intended for scaling content. /// /// {@macro flutter.gestures.GestureRecognizer.supportedDevices} EagerScaleGestureRecognizer({ super.debugOwner, - @Deprecated( - 'Migrate to supportedDevices. ' - 'This feature was deprecated after v2.3.0-1.0.pre.', - ) - super.kind, super.supportedDevices, + super.allowedButtonsFilter, this.dragStartBehavior = DragStartBehavior.down, - }) : assert(dragStartBehavior != null); + this.trackpadScrollCausesScale = false, + this.trackpadScrollToScaleFactor = kDefaultTrackpadScrollToScaleFactor, + }); /// Determines what point is used as the starting point in all calculations /// involving this gesture. @@ -137,6 +161,26 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { Matrix4? _lastTransform; + /// {@template flutter.gestures.scale.trackpadScrollCausesScale} + /// Whether scrolling up/down on a trackpad should cause scaling instead of + /// panning. + /// + /// Defaults to false. + /// {@endtemplate} + bool trackpadScrollCausesScale; + + /// {@template flutter.gestures.scale.trackpadScrollToScaleFactor} + /// A factor to control the direction and magnitude of scale when converting + /// trackpad scrolling. + /// + /// Incoming trackpad pan offsets will be divided by this factor to get scale + /// values. Increasing this offset will reduce the amount of scaling caused by + /// a fixed amount of trackpad scrolling. + /// + /// Defaults to [kDefaultTrackpadScrollToScaleFactor]. + /// {@endtemplate} + Offset trackpadScrollToScaleFactor; + late Offset _initialFocalPoint; Offset? _currentFocalPoint; late double _initialSpan; @@ -151,6 +195,7 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { final Map _pointerLocations = {}; final List _pointerQueue = []; // A queue to sort pointers in order of entrance final Map _velocityTrackers = {}; + VelocityTracker? _scaleVelocityTracker; late Offset _delta; final Map _pointerPanZooms = {}; double _initialPanZoomScaleFactor = 1; @@ -271,15 +316,16 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { _lastTransform = event.transform; } else if (event is PointerPanZoomStartEvent) { assert(_pointerPanZooms[event.pointer] == null); - _pointerPanZooms[event.pointer] = _PointerPanZoomData(focalPoint: event.position, scale: 1, rotation: 0); + _pointerPanZooms[event.pointer] = _PointerPanZoomData.fromStartEvent(this, event); didChangeConfiguration = true; shouldStartIfAccepted = true; + _lastTransform = event.transform; } else if (event is PointerPanZoomUpdateEvent) { assert(_pointerPanZooms[event.pointer] != null); - if (!event.synthesized) { + if (!event.synthesized && !trackpadScrollCausesScale) { _velocityTrackers[event.pointer]!.addPosition(event.timeStamp, event.pan); } - _pointerPanZooms[event.pointer] = _PointerPanZoomData(focalPoint: event.position + event.pan, scale: event.scale, rotation: event.rotation); + _pointerPanZooms[event.pointer] = _PointerPanZoomData.fromUpdateEvent(this, event); _lastTransform = event.transform; shouldStartIfAccepted = true; } else if (event is PointerPanZoomEndEvent) { @@ -292,7 +338,7 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { _update(); if (!didChangeConfiguration || _reconfigure(event.pointer)) { - _advanceStateMachine(shouldStartIfAccepted, event.kind); + _advanceStateMachine(shouldStartIfAccepted, event); } stopTrackingIfPointerNoLongerDown(event); } @@ -403,18 +449,20 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity) { velocity = Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity); } - invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity, pointerCount: _pointerCount))); + invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity, scaleVelocity: _scaleVelocityTracker?.getVelocity().pixelsPerSecond.dx ?? -1, pointerCount: _pointerCount))); } else { - invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(pointerCount: _pointerCount))); + invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(scaleVelocity: _scaleVelocityTracker?.getVelocity().pixelsPerSecond.dx ?? -1, pointerCount: _pointerCount))); } } _state = _ScaleState.accepted; + _scaleVelocityTracker = VelocityTracker.withKind(PointerDeviceKind.touch); // arbitrary PointerDeviceKind return false; } + _scaleVelocityTracker = VelocityTracker.withKind(PointerDeviceKind.touch); // arbitrary PointerDeviceKind return true; } - void _advanceStateMachine(bool shouldStartIfAccepted, PointerDeviceKind pointerDeviceKind) { + void _advanceStateMachine(bool shouldStartIfAccepted, PointerEvent event) { if (_state == _ScaleState.ready) { _state = _ScaleState.possible; } @@ -428,7 +476,7 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { if (_state == _ScaleState.possible) { final double spanDelta = (_currentSpan - _initialSpan).abs(); final double focalPointDelta = (_currentFocalPoint! - _initialFocalPoint).distance; - if (spanDelta > computeScaleSlop(pointerDeviceKind) || focalPointDelta > computePanSlop(pointerDeviceKind, gestureSettings) || math.max(_scaleFactor / _pointerScaleFactor, _pointerScaleFactor / _scaleFactor) > 1.05) { + if (spanDelta > computeScaleSlop(event.kind) || focalPointDelta > computePanSlop(event.kind, gestureSettings) || math.max(_scaleFactor / _pointerScaleFactor, _pointerScaleFactor / _scaleFactor) > 1.05) { resolve(GestureDisposition.accepted); } } else if (_state.index >= _ScaleState.accepted.index) { @@ -440,19 +488,22 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { _dispatchOnStartCallbackIfNeeded(); } - if (_state == _ScaleState.started && onUpdate != null) { - invokeCallback('onUpdate', () { - onUpdate!(ScaleUpdateDetails( - scale: _scaleFactor, - horizontalScale: _horizontalScaleFactor, - verticalScale: _verticalScaleFactor, - focalPoint: _currentFocalPoint!, - localFocalPoint: _localFocalPoint, - rotation: _computeRotationFactor(), - pointerCount: _pointerCount, - focalPointDelta: _delta, - )); - }); + if (_state == _ScaleState.started) { + _scaleVelocityTracker?.addPosition(event.timeStamp, Offset(_scaleFactor, 0)); + if (onUpdate != null) { + invokeCallback('onUpdate', () { + onUpdate!(ScaleUpdateDetails( + scale: _scaleFactor, + horizontalScale: _horizontalScaleFactor, + verticalScale: _verticalScaleFactor, + focalPoint: _currentFocalPoint!, + localFocalPoint: _localFocalPoint, + rotation: _computeRotationFactor(), + pointerCount: _pointerCount, + focalPointDelta: _delta, + )); + }); + } } } @@ -504,15 +555,12 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { switch (_state) { case _ScaleState.possible: resolve(GestureDisposition.rejected); - break; case _ScaleState.ready: assert(false); // We should have not seen a pointer yet - break; case _ScaleState.accepted: break; case _ScaleState.started: assert(false); // We should be in the accepted state when user is done - break; } _state = _ScaleState.ready; } diff --git a/lib/widgets/common/behaviour/intents.dart b/lib/widgets/common/behaviour/intents.dart index d58dc2e8f..98dcfd723 100644 --- a/lib/widgets/common/behaviour/intents.dart +++ b/lib/widgets/common/behaviour/intents.dart @@ -14,11 +14,9 @@ class ScrollControllerAction extends CallbackAction { case AxisDirection.up: case AxisDirection.left: factor = -1; - break; case AxisDirection.down: case AxisDirection.right: factor = 1; - break; } scrollController.animateTo( scrollController.offset + factor * 150, diff --git a/lib/widgets/common/behaviour/known_extent_scroll_physics.dart b/lib/widgets/common/behaviour/known_extent_scroll_physics.dart index 0dce20b84..57bb1b809 100644 --- a/lib/widgets/common/behaviour/known_extent_scroll_physics.dart +++ b/lib/widgets/common/behaviour/known_extent_scroll_physics.dart @@ -53,7 +53,7 @@ class KnownExtentScrollPhysics extends ScrollPhysics { // Scenario 3: // If there's no velocity and we're already at where we intend to land, // do nothing. - if (velocity.abs() < tolerance.velocity && (settlingPixels - metrics.pixels).abs() < tolerance.distance) { + if (velocity.abs() < toleranceFor(position).velocity && (settlingPixels - metrics.pixels).abs() < toleranceFor(position).distance) { return null; } @@ -66,7 +66,7 @@ class KnownExtentScrollPhysics extends ScrollPhysics { metrics.pixels, settlingPixels, velocity, - tolerance: tolerance, + tolerance: toleranceFor(position), ); } @@ -77,7 +77,7 @@ class KnownExtentScrollPhysics extends ScrollPhysics { metrics.pixels, settlingPixels, velocity, - tolerance.velocity * velocity.sign, + toleranceFor(position).velocity * velocity.sign, ); } } diff --git a/lib/widgets/common/behaviour/springy_scroll_physics.dart b/lib/widgets/common/behaviour/springy_scroll_physics.dart index 1b39c0540..51b887cde 100644 --- a/lib/widgets/common/behaviour/springy_scroll_physics.dart +++ b/lib/widgets/common/behaviour/springy_scroll_physics.dart @@ -16,5 +16,4 @@ class SpringyScrollPhysics extends ScrollPhysics { parent: buildParent(ancestor), ); } - } diff --git a/lib/widgets/common/fx/borders.dart b/lib/widgets/common/fx/borders.dart index b9dc02a0d..cc474869a 100644 --- a/lib/widgets/common/fx/borders.dart +++ b/lib/widgets/common/fx/borders.dart @@ -1,26 +1,22 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; class AvesBorder { static Color _borderColor(BuildContext context) => Theme.of(context).brightness == Brightness.dark ? Colors.white30 : Colors.black26; - // directly uses `devicePixelRatio` as it never changes, to avoid visiting ancestors via `MediaQuery` - // 1 device pixel for straight lines is fine - static double get straightBorderWidth => 1 / window.devicePixelRatio; + static double straightBorderWidth(BuildContext context) => 1 / View.of(context).devicePixelRatio; // 1 device pixel for curves is too thin - static double get curvedBorderWidth => window.devicePixelRatio > 2 ? 0.5 : 1.0; + static double curvedBorderWidth(BuildContext context) => View.of(context).devicePixelRatio > 2 ? 0.5 : 1.0; static BorderSide straightSide(BuildContext context, {double? width}) => BorderSide( color: _borderColor(context), - width: width ?? straightBorderWidth, + width: width ?? straightBorderWidth(context), ); static BorderSide curvedSide(BuildContext context, {double? width}) => BorderSide( color: _borderColor(context), - width: width ?? curvedBorderWidth, + width: width ?? curvedBorderWidth(context), ); static Border border(BuildContext context, {double? width}) => Border.fromBorderSide(curvedSide(context, width: width)); diff --git a/lib/widgets/common/fx/transition_image.dart b/lib/widgets/common/fx/transition_image.dart index 4ee1b8390..f9aa1284c 100644 --- a/lib/widgets/common/fx/transition_image.dart +++ b/lib/widgets/common/fx/transition_image.dart @@ -2,6 +2,8 @@ import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/semantics.dart'; // adapted from Flutter `_ImageState` in `/widgets/image.dart` // and `DecorationImagePainter` in `/painting/decoration_image.dart` @@ -13,6 +15,11 @@ class TransitionImage extends StatefulWidget { final ImageProvider image; final ValueListenable animation; final BoxFit thumbnailFit, viewerFit; + final ImageFrameBuilder? frameBuilder; + final ImageLoadingBuilder? loadingBuilder; + final ImageErrorWidgetBuilder? errorBuilder; + final String? semanticLabel; + final bool excludeFromSemantics; final double? width, height; final bool gaplessPlayback = false; final Color? background; @@ -23,6 +30,11 @@ class TransitionImage extends StatefulWidget { required this.animation, required this.thumbnailFit, required this.viewerFit, + this.frameBuilder, + this.loadingBuilder, + this.errorBuilder, + this.semanticLabel, + this.excludeFromSemantics = false, this.width, this.height, this.background, @@ -32,16 +44,33 @@ class TransitionImage extends StatefulWidget { State createState() => _TransitionImageState(); } -class _TransitionImageState extends State { +class _TransitionImageState extends State with WidgetsBindingObserver { ImageStream? _imageStream; ImageInfo? _imageInfo; + ImageChunkEvent? _loadingProgress; bool _isListeningToStream = false; int? _frameNumber; + bool _wasSynchronouslyLoaded = false; + late DisposableBuildContext> _scrollAwareContext; + Object? _lastException; + StackTrace? _lastStack; + ImageStreamCompleterHandle? _completerHandle; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + _scrollAwareContext = DisposableBuildContext>(this); + } @override void dispose() { assert(_imageStream != null); + WidgetsBinding.instance.removeObserver(this); _stopListeningToStream(); + _completerHandle?.dispose(); + _scrollAwareContext.dispose(); + _replaceImage(info: null); super.dispose(); } @@ -52,21 +81,23 @@ class _TransitionImageState extends State { if (TickerMode.of(context)) { _listenToStream(); } else { - _stopListeningToStream(); + _stopListeningToStream(keepStreamAlive: true); } super.didChangeDependencies(); } @override - void didUpdateWidget(covariant TransitionImage oldWidget) { + void didUpdateWidget(TransitionImage oldWidget) { super.didUpdateWidget(oldWidget); - if (_isListeningToStream) { + if (_isListeningToStream && (widget.loadingBuilder == null) != (oldWidget.loadingBuilder == null)) { final ImageStreamListener oldListener = _getListener(); _imageStream!.addListener(_getListener(recreateListener: true)); _imageStream!.removeListener(oldListener); } - if (widget.image != oldWidget.image) _resolveImage(); + if (widget.image != oldWidget.image) { + _resolveImage(); + } } @override @@ -76,8 +107,11 @@ class _TransitionImageState extends State { } void _resolveImage() { - final provider = widget.image; - final newStream = provider.resolve(createLocalImageConfiguration( + final ScrollAwareImageProvider provider = ScrollAwareImageProvider( + context: _scrollAwareContext, + imageProvider: widget.image, + ); + final ImageStream newStream = provider.resolve(createLocalImageConfiguration( context, size: widget.width != null && widget.height != null ? Size(widget.width!, widget.height!) : null, )); @@ -88,8 +122,26 @@ class _TransitionImageState extends State { ImageStreamListener _getListener({bool recreateListener = false}) { if (_imageStreamListener == null || recreateListener) { + _lastException = null; + _lastStack = null; _imageStreamListener = ImageStreamListener( _handleImageFrame, + onChunk: widget.loadingBuilder == null ? null : _handleImageChunk, + onError: widget.errorBuilder != null || kDebugMode + ? (error, stackTrace) { + setState(() { + _lastException = error; + _lastStack = stackTrace; + }); + assert(() { + if (widget.errorBuilder == null) { + // ignore: only_throw_errors, since we're just proxying the error. + throw error; // Ensures the error message is printed to the console. + } + return true; + }()); + } + : null, ); } return _imageStreamListener!; @@ -98,15 +150,32 @@ class _TransitionImageState extends State { void _handleImageFrame(ImageInfo imageInfo, bool synchronousCall) { setState(() { _replaceImage(info: imageInfo); + _loadingProgress = null; + _lastException = null; + _lastStack = null; _frameNumber = _frameNumber == null ? 0 : _frameNumber! + 1; + _wasSynchronouslyLoaded = _wasSynchronouslyLoaded | synchronousCall; + }); + } + + void _handleImageChunk(ImageChunkEvent event) { + assert(widget.loadingBuilder != null); + setState(() { + _loadingProgress = event; + _lastException = null; + _lastStack = null; }); } void _replaceImage({required ImageInfo? info}) { - _imageInfo?.dispose(); + final ImageInfo? oldImageInfo = _imageInfo; + SchedulerBinding.instance.addPostFrameCallback((_) => oldImageInfo?.dispose()); _imageInfo = info; } + // Updates _imageStream to newStream, and moves the stream listener + // registration from the old stream to the new stream (if a listener was + // registered). void _updateSourceStream(ImageStream newStream) { if (_imageStream?.key == newStream.key) { return; @@ -123,7 +192,9 @@ class _TransitionImageState extends State { } setState(() { + _loadingProgress = null; _frameNumber = null; + _wasSynchronouslyLoaded = false; }); _imageStream = newStream; @@ -138,22 +209,72 @@ class _TransitionImageState extends State { } _imageStream!.addListener(_getListener()); + _completerHandle?.dispose(); + _completerHandle = null; _isListeningToStream = true; } - void _stopListeningToStream() { + /// Stops listening to the image stream, if this state object has attached a + /// listener. + /// + /// If the listener from this state is the last listener on the stream, the + /// stream will be disposed. To keep the stream alive, set `keepStreamAlive` + /// to true, which create [ImageStreamCompleterHandle] to keep the completer + /// alive and is compatible with the [TickerMode] being off. + void _stopListeningToStream({bool keepStreamAlive = false}) { if (!_isListeningToStream) { return; } + if (keepStreamAlive && _completerHandle == null && _imageStream?.completer != null) { + _completerHandle = _imageStream!.completer!.keepAlive(); + } + _imageStream!.removeListener(_getListener()); _isListeningToStream = false; } + Widget _debugBuildErrorWidget(BuildContext context, Object error) { + return Stack( + alignment: Alignment.center, + children: [ + const Positioned.fill( + child: Placeholder( + color: Color(0xCF8D021F), + ), + ), + Padding( + padding: const EdgeInsets.all(4.0), + child: FittedBox( + child: Text( + '$error', + textAlign: TextAlign.center, + textDirection: TextDirection.ltr, + style: const TextStyle( + shadows: [ + Shadow(blurRadius: 1.0), + ], + ), + ), + ), + ), + ], + ); + } + @override Widget build(BuildContext context) { - return ValueListenableBuilder( + if (_lastException != null) { + if (widget.errorBuilder != null) { + return widget.errorBuilder!(context, _lastException!, _lastStack); + } + if (kDebugMode) { + return _debugBuildErrorWidget(context, _lastException!); + } + } + + Widget result = ValueListenableBuilder( valueListenable: widget.animation, builder: (context, t, child) => CustomPaint( painter: _TransitionImagePainter( @@ -166,6 +287,35 @@ class _TransitionImageState extends State { ), ), ); + + if (!widget.excludeFromSemantics) { + result = Semantics( + container: widget.semanticLabel != null, + image: true, + label: widget.semanticLabel ?? '', + child: result, + ); + } + + if (widget.frameBuilder != null) { + result = widget.frameBuilder!(context, result, _frameNumber, _wasSynchronouslyLoaded); + } + + if (widget.loadingBuilder != null) { + result = widget.loadingBuilder!(context, result, _loadingProgress); + } + + return result; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder description) { + super.debugFillProperties(description); + description.add(DiagnosticsProperty('stream', _imageStream)); + description.add(DiagnosticsProperty('pixels', _imageInfo)); + description.add(DiagnosticsProperty('loadingProgress', _loadingProgress)); + description.add(DiagnosticsProperty('frameNumber', _frameNumber)); + description.add(DiagnosticsProperty('wasSynchronouslyLoaded', _wasSynchronouslyLoaded)); } } @@ -194,8 +344,11 @@ class _TransitionImagePainter extends CustomPainter { const alignment = Alignment.center; final rect = ui.Rect.fromLTWH(0, 0, size.width, size.height); - final inputSize = Size(image!.width.toDouble(), image!.height.toDouble()); + if (rect.isEmpty) { + return; + } final outputSize = rect.size; + final inputSize = Size(image!.width.toDouble(), image!.height.toDouble()); final thumbnailSizes = applyBoxFit(thumbnailFit, inputSize / scale, size); final viewerSizes = applyBoxFit(viewerFit, inputSize / scale, size); diff --git a/lib/widgets/common/grid/item_tracker.dart b/lib/widgets/common/grid/item_tracker.dart index 9d657887b..74cd97101 100644 --- a/lib/widgets/common/grid/item_tracker.dart +++ b/lib/widgets/common/grid/item_tracker.dart @@ -44,24 +44,18 @@ class _GridItemTrackerState extends State> with WidgetsBin return (scrollableContext.findRenderObject() as RenderBox).size; } - Orientation get _windowOrientation { - final size = WidgetsBinding.instance.window.physicalSize; - return size.width > size.height ? Orientation.landscape : Orientation.portrait; - } - final List _subscriptions = []; // grid section metrics before the app is laid out with the new orientation late SectionedListLayout _lastSectionedListLayout; late Size _lastScrollableSize; - late Orientation _lastOrientation; + Orientation _lastOrientation = Orientation.portrait; @override void initState() { super.initState(); final highlightInfo = context.read(); _subscriptions.add(highlightInfo.eventBus.on>().listen(_trackItem)); - _lastOrientation = _windowOrientation; WidgetsBinding.instance.addObserver(this); _saveLayoutMetrics(); } @@ -78,9 +72,10 @@ class _GridItemTrackerState extends State> with WidgetsBin @override void didChangeMetrics() { // the order of `WidgetsBindingObserver` metrics change notification is unreliable - // w.r.t. the `MediaQuery` update, and consequentially to this widget update: + // w.r.t. the `View` update, and consequentially to this widget update: // `WidgetsBindingObserver` is notified mostly before, sometimes after, the widget update - final orientation = _windowOrientation; + final size = View.of(context).physicalSize; + final orientation = size.width > size.height ? Orientation.landscape : Orientation.portrait; if (_lastOrientation != orientation) { _lastOrientation = orientation; _onLayoutChanged(); @@ -138,7 +133,7 @@ class _GridItemTrackerState extends State> with WidgetsBin Future _saveLayoutMetrics() async { // use a delay to obtain current layout metrics // so that we can handle window orientation change with the previous metrics, - // regardless of the `MediaQuery`/`WidgetsBindingObserver` order uncertainty + // regardless of the `View`/`WidgetsBindingObserver` order uncertainty await Future.delayed(const Duration(milliseconds: 500)); if (mounted) { diff --git a/lib/widgets/common/grid/scaling.dart b/lib/widgets/common/grid/scaling.dart index 767b86cf9..9f4493a61 100644 --- a/lib/widgets/common/grid/scaling.dart +++ b/lib/widgets/common/grid/scaling.dart @@ -57,7 +57,7 @@ class _GridScaleGestureDetectorState extends State((mq) => mq.gestureSettings); + final gestureSettings = MediaQuery.gestureSettingsOf(context); final child = GestureDetector( // Horizontal/vertical drag gestures are interpreted as scaling @@ -116,11 +116,9 @@ class _GridScaleGestureDetectorState extends State extends State extends State extends State extends State { return _initialized ? BoxDecoration( gradient: RadialGradient( - center: FractionalOffset.fromOffsetAndSize(gradientCenter, context.select((mq) => mq.size)), + center: FractionalOffset.fromOffsetAndSize(gradientCenter, MediaQuery.sizeOf(context)), radius: 1, colors: isDark ? const [ diff --git a/lib/widgets/common/grid/sections/mosaic/row.dart b/lib/widgets/common/grid/sections/mosaic/row.dart index 4d0767f96..8d0aae525 100644 --- a/lib/widgets/common/grid/sections/mosaic/row.dart +++ b/lib/widgets/common/grid/sections/mosaic/row.dart @@ -8,7 +8,7 @@ class MosaicGridRow extends MultiChildRenderObjectWidget { final double spacing; final TextDirection textDirection; - MosaicGridRow({ + const MosaicGridRow({ super.key, required this.rowLayout, required this.spacing, diff --git a/lib/widgets/common/identity/aves_app_bar.dart b/lib/widgets/common/identity/aves_app_bar.dart index 3d5b57559..590be02f1 100644 --- a/lib/widgets/common/identity/aves_app_bar.dart +++ b/lib/widgets/common/identity/aves_app_bar.dart @@ -32,73 +32,68 @@ class AvesAppBar extends StatelessWidget { @override Widget build(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); final useTvLayout = settings.useTvLayout; - return Selector( - selector: (context, mq) => mq.padding.top, - builder: (context, mqPaddingTop, child) { - return SliverPersistentHeader( - floating: !useTvLayout, - pinned: pinned, - delegate: _SliverAppBarDelegate( - height: mqPaddingTop + appBarHeightForContentHeight(contentHeight), - child: child!, - ), - ); - }, - child: DirectionalSafeArea( - start: !useTvLayout, - bottom: false, - child: AvesFloatingBar( - builder: (context, backgroundColor, child) => Material( - color: backgroundColor, - child: child, - ), - child: Column( - children: [ - SizedBox( - height: kToolbarHeight * context.select((mq) => mq.textScaleFactor), - child: Row( - children: [ - leading != null - ? Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Hero( - tag: leadingHeroTag, - flightShuttleBuilder: _flightShuttleBuilder, - transitionOnUserGestures: true, - child: FontSizeIconTheme( - child: leading!, + return SliverPersistentHeader( + floating: !useTvLayout, + pinned: pinned, + delegate: _SliverAppBarDelegate( + height: MediaQuery.paddingOf(context).top + appBarHeightForContentHeight(contentHeight), + child: DirectionalSafeArea( + start: !useTvLayout, + bottom: false, + child: AvesFloatingBar( + builder: (context, backgroundColor, child) => Material( + color: backgroundColor, + child: child, + ), + child: Column( + children: [ + SizedBox( + height: kToolbarHeight * textScaleFactor, + child: Row( + children: [ + leading != null + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Hero( + tag: leadingHeroTag, + flightShuttleBuilder: _flightShuttleBuilder, + transitionOnUserGestures: true, + child: FontSizeIconTheme( + child: leading!, + ), ), - ), - ) - : const SizedBox(width: 16), - Expanded( - child: DefaultTextStyle( - style: Theme.of(context).appBarTheme.titleTextStyle!, - child: Hero( - tag: titleHeroTag, - flightShuttleBuilder: _flightShuttleBuilder, - transitionOnUserGestures: true, - child: AnimatedSwitcher( - duration: context.read().iconAnimation, - child: FontSizeIconTheme( - child: Row( - key: ValueKey(transitionKey), - children: [ - Expanded(child: title), - ...actions, - ], + ) + : const SizedBox(width: 16), + Expanded( + child: DefaultTextStyle( + style: Theme.of(context).appBarTheme.titleTextStyle!, + child: Hero( + tag: titleHeroTag, + flightShuttleBuilder: _flightShuttleBuilder, + transitionOnUserGestures: true, + child: AnimatedSwitcher( + duration: context.read().iconAnimation, + child: FontSizeIconTheme( + child: Row( + key: ValueKey(transitionKey), + children: [ + Expanded(child: title), + ...actions, + ], + ), ), ), ), ), ), - ), - ], + ], + ), ), - ), - if (bottom != null) bottom!, - ], + if (bottom != null) bottom!, + ], + ), ), ), ), diff --git a/lib/widgets/common/identity/aves_filter_chip.dart b/lib/widgets/common/identity/aves_filter_chip.dart index 87809c610..1192c6322 100644 --- a/lib/widgets/common/identity/aves_filter_chip.dart +++ b/lib/widgets/common/identity/aves_filter_chip.dart @@ -31,12 +31,12 @@ enum HeroType { always, onTap, never } @immutable class AvesFilterDecoration { - final Widget widget; final Radius radius; + final Widget widget; const AvesFilterDecoration({ - required this.widget, required this.radius, + required this.widget, }); BorderRadius get textBorderRadius => BorderRadius.vertical(bottom: radius); @@ -88,9 +88,9 @@ class AvesFilterChip extends StatefulWidget { required double chipPadding, required double rowPadding, }) { - return context.select((mq) { - return (mq.size.width - mq.padding.horizontal - chipPadding * minChipPerRow - rowPadding) / minChipPerRow; - }); + final mqWidth = MediaQuery.sizeOf(context).width; + final mqHorizontalPadding = MediaQuery.paddingOf(context).horizontal; + return (mqWidth - mqHorizontalPadding - chipPadding * minChipPerRow - rowPadding) / minChipPerRow; } static Future showDefaultLongPressMenu(BuildContext context, CollectionFilter filter, Offset tapPosition) async { diff --git a/lib/widgets/common/identity/aves_logo.dart b/lib/widgets/common/identity/aves_logo.dart index c6c03d914..cd25fe4d5 100644 --- a/lib/widgets/common/identity/aves_logo.dart +++ b/lib/widgets/common/identity/aves_logo.dart @@ -37,7 +37,7 @@ class AvesLogo extends StatelessWidget { radius: size / 2, child: CircleAvatar( backgroundColor: Colors.white, - radius: size / 2 - AvesBorder.curvedBorderWidth, + radius: size / 2 - AvesBorder.curvedBorderWidth(context), child: Padding( padding: EdgeInsets.only(top: size / 15), child: child, diff --git a/lib/widgets/common/identity/buttons/overlay_button.dart b/lib/widgets/common/identity/buttons/overlay_button.dart index d4b085433..ce1aeeffd 100644 --- a/lib/widgets/common/identity/buttons/overlay_button.dart +++ b/lib/widgets/common/identity/buttons/overlay_button.dart @@ -73,7 +73,7 @@ class _OverlayButtonState extends State { builder: (context, focused, child) { final border = AvesBorder.border( context, - width: AvesBorder.curvedBorderWidth * (focused ? 3 : 1), + width: AvesBorder.curvedBorderWidth(context) * (focused ? 3 : 1), ); return borderRadius != null ? BlurredRRect( diff --git a/lib/widgets/common/map/buttons/panel.dart b/lib/widgets/common/map/buttons/panel.dart index ecb325cd9..c25427800 100644 --- a/lib/widgets/common/map/buttons/panel.dart +++ b/lib/widgets/common/map/buttons/panel.dart @@ -42,7 +42,6 @@ class MapButtonPanel extends StatelessWidget { tooltip: MaterialLocalizations.of(context).backButtonTooltip, ); } - break; case MapNavigationButton.map: if (openMapPage != null) { navigationButton = MapOverlayButton( @@ -51,7 +50,6 @@ class MapButtonPanel extends StatelessWidget { tooltip: context.l10n.openMapPageTooltip, ); } - break; case MapNavigationButton.none: break; } diff --git a/lib/widgets/common/map/geo_map.dart b/lib/widgets/common/map/geo_map.dart index 5d008fb20..ef12052ea 100644 --- a/lib/widgets/common/map/geo_map.dart +++ b/lib/widgets/common/map/geo_map.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:math'; -import 'dart:ui'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/extensions/images.dart'; @@ -35,6 +34,7 @@ class GeoMap extends StatefulWidget { final AvesMapController? controller; final Listenable? collectionListenable; final List entries; + final Size availableSize; final LatLng? initialCenter; final ValueNotifier isAnimatingNotifier; final ValueNotifier? dotLocationNotifier; @@ -60,6 +60,7 @@ class GeoMap extends StatefulWidget { this.controller, this.collectionListenable, required this.entries, + required this.availableSize, this.initialCenter, required this.isAnimatingNotifier, this.dotLocationNotifier, @@ -133,6 +134,13 @@ class _GeoMapState extends State { @override Widget build(BuildContext context) { + final devicePixelRatio = View.of(context).devicePixelRatio; + void onMarkerLongPress(GeoEntry geoEntry, LatLng tapLocation) => _onMarkerLongPress( + geoEntry: geoEntry, + tapLocation: tapLocation, + devicePixelRatio: devicePixelRatio, + ); + return Selector( selector: (context, s) => s.mapStyle, builder: (context, mapStyle, child) { @@ -143,6 +151,7 @@ class _GeoMapState extends State { buildThumbnailImage: (extent) => ThumbnailImage( entry: key.entry, extent: extent, + devicePixelRatio: devicePixelRatio, progressive: !isHeavy, ), ); @@ -173,9 +182,8 @@ class _GeoMapState extends State { onUserZoomChange: widget.onUserZoomChange, onMapTap: widget.onMapTap, onMarkerTap: _onMarkerTap, - onMarkerLongPress: _onMarkerLongPress, + onMarkerLongPress: onMarkerLongPress, ); - break; case EntryMapStyle.osmHot: case EntryMapStyle.stamenToner: case EntryMapStyle.stamenWatercolor: @@ -204,9 +212,8 @@ class _GeoMapState extends State { onUserZoomChange: widget.onUserZoomChange, onMapTap: widget.onMapTap, onMarkerTap: _onMarkerTap, - onMarkerLongPress: _onMarkerLongPress, + onMarkerLongPress: onMarkerLongPress, ); - break; } } else { final overlay = Center( @@ -360,8 +367,8 @@ class _GeoMapState extends State { ); bounds = bounds.copyWith(zoom: max(minInitialZoom, bounds.zoom.floorToDouble())); - final availableSize = window.physicalSize / window.devicePixelRatio; final neededSize = bounds.toDisplaySize(); + final availableSize = widget.availableSize; if (neededSize.width > availableSize.width || neededSize.height > availableSize.height) { return _initBoundsForEntries(entries: entries, recentCount: (recentCount ?? 10000) ~/ 10); } @@ -457,7 +464,11 @@ class _GeoMapState extends State { onTap(markerLocation, markerEntry); } - Future _onMarkerLongPress(GeoEntry geoEntry, LatLng tapLocation) async { + Future _onMarkerLongPress({ + required GeoEntry geoEntry, + required LatLng tapLocation, + required double devicePixelRatio, + }) async { final onMarkerLongPress = widget.onMarkerLongPress; if (onMarkerLongPress == null) return; @@ -478,6 +489,7 @@ class _GeoMapState extends State { buildThumbnailImage: (extent) => ThumbnailImage( entry: markerEntry, extent: extent, + devicePixelRatio: devicePixelRatio, ), ); onMarkerLongPress( diff --git a/lib/widgets/common/map/leaflet/scale_layer.dart b/lib/widgets/common/map/leaflet/scale_layer.dart index af99267d9..d9c55d1db 100644 --- a/lib/widgets/common/map/leaflet/scale_layer.dart +++ b/lib/widgets/common/map/leaflet/scale_layer.dart @@ -82,7 +82,6 @@ class ScaleLayerWidget extends StatelessWidget { // meters distanceMeters = scaleMeters[scaleLevel]; displayDistance = distanceMeters >= metersInAKilometer ? '${(distanceMeters / metersInAKilometer).toStringAsFixed(0)} km' : '${distanceMeters.toStringAsFixed(0)} m'; - break; case UnitSystem.imperial: if (scaleLevel < 15) { // miles @@ -95,7 +94,6 @@ class ScaleLayerWidget extends StatelessWidget { distanceMeters = distanceFeet * metersInAFoot; displayDistance = '${distanceFeet.toStringAsFixed(0)} ft'; } - break; } final start = map.project(center); diff --git a/lib/widgets/common/map/leaflet/tile_layers.dart b/lib/widgets/common/map/leaflet/tile_layers.dart index 5ea7d1bb9..2a547a0a3 100644 --- a/lib/widgets/common/map/leaflet/tile_layers.dart +++ b/lib/widgets/common/map/leaflet/tile_layers.dart @@ -1,7 +1,6 @@ import 'package:aves/model/device.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; -import 'package:provider/provider.dart'; const _tileLayerBackgroundColor = Colors.transparent; @@ -14,7 +13,7 @@ class OSMHotLayer extends StatelessWidget { urlTemplate: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', subdomains: const ['a', 'b', 'c'], backgroundColor: _tileLayerBackgroundColor, - retinaMode: context.select((mq) => mq.devicePixelRatio) > 1, + retinaMode: MediaQuery.devicePixelRatioOf(context) > 1, userAgentPackageName: device.userAgent, ); } @@ -29,7 +28,7 @@ class StamenTonerLayer extends StatelessWidget { urlTemplate: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.png', subdomains: const ['a', 'b', 'c', 'd'], backgroundColor: _tileLayerBackgroundColor, - retinaMode: context.select((mq) => mq.devicePixelRatio) > 1, + retinaMode: MediaQuery.devicePixelRatioOf(context) > 1, userAgentPackageName: device.userAgent, ); } @@ -44,7 +43,7 @@ class StamenWatercolorLayer extends StatelessWidget { urlTemplate: 'https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg', subdomains: const ['a', 'b', 'c', 'd'], backgroundColor: _tileLayerBackgroundColor, - retinaMode: context.select((mq) => mq.devicePixelRatio) > 1, + retinaMode: MediaQuery.devicePixelRatioOf(context) > 1, userAgentPackageName: device.userAgent, ); } diff --git a/lib/widgets/common/map/map_action_delegate.dart b/lib/widgets/common/map/map_action_delegate.dart index e108d01bb..d5fe1b079 100644 --- a/lib/widgets/common/map/map_action_delegate.dart +++ b/lib/widgets/common/map/map_action_delegate.dart @@ -26,13 +26,10 @@ class MapActionDelegate { ), onSelection: (v) => settings.mapStyle = v, ); - break; case MapAction.zoomIn: controller?.zoomBy(1); - break; case MapAction.zoomOut: controller?.zoomBy(-1); - break; } } } diff --git a/lib/widgets/common/search/page.dart b/lib/widgets/common/search/page.dart index 31bfca47d..8aee4f8d9 100644 --- a/lib/widgets/common/search/page.dart +++ b/lib/widgets/common/search/page.dart @@ -114,13 +114,11 @@ class _SearchPageState extends State { key: const ValueKey(SearchBody.suggestions), child: widget.delegate.buildSuggestions(context), ); - break; case SearchBody.results: body = KeyedSubtree( key: const ValueKey(SearchBody.results), child: widget.delegate.buildResults(context), ); - break; case null: break; } diff --git a/lib/widgets/common/thumbnail/decorated.dart b/lib/widgets/common/thumbnail/decorated.dart index b4176b264..e55912e26 100644 --- a/lib/widgets/common/thumbnail/decorated.dart +++ b/lib/widgets/common/thumbnail/decorated.dart @@ -14,7 +14,8 @@ class DecoratedThumbnail extends StatelessWidget { final Object? Function()? heroTagger; static final Color borderColor = Colors.grey.shade700; - static final double borderWidth = AvesBorder.straightBorderWidth; + + static double borderWidth(BuildContext context) => AvesBorder.straightBorderWidth(context); const DecoratedThumbnail({ super.key, @@ -35,6 +36,7 @@ class DecoratedThumbnail extends StatelessWidget { Widget child = ThumbnailImage( entry: entry, extent: tileExtent, + devicePixelRatio: MediaQuery.devicePixelRatioOf(context), isMosaic: isMosaic, cancellableNotifier: cancellableNotifier, heroTag: heroTagger?.call(), @@ -64,7 +66,7 @@ class DecoratedThumbnail extends StatelessWidget { foregroundDecoration: BoxDecoration( border: Border.fromBorderSide(BorderSide( color: borderColor, - width: borderWidth, + width: borderWidth(context), )), ), width: thumbnailWidth, diff --git a/lib/widgets/common/thumbnail/image.dart b/lib/widgets/common/thumbnail/image.dart index 0c3464951..794979ef8 100644 --- a/lib/widgets/common/thumbnail/image.dart +++ b/lib/widgets/common/thumbnail/image.dart @@ -1,5 +1,4 @@ import 'dart:math'; -import 'dart:ui'; import 'package:aves/image_providers/thumbnail_provider.dart'; import 'package:aves/model/entry/entry.dart'; @@ -20,7 +19,7 @@ import 'package:provider/provider.dart'; class ThumbnailImage extends StatefulWidget { final AvesEntry entry; - final double extent; + final double extent, devicePixelRatio; final bool isMosaic, progressive; final BoxFit? fit; final bool showLoadingBackground; @@ -31,6 +30,7 @@ class ThumbnailImage extends StatefulWidget { super.key, required this.entry, required this.extent, + required this.devicePixelRatio, this.progressive = true, this.isMosaic = false, this.fit, @@ -57,7 +57,6 @@ class _ThumbnailImageState extends State { ImageInfo? _lastImageInfo; Object? _lastException; late final ImageStreamListener _streamListener; - late DisposableBuildContext> _scrollAwareContext; AvesEntry get entry => widget.entry; @@ -69,7 +68,6 @@ class _ThumbnailImageState extends State { void initState() { super.initState(); _streamListener = ImageStreamListener(_onImageLoad, onError: _onError); - _scrollAwareContext = DisposableBuildContext>(this); _registerWidget(widget); } @@ -85,7 +83,6 @@ class _ThumbnailImageState extends State { @override void dispose() { _unregisterWidget(widget); - _scrollAwareContext.dispose(); super.dispose(); } @@ -126,16 +123,10 @@ class _ThumbnailImageState extends State { _providers.addAll([ if (lowQuality != null) _ConditionalImageProvider( - ScrollAwareImageProvider( - context: _scrollAwareContext, - imageProvider: lowQuality, - ), + lowQuality, ), _ConditionalImageProvider( - ScrollAwareImageProvider( - context: _scrollAwareContext, - imageProvider: highQuality, - ), + highQuality, _needSizedProvider, ), ]); @@ -176,8 +167,7 @@ class _ThumbnailImageState extends State { bool _needSizedProvider(ImageInfo? currentImageInfo) { if (currentImageInfo == null) return true; final currentImage = currentImageInfo.image; - // directly uses `devicePixelRatio` as it never changes, to avoid visiting ancestors via `MediaQuery` - final sizedThreshold = extent * window.devicePixelRatio; + final sizedThreshold = extent * widget.devicePixelRatio; return sizedThreshold > min(currentImage.width, currentImage.height); } diff --git a/lib/widgets/debug/app_debug_page.dart b/lib/widgets/debug/app_debug_page.dart index 70729be0d..9c5506efb 100644 --- a/lib/widgets/debug/app_debug_page.dart +++ b/lib/widgets/debug/app_debug_page.dart @@ -182,18 +182,15 @@ class _AppDebugPageState extends State { }, false); await favourites.clear(); await favourites.add(source.visibleEntries); - break; case AppDebugAction.prepScreenshotStats: settings.changeFilterVisibility(settings.hiddenFilters, true); settings.changeFilterVisibility({ PathFilter('/storage/emulated/0/Pictures/Dev'), }, false); - break; case AppDebugAction.prepScreenshotCountries: settings.changeFilterVisibility({ LocationFilter(LocationLevel.country, 'Belgium;BE'), }, false); - break; case AppDebugAction.mediaStoreScanDir: // scan files copied from test assets // we do it via the app instead of broadcasting via ADB @@ -202,7 +199,6 @@ class _AppDebugPageState extends State { context: context, builder: (context) => const MediaStoreScanDirDialog(), ); - break; case AppDebugAction.greenScreen: await Navigator.maybeOf(context)?.push( MaterialPageRoute( @@ -212,7 +208,6 @@ class _AppDebugPageState extends State { ), ), ); - break; } } } diff --git a/lib/widgets/debug/settings.dart b/lib/widgets/debug/settings.dart index b03b03356..cbc87137c 100644 --- a/lib/widgets/debug/settings.dart +++ b/lib/widgets/debug/settings.dart @@ -66,7 +66,7 @@ class DebugSettingsSection extends StatelessWidget { 'recentDestinationAlbums': toMultiline(settings.recentDestinationAlbums), 'recentTags': toMultiline(settings.recentTags), 'locale': '${settings.locale}', - 'systemLocales': '${WidgetsBinding.instance.window.locales}', + 'systemLocales': '${WidgetsBinding.instance.platformDispatcher.locales}', 'topEntryIds': '${settings.topEntryIds}', }, ), diff --git a/lib/widgets/dialogs/add_shortcut_dialog.dart b/lib/widgets/dialogs/add_shortcut_dialog.dart index f445e3df6..095a836b8 100644 --- a/lib/widgets/dialogs/add_shortcut_dialog.dart +++ b/lib/widgets/dialogs/add_shortcut_dialog.dart @@ -8,7 +8,6 @@ import 'package:aves/widgets/dialogs/item_picker.dart'; import 'package:aves/widgets/dialogs/pick_dialogs/item_pick_page.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:tuple/tuple.dart'; import 'aves_dialog.dart'; @@ -60,7 +59,7 @@ class _AddShortcutDialogState extends State { return MediaQueryDataProvider( child: Builder( builder: (context) { - final shortestSide = context.select((mq) => mq.size.shortestSide); + final shortestSide = MediaQuery.sizeOf(context).shortestSide; final extent = (shortestSide / 3.0).clamp(60.0, 160.0); return AvesDialog( scrollableContent: [ diff --git a/lib/widgets/dialogs/aves_confirmation_dialog.dart b/lib/widgets/dialogs/aves_confirmation_dialog.dart index ffbba695d..dd9f4b312 100644 --- a/lib/widgets/dialogs/aves_confirmation_dialog.dart +++ b/lib/widgets/dialogs/aves_confirmation_dialog.dart @@ -72,16 +72,12 @@ void _skipConfirmation(ConfirmationDialog type) { switch (type) { case ConfirmationDialog.createVault: settings.confirmCreateVault = false; - break; case ConfirmationDialog.deleteForever: settings.confirmDeleteForever = false; - break; case ConfirmationDialog.moveToBin: settings.confirmMoveToBin = false; - break; case ConfirmationDialog.moveUndatedItems: settings.confirmMoveUndatedItems = false; - break; } } diff --git a/lib/widgets/dialogs/aves_dialog.dart b/lib/widgets/dialogs/aves_dialog.dart index c19c0fe5a..8127a61d1 100644 --- a/lib/widgets/dialogs/aves_dialog.dart +++ b/lib/widgets/dialogs/aves_dialog.dart @@ -3,7 +3,6 @@ import 'dart:ui'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class AvesDialog extends StatelessWidget { static const confirmationRouteName = '/dialog/confirmation'; @@ -104,7 +103,7 @@ class AvesDialog extends StatelessWidget { // workaround because the dialog tries // to size itself to the content intrinsic size, // but the `ListView` viewport does not have one - width: context.select((mq) => mq.size.width / 2), + width: MediaQuery.sizeOf(context).width / 2, child: DecoratedBox( decoration: contentDecoration(context), child: child, diff --git a/lib/widgets/dialogs/convert_entry_dialog.dart b/lib/widgets/dialogs/convert_entry_dialog.dart index f7b047d17..fe9bae4a0 100644 --- a/lib/widgets/dialogs/convert_entry_dialog.dart +++ b/lib/widgets/dialogs/convert_entry_dialog.dart @@ -78,11 +78,9 @@ class _ConvertEntryDialogState extends State { final displaySize = entries.first.displaySize; _widthController.text = '${displaySize.width.round()}'; _heightController.text = '${displaySize.height.round()}'; - break; case LengthUnit.percent: _widthController.text = '100'; _heightController.text = '100'; - break; } } @@ -149,10 +147,8 @@ class _ConvertEntryDialogState extends State { switch (_lengthUnit) { case LengthUnit.px: _heightController.text = '${(width / entries.first.displayAspectRatio).round()}'; - break; case LengthUnit.percent: _heightController.text = '$width'; - break; } } else { _heightController.text = ''; @@ -175,10 +171,8 @@ class _ConvertEntryDialogState extends State { switch (_lengthUnit) { case LengthUnit.px: _widthController.text = '${(height * entries.first.displayAspectRatio).round()}'; - break; case LengthUnit.percent: _widthController.text = '$height'; - break; } } else { _widthController.text = ''; diff --git a/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart index f46d2c53c..4111ed044 100644 --- a/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart @@ -145,7 +145,7 @@ class _EditEntryDateDialogState extends State { Widget _buildSetCustomContent(BuildContext context) { final l10n = context.l10n; final locale = l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); return Padding( padding: const EdgeInsetsDirectional.only(start: 16, end: 8), @@ -179,7 +179,7 @@ class _EditEntryDateDialogState extends State { Widget _buildCopyItemContent(BuildContext context) { final l10n = context.l10n; final locale = l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); return Padding( padding: const EdgeInsetsDirectional.only(start: 16, end: 8), @@ -365,11 +365,9 @@ class _EditEntryDateDialogState extends State { case DateEditAction.copyItem: case DateEditAction.extractFromTitle: _isValidNotifier.value = true; - break; case DateEditAction.shift: case DateEditAction.remove: _isValidNotifier.value = _fields.isNotEmpty; - break; } } diff --git a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart index 4096bd154..1cad7d7e4 100644 --- a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart @@ -307,33 +307,26 @@ class _EditEntryLocationDialogState extends State { switch (_action) { case LocationEditAction.chooseOnMap: _isValidNotifier.value = _mapCoordinates != null; - break; case LocationEditAction.copyItem: _isValidNotifier.value = _copyItemSource.hasGps; - break; case LocationEditAction.setCustom: _isValidNotifier.value = _parseLatLng() != null; - break; case LocationEditAction.remove: _isValidNotifier.value = true; - break; } } void _submit(BuildContext context) { + final navigator = Navigator.maybeOf(context); switch (_action) { case LocationEditAction.chooseOnMap: - Navigator.maybeOf(context)?.pop(_mapCoordinates); - break; + navigator?.pop(_mapCoordinates); case LocationEditAction.copyItem: - Navigator.maybeOf(context)?.pop(_copyItemSource.latLng); - break; + navigator?.pop(_copyItemSource.latLng); case LocationEditAction.setCustom: - Navigator.maybeOf(context)?.pop(_parseLatLng()); - break; + navigator?.pop(_parseLatLng()); case LocationEditAction.remove: - Navigator.maybeOf(context)?.pop(ExtraAvesEntryMetadataEdition.removalLocation); - break; + navigator?.pop(ExtraAvesEntryMetadataEdition.removalLocation); } } } diff --git a/lib/widgets/dialogs/entry_editors/edit_rating_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_rating_dialog.dart index 8004d5e1c..4c79a3fb9 100644 --- a/lib/widgets/dialogs/entry_editors/edit_rating_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_rating_dialog.dart @@ -32,11 +32,9 @@ class _EditEntryRatingDialogState extends State { case -1: _action = _RatingAction.rejected; _rating = 0; - break; case 0: _action = _RatingAction.unrated; _rating = 0; - break; default: _action = _RatingAction.set; _rating = entryRating; @@ -121,13 +119,10 @@ class _EditEntryRatingDialogState extends State { switch (_action) { case _RatingAction.set: entryRating = _rating; - break; case _RatingAction.rejected: entryRating = -1; - break; case _RatingAction.unrated: entryRating = 0; - break; } Navigator.maybeOf(context)?.pop(entryRating); } diff --git a/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart b/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart index 3ba035090..a9bb11799 100644 --- a/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart +++ b/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart @@ -16,7 +16,6 @@ import 'package:aves/widgets/common/identity/buttons/outlined_button.dart'; import 'package:aves/widgets/common/thumbnail/decorated.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import 'package:provider/provider.dart'; class RenameEntrySetPage extends StatefulWidget { static const routeName = '/rename_entry_set'; @@ -60,6 +59,8 @@ class _RenameEntrySetPageState extends State { @override Widget build(BuildContext context) { final l10n = context.l10n; + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final effectiveThumbnailExtent = max(thumbnailExtent, thumbnailExtent * textScaleFactor); return AvesScaffold( appBar: AppBar( title: Text(l10n.renameEntrySetPageTitle), @@ -121,63 +122,58 @@ class _RenameEntrySetPageState extends State { ), ), Expanded( - child: Selector( - selector: (context, mq) => mq.textScaleFactor, - builder: (context, textScaleFactor, child) { - final effectiveThumbnailExtent = max(thumbnailExtent, thumbnailExtent * textScaleFactor); - return GridTheme( - extent: effectiveThumbnailExtent, - child: ListView.separated( - physics: const NeverScrollableScrollPhysics(), - padding: const EdgeInsets.symmetric(vertical: 12), - itemBuilder: (context, index) { - final entry = entries[index]; - final sourceName = entry.filenameWithoutExtension ?? ''; - return Row( + child: GridTheme( + extent: effectiveThumbnailExtent, + child: ListView.separated( + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.symmetric(vertical: 12), + itemBuilder: (context, index) { + final entry = entries[index]; + final sourceName = entry.filenameWithoutExtension ?? ''; + return Row( + children: [ + DecoratedThumbnail( + entry: entry, + tileExtent: effectiveThumbnailExtent, + selectable: false, + highlightable: false, + ), + const SizedBox(width: 8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - DecoratedThumbnail( - entry: entry, - tileExtent: effectiveThumbnailExtent, - selectable: false, - highlightable: false, + Text( + sourceName, + style: TextStyle(color: Theme.of(context).textTheme.bodySmall!.color), + softWrap: false, + overflow: TextOverflow.fade, + maxLines: 1, ), - const SizedBox(width: 8), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - sourceName, - style: TextStyle(color: Theme.of(context).textTheme.bodySmall!.color), - softWrap: false, - overflow: TextOverflow.fade, - maxLines: 1, - ), - const SizedBox(height: 4), - ValueListenableBuilder( - valueListenable: _namingPatternNotifier, - builder: (context, pattern, child) { - return Text( - pattern.apply(entry, index), - softWrap: false, - overflow: TextOverflow.fade, - maxLines: 1, - ); - }, - ), - ], - ), + const SizedBox(height: 4), + ValueListenableBuilder( + valueListenable: _namingPatternNotifier, + builder: (context, pattern, child) { + return Text( + pattern.apply(entry, index), + softWrap: false, + overflow: TextOverflow.fade, + maxLines: 1, + ); + }, ), ], - ); - }, - separatorBuilder: (context, index) => const SizedBox( - height: CollectionGrid.fixedExtentLayoutSpacing, + ), ), - itemCount: min(entryCount, previewMax), - ), + ], ); - }), + }, + separatorBuilder: (context, index) => const SizedBox( + height: CollectionGrid.fixedExtentLayoutSpacing, + ), + itemCount: min(entryCount, previewMax), + ), + ), ), const Divider(height: 0), Center( diff --git a/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart b/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart index dbd30f69d..3a3c8db7d 100644 --- a/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart @@ -57,7 +57,10 @@ class _CoverSelectionDialogState extends State { static const double itemPickerExtent = 46; static const double appPickerExtent = 32; - double tabBarHeight(BuildContext context) => 64 * max(1, MediaQuery.textScaleFactorOf(context)); + double tabBarHeight(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + return 64 * max(1, textScaleFactor); + } static const double tabIndicatorWeight = 2; diff --git a/lib/widgets/dialogs/filter_editors/pattern_dialog.dart b/lib/widgets/dialogs/filter_editors/pattern_dialog.dart index f77241c9d..d027af570 100644 --- a/lib/widgets/dialogs/filter_editors/pattern_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/pattern_dialog.dart @@ -2,7 +2,6 @@ import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:flutter/material.dart'; import 'package:pattern_lock/pattern_lock.dart'; -import 'package:provider/provider.dart'; class PatternDialog extends StatefulWidget { static const routeName = '/dialog/pattern'; @@ -33,7 +32,7 @@ class _PatternDialogState extends State { Padding( padding: const EdgeInsets.symmetric(vertical: 16), child: SizedBox.square( - dimension: context.select((mq) => mq.size.shortestSide / 2), + dimension: MediaQuery.sizeOf(context).shortestSide / 2, child: PatternLock( relativePadding: .4, selectedColor: colorScheme.secondary, diff --git a/lib/widgets/dialogs/item_picker.dart b/lib/widgets/dialogs/item_picker.dart index 1b908c1f0..c13726e17 100644 --- a/lib/widgets/dialogs/item_picker.dart +++ b/lib/widgets/dialogs/item_picker.dart @@ -43,6 +43,7 @@ class ItemPicker extends StatelessWidget { ThumbnailImage( entry: entry, extent: extent, + devicePixelRatio: MediaQuery.devicePixelRatioOf(context), ), PositionedDirectional( end: -1, diff --git a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart index 253e1ebaa..13f446aef 100644 --- a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart @@ -164,13 +164,10 @@ class _AlbumPickPageState extends State<_AlbumPickPage> { switch (action) { case ChipSetAction.createAlbum: _createAlbum(); - break; case ChipSetAction.createVault: _createVault(); - break; default: actionDelegate.onActionSelected(context, {}, action); - break; } } diff --git a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart index a20f76ad4..5c79bc06a 100644 --- a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart @@ -20,7 +20,6 @@ import 'package:aves_map/aves_map.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:latlong2/latlong.dart'; -import 'package:provider/provider.dart'; class LocationPickPage extends StatelessWidget { static const routeName = '/location_pick'; @@ -137,6 +136,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin controller: _mapController, collectionListenable: openingCollection, entries: openingCollection?.sortedEntries ?? [], + availableSize: MediaQuery.sizeOf(context), initialCenter: widget.initialLocation, isAnimatingNotifier: _isPageAnimatingNotifier, dotLocationNotifier: _dotLocationNotifier, @@ -177,12 +177,11 @@ class _LocationInfo extends StatelessWidget { @override Widget build(BuildContext context) { - final orientation = context.select((v) => v.orientation); - return ValueListenableBuilder( valueListenable: locationNotifier, builder: (context, location, child) { - final content = orientation == Orientation.portrait + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; + final content = isPortrait ? [ Expanded( child: Column( @@ -218,7 +217,10 @@ class _LocationInfo extends StatelessWidget { ); } - static double getIconSize(BuildContext context) => 16.0 * context.select((mq) => mq.textScaleFactor); + static double getIconSize(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + return 16 * textScaleFactor; + } } class _AddressRow extends StatefulWidget { @@ -251,6 +253,7 @@ class _AddressRowState extends State<_AddressRow> { @override Widget build(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -263,7 +266,7 @@ class _AddressRowState extends State<_AddressRow> { // addresses can include non-latin scripts with inconsistent line height, // which is especially an issue for relayout/painting of heavy Google map, // so we give extra height to give breathing room to the text and stabilize layout - height: Theme.of(context).textTheme.bodyMedium!.fontSize! * context.select((mq) => mq.textScaleFactor) * 2, + height: Theme.of(context).textTheme.bodyMedium!.fontSize! * textScaleFactor * 2, child: ValueListenableBuilder( valueListenable: _addressLineNotifier, builder: (context, addressLine, child) { diff --git a/lib/widgets/dialogs/tile_view_dialog.dart b/lib/widgets/dialogs/tile_view_dialog.dart index b4aa1d56e..941963e98 100644 --- a/lib/widgets/dialogs/tile_view_dialog.dart +++ b/lib/widgets/dialogs/tile_view_dialog.dart @@ -195,8 +195,9 @@ class _TileViewDialogState extends State> with dropdownColor: Themes.thirdLayerColor(context), ); - final iconSize = IconTheme.of(context).size! * MediaQuery.textScaleFactorOf(context); - final isPortrait = context.select((mq) => mq.orientation) == Orientation.portrait; + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final iconSize = IconTheme.of(context).size! * textScaleFactor; + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; final child = isPortrait ? Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/widgets/filter_grids/albums_page.dart b/lib/widgets/filter_grids/albums_page.dart index 259fa0728..a40a79a66 100644 --- a/lib/widgets/filter_grids/albums_page.dart +++ b/lib/widgets/filter_grids/albums_page.dart @@ -123,7 +123,6 @@ class AlbumListPage extends StatelessWidget { if (sections.containsKey(vaultKey)) vaultKey: sections[vaultKey]!, if (sections.containsKey(regularKey)) regularKey: sections[regularKey]!, }; - break; case AlbumChipGroupFactor.mimeType: final visibleEntries = source.visibleEntries; sections = groupBy, ChipSectionKey>(unpinnedMapEntries, (kv) { @@ -134,12 +133,10 @@ class AlbumListPage extends StatelessWidget { if (!hasImage && hasVideo) return MimeTypeSectionKey.videos(context); return MimeTypeSectionKey.mixed(context); }); - break; case AlbumChipGroupFactor.volume: sections = groupBy, ChipSectionKey>(unpinnedMapEntries, (kv) { return StorageVolumeSectionKey(context, androidFileUtils.getStorageVolume(kv.filter.album)); }); - break; case AlbumChipGroupFactor.none: return { if (sortedMapEntries.isNotEmpty) diff --git a/lib/widgets/filter_grids/common/action_delegates/album_set.dart b/lib/widgets/filter_grids/common/action_delegates/album_set.dart index 7c46687a4..28894923c 100644 --- a/lib/widgets/filter_grids/common/action_delegates/album_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/album_set.dart @@ -147,25 +147,19 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with // general case ChipSetAction.createAlbum: _createAlbum(context, locked: false); - break; case ChipSetAction.createVault: _createAlbum(context, locked: true); - break; // single/multiple filters case ChipSetAction.delete: _delete(context, filters); - break; case ChipSetAction.lockVault: lockFilters(filters); browse(context); - break; // single filter case ChipSetAction.rename: _rename(context, filters.first); - break; case ChipSetAction.configureVault: _configureVault(context, filters.first); - break; default: break; } diff --git a/lib/widgets/filter_grids/common/action_delegates/chip.dart b/lib/widgets/filter_grids/common/action_delegates/chip.dart index b5fe5b64a..5d3760a43 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip.dart @@ -40,22 +40,16 @@ class ChipActionDelegate with FeedbackMixin, VaultAwareMixin { switch (action) { case ChipAction.goToAlbumPage: _goTo(context, filter, AlbumListPage.routeName, (context) => const AlbumListPage()); - break; case ChipAction.goToCountryPage: _goTo(context, filter, CountryListPage.routeName, (context) => const CountryListPage()); - break; case ChipAction.goToPlacePage: _goTo(context, filter, PlaceListPage.routeName, (context) => const PlaceListPage()); - break; case ChipAction.goToTagPage: _goTo(context, filter, TagListPage.routeName, (context) => const TagListPage()); - break; case ChipAction.reverse: ReverseFilterNotification(filter).dispatch(context); - break; case ChipAction.hide: _hide(context, filter); - break; case ChipAction.lockVault: if (filter is AlbumFilter) { lockFilters({filter}); diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index 111dd9960..4f4a8b92d 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -164,48 +164,36 @@ abstract class ChipSetActionDelegate with FeedbackMi // general case ChipSetAction.configureView: configureView(context); - break; case ChipSetAction.select: context.read>>().select(); - break; case ChipSetAction.selectAll: context.read>>().addToSelection(allItems); - break; case ChipSetAction.selectNone: context.read>>().clearSelection(); - break; // browsing case ChipSetAction.search: _goToSearch(context); - break; case ChipSetAction.toggleTitleSearch: context.read().toggle(); - break; case ChipSetAction.createAlbum: case ChipSetAction.createVault: break; // browsing or selecting case ChipSetAction.map: _goToMap(context, filters); - break; case ChipSetAction.slideshow: _goToSlideshow(context, filters); - break; case ChipSetAction.stats: _goToStats(context, filters); - break; // selecting (single/multiple filters) case ChipSetAction.hide: _hide(context, filters); - break; case ChipSetAction.pin: settings.pinnedFilters = settings.pinnedFilters..addAll(filters); browse(context); - break; case ChipSetAction.unpin: settings.pinnedFilters = settings.pinnedFilters..removeAll(filters); browse(context); - break; case ChipSetAction.delete: case ChipSetAction.lockVault: case ChipSetAction.showCountryStates: @@ -213,7 +201,6 @@ abstract class ChipSetActionDelegate with FeedbackMi // selecting (single filter) case ChipSetAction.setCover: _setCover(context, filters.first); - break; case ChipSetAction.rename: case ChipSetAction.configureVault: break; diff --git a/lib/widgets/filter_grids/common/action_delegates/country_set.dart b/lib/widgets/filter_grids/common/action_delegates/country_set.dart index 0f3cc66dc..669bb67d0 100644 --- a/lib/widgets/filter_grids/common/action_delegates/country_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/country_set.dart @@ -87,7 +87,6 @@ class CountryChipSetActionDelegate extends ChipSetActionDelegate case ChipSetAction.showCountryStates: _showStates(context, filters); browse(context); - break; default: break; } diff --git a/lib/widgets/filter_grids/common/action_delegates/tag_set.dart b/lib/widgets/filter_grids/common/action_delegates/tag_set.dart index d669b6fab..6c9e2324d 100644 --- a/lib/widgets/filter_grids/common/action_delegates/tag_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/tag_set.dart @@ -70,7 +70,6 @@ class TagChipSetActionDelegate extends ChipSetActionDelegate { // single/multiple filters case ChipSetAction.delete: _delete(context, filters); - break; default: break; } diff --git a/lib/widgets/filter_grids/common/app_bar.dart b/lib/widgets/filter_grids/common/app_bar.dart index 7c752c228..435576e71 100644 --- a/lib/widgets/filter_grids/common/app_bar.dart +++ b/lib/widgets/filter_grids/common/app_bar.dart @@ -61,10 +61,8 @@ class FilterGridAppBar().enabled, isMenuItem: true, ); - break; default: child = MenuRow(text: action.getText(context), icon: action.getIcon()); - break; } return PopupMenuItem( @@ -180,7 +178,7 @@ class _FilterGridAppBarState().textScaleFactor; + final textScaleFactor = MediaQuery.textScaleFactorOf(context); double height = kToolbarHeight * textScaleFactor; if (settings.useTvLayout) { height += CaptionedButton.getTelevisionButtonHeight(context); diff --git a/lib/widgets/filter_grids/common/covered_filter_chip.dart b/lib/widgets/filter_grids/common/covered_filter_chip.dart index a2e066edf..d1fa7f60c 100644 --- a/lib/widgets/filter_grids/common/covered_filter_chip.dart +++ b/lib/widgets/filter_grids/common/covered_filter_chip.dart @@ -111,26 +111,22 @@ class CoveredFilterChip extends StatelessWidget { // album filters themselves do not change, but decoration derived from it does chipKey = ValueKey(appInventory.areAppNamesReadyNotifier.value); } + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return AvesFilterChip( key: chipKey, filter: _filter, showText: showText, showGenericIcon: false, decoration: AvesFilterDecoration( - widget: Selector( - selector: (context, mq) => mq.textScaleFactor, - builder: (context, textScaleFactor, child) { - return Padding( - padding: EdgeInsets.only( - bottom: infoHeight( - extent: extent, - textScaleFactor: textScaleFactor, - showText: showText, - ), - ), - child: child, - ); - }, + radius: radius(extent), + widget: Padding( + padding: EdgeInsets.only( + bottom: infoHeight( + extent: extent, + textScaleFactor: textScaleFactor, + showText: showText, + ), + ), child: entry == null ? StreamBuilder?>( stream: covers.colorChangeStream.where((event) => event == null || event.contains(_filter)), @@ -159,9 +155,9 @@ class CoveredFilterChip extends StatelessWidget { : ThumbnailImage( entry: entry, extent: thumbnailExtent, + devicePixelRatio: MediaQuery.devicePixelRatioOf(context), ), ), - radius: radius(extent), ), banner: banner, details: showText ? _buildDetails(context, source, _filter) : null, diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index 39567170b..7daaca92a 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -86,28 +86,23 @@ class FilterGridPage extends StatelessWidget { start: !useTvLayout, top: false, bottom: false, - child: Selector( - selector: (context, mq) => mq.padding.top, - builder: (context, mqPaddingTop, child) { - return ValueListenableBuilder( - valueListenable: appBarHeightNotifier, - builder: (context, appBarHeight, child) { - return _FilterGrid( - // key is expected by test driver - key: const Key('filter-grid'), - settingsRouteKey: settingsRouteKey, - appBar: appBar, - appBarHeight: mqPaddingTop + appBarHeight, - sections: sections, - newFilters: newFilters, - sortFactor: sortFactor, - showHeaders: showHeaders, - selectable: selectable, - applyQuery: applyQuery, - emptyBuilder: emptyBuilder, - heroType: heroType, - ); - }, + child: ValueListenableBuilder( + valueListenable: appBarHeightNotifier, + builder: (context, appBarHeight, child) { + return _FilterGrid( + // key is expected by test driver + key: const Key('filter-grid'), + settingsRouteKey: settingsRouteKey, + appBar: appBar, + appBarHeight: MediaQuery.paddingOf(context).top + appBarHeight, + sections: sections, + newFilters: newFilters, + sortFactor: sortFactor, + showHeaders: showHeaders, + selectable: selectable, + applyQuery: applyQuery, + emptyBuilder: emptyBuilder, + heroType: heroType, ); }, ), @@ -332,80 +327,76 @@ class _FilterGridContentState extends State<_FilterG // do not listen for animation delay change final target = context.read().staggeredAnimationPageTarget; final tileAnimationDelay = context.read().getTileAnimationDelay(target); - return Selector( - selector: (context, mq) => mq.textScaleFactor, - builder: (context, textScaleFactor, child) { - final tileHeight = CoveredFilterChip.tileHeight( - extent: thumbnailExtent, - textScaleFactor: textScaleFactor, - showText: tileLayout != TileLayout.list, - ); - return GridTheme( - extent: thumbnailExtent, - child: FilterListDetailsTheme( - extent: thumbnailExtent, - child: AnimatedBuilder( - animation: vaults, - builder: (context, child) { - return SectionedFilterListLayoutProvider( - sections: visibleSections, - showHeaders: widget.showHeaders, - selectable: widget.selectable, - tileLayout: tileLayout, - scrollableWidth: scrollableWidth, - columnCount: columnCount, - spacing: tileSpacing, - horizontalPadding: horizontalPadding, - tileWidth: thumbnailExtent, - tileHeight: tileHeight, - tileBuilder: (gridItem, tileSize) { - final extent = tileSize.shortestSide; - final tile = InteractiveFilterTile( - gridItem: gridItem, - chipExtent: extent, - thumbnailExtent: extent, - tileLayout: tileLayout, - banner: _getFilterBanner(context, gridItem.filter), - heroType: widget.heroType, - ); - if (!settings.useTvLayout) return tile; - return Focus( - onFocusChange: (focused) { - if (focused) { - _focusedItemNotifier.value = gridItem; - } else if (_focusedItemNotifier.value == gridItem) { - _focusedItemNotifier.value = null; - } - }, - child: ValueListenableBuilder?>( - valueListenable: _focusedItemNotifier, - builder: (context, focusedItem, child) { - return AnimatedScale( - scale: focusedItem == gridItem ? 1 : .9, - curve: Curves.fastOutSlowIn, - duration: context.select((v) => v.tvImageFocusAnimation), - child: child!, - ); - }, - child: tile, - ), - ); + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final tileHeight = CoveredFilterChip.tileHeight( + extent: thumbnailExtent, + textScaleFactor: textScaleFactor, + showText: tileLayout != TileLayout.list, + ); + return GridTheme( + extent: thumbnailExtent, + child: FilterListDetailsTheme( + extent: thumbnailExtent, + child: AnimatedBuilder( + animation: vaults, + builder: (context, child) { + return SectionedFilterListLayoutProvider( + sections: visibleSections, + showHeaders: widget.showHeaders, + selectable: widget.selectable, + tileLayout: tileLayout, + scrollableWidth: scrollableWidth, + columnCount: columnCount, + spacing: tileSpacing, + horizontalPadding: horizontalPadding, + tileWidth: thumbnailExtent, + tileHeight: tileHeight, + tileBuilder: (gridItem, tileSize) { + final extent = tileSize.shortestSide; + final tile = InteractiveFilterTile( + gridItem: gridItem, + chipExtent: extent, + thumbnailExtent: extent, + tileLayout: tileLayout, + banner: _getFilterBanner(context, gridItem.filter), + heroType: widget.heroType, + ); + if (!settings.useTvLayout) return tile; + + return Focus( + onFocusChange: (focused) { + if (focused) { + _focusedItemNotifier.value = gridItem; + } else if (_focusedItemNotifier.value == gridItem) { + _focusedItemNotifier.value = null; + } }, - tileAnimationDelay: tileAnimationDelay, - coverRatioResolver: (item) { - final coverEntry = source.coverEntry(item.filter) ?? item.entry; - return coverEntry?.displayAspectRatio ?? 1; - }, - child: child!, + child: ValueListenableBuilder?>( + valueListenable: _focusedItemNotifier, + builder: (context, focusedItem, child) { + return AnimatedScale( + scale: focusedItem == gridItem ? 1 : .9, + curve: Curves.fastOutSlowIn, + duration: context.select((v) => v.tvImageFocusAnimation), + child: child!, + ); + }, + child: tile, + ), ); }, - child: child, - ), - ), - ); - }, - child: child, + tileAnimationDelay: tileAnimationDelay, + coverRatioResolver: (item) { + final coverEntry = source.coverEntry(item.filter) ?? item.entry; + return coverEntry?.displayAspectRatio ?? 1; + }, + child: child!, + ); + }, + child: child, + ), + ), ); }, child: child, @@ -579,7 +570,7 @@ class _FilterScaler extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = context.select((mq) => mq.textScaleFactor); + final textScaleFactor = MediaQuery.textScaleFactorOf(context); final metrics = context.select>((v) => Tuple2(v.spacing, v.horizontalPadding)); final tileSpacing = metrics.item1; final horizontalPadding = metrics.item2; diff --git a/lib/widgets/filter_grids/common/filter_nav_page.dart b/lib/widgets/filter_grids/common/filter_nav_page.dart index b2a156655..864bef00d 100644 --- a/lib/widgets/filter_grids/common/filter_nav_page.dart +++ b/lib/widgets/filter_grids/common/filter_nav_page.dart @@ -76,22 +76,18 @@ class FilterNavigationPage MapEntry(filter, source.count(filter)))); filtersWithCount.sort(compareFiltersByEntryCount); filters = filtersWithCount.map((kv) => kv.key).toSet(); allMapEntries = toGridItem(source, filters); - break; case ChipSortFactor.size: final filtersWithSize = List.of(filters.map((filter) => MapEntry(filter, source.size(filter)))); filtersWithSize.sort(compareFiltersBySize); filters = filtersWithSize.map((kv) => kv.key).toSet(); allMapEntries = toGridItem(source, filters); - break; } if (reverse) { allMapEntries = allMapEntries.reversed.toList(); diff --git a/lib/widgets/filter_grids/common/filter_tile.dart b/lib/widgets/filter_grids/common/filter_tile.dart index 4ac473b8c..b9b1b64f4 100644 --- a/lib/widgets/filter_grids/common/filter_tile.dart +++ b/lib/widgets/filter_grids/common/filter_tile.dart @@ -65,10 +65,8 @@ class _InteractiveFilterTileState extends State(filter); - break; case AppMode.pickMediaInternal: case AppMode.screenSaver: case AppMode.setWallpaper: diff --git a/lib/widgets/filter_grids/common/list_details.dart b/lib/widgets/filter_grids/common/list_details.dart index 37e6224c4..872fef703 100644 --- a/lib/widgets/filter_grids/common/list_details.dart +++ b/lib/widgets/filter_grids/common/list_details.dart @@ -86,7 +86,7 @@ class FilterListDetails extends StatelessWidget { Widget _buildDateRow(BuildContext context, FilterListDetailsThemeData detailsTheme, bool hasTitleLeading) { final locale = context.l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry?.bestDate; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; diff --git a/lib/widgets/filter_grids/common/query_bar.dart b/lib/widgets/filter_grids/common/query_bar.dart index 4f861b861..a6a09228b 100644 --- a/lib/widgets/filter_grids/common/query_bar.dart +++ b/lib/widgets/filter_grids/common/query_bar.dart @@ -17,7 +17,7 @@ class FilterQueryBar extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = context.select((mq) => mq.textScaleFactor); + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return Container( height: getPreferredHeight(textScaleFactor), alignment: Alignment.topCenter, diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index f2ea00c12..fd3258664 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -129,10 +129,8 @@ class _HomePageState extends State { break; case WidgetOpenPage.collection: _initialFilters = settings.getWidgetCollectionFilters(widgetId); - break; case WidgetOpenPage.viewer: uri = settings.getWidgetUri(widgetId); - break; } unawaited(WidgetService.update(widgetId)); } else { @@ -148,7 +146,6 @@ class _HomePageState extends State { appMode = AppMode.view; } } - break; case actionPickItems: // TODO TLAD apply pick mimetype(s) // some apps define multiple types, separated by a space (maybe other signs too, like `,` `;`?) @@ -156,32 +153,25 @@ class _HomePageState extends State { final multiple = intentData[intentDataKeyAllowMultiple] ?? false; debugPrint('pick mimeType=$pickMimeTypes multiple=$multiple'); appMode = multiple ? AppMode.pickMultipleMediaExternal : AppMode.pickSingleMediaExternal; - break; case actionPickCollectionFilters: appMode = AppMode.pickCollectionFiltersExternal; - break; case actionScreenSaver: appMode = AppMode.screenSaver; _initialRouteName = ScreenSaverPage.routeName; - break; case actionScreenSaverSettings: _initialRouteName = ScreenSaverSettingsPage.routeName; - break; case actionSearch: _initialRouteName = SearchPage.routeName; _initialSearchQuery = intentData[intentDataKeyQuery]; - break; case actionSetWallpaper: appMode = AppMode.setWallpaper; _viewerEntry = await _initViewerEntry( uri: intentData[intentDataKeyUri], mimeType: intentData[intentDataKeyMimeType], ); - break; case actionWidgetSettings: _initialRouteName = HomeWidgetSettingsPage.routeName; _widgetId = intentData[intentDataKeyWidgetId] ?? 0; - break; default: // do not use 'route' as extra key, as the Flutter framework acts on it final extraRoute = intentData[intentDataKeyPage]; @@ -210,13 +200,11 @@ class _HomePageState extends State { loadTopEntriesFirst: settings.homePage == HomePageSetting.collection, canAnalyze: !safeMode, ); - break; case AppMode.screenSaver: final source = context.read(); await source.init( canAnalyze: false, ); - break; case AppMode.view: if (_isViewerSourceable(_viewerEntry)) { final directory = _viewerEntry?.directory; @@ -231,10 +219,8 @@ class _HomePageState extends State { } else { await _initViewerEssentials(); } - break; case AppMode.setWallpaper: await _initViewerEssentials(); - break; case AppMode.pickMediaInternal: case AppMode.pickFilterInternal: case AppMode.slideshow: @@ -340,11 +326,9 @@ class _HomePageState extends State { case AppMode.pickSingleMediaExternal: case AppMode.pickMultipleMediaExternal: routeName = CollectionPage.routeName; - break; default: routeName = _initialRouteName ?? settings.homePage.routeName; filters = _initialFilters ?? {}; - break; } Route buildRoute(WidgetBuilder builder) => DirectMaterialPageRoute( settings: RouteSettings(name: routeName), diff --git a/lib/widgets/map/address_row.dart b/lib/widgets/map/address_row.dart index 407e24aab..daeab20ed 100644 --- a/lib/widgets/map/address_row.dart +++ b/lib/widgets/map/address_row.dart @@ -9,7 +9,6 @@ import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'info_row.dart'; @@ -44,12 +43,13 @@ class _MapAddressRowState extends State { @override Widget build(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); return Container( alignment: AlignmentDirectional.centerStart, // addresses can include non-latin scripts with inconsistent line height, // which is especially an issue for relayout/painting of heavy Google map, // so we give extra height to give breathing room to the text and stabilize layout - height: Theme.of(context).textTheme.bodyMedium!.fontSize! * context.select((mq) => mq.textScaleFactor) * 2, + height: Theme.of(context).textTheme.bodyMedium!.fontSize! * textScaleFactor * 2, child: ValueListenableBuilder( valueListenable: _addressLineNotifier, builder: (context, addressLine, child) { diff --git a/lib/widgets/map/date_row.dart b/lib/widgets/map/date_row.dart index 430a731fc..33e5893ca 100644 --- a/lib/widgets/map/date_row.dart +++ b/lib/widgets/map/date_row.dart @@ -6,7 +6,6 @@ import 'package:aves/theme/text.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/map/info_row.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class MapDateRow extends StatelessWidget { final AvesEntry? entry; @@ -19,7 +18,7 @@ class MapDateRow extends StatelessWidget { @override Widget build(BuildContext context) { final locale = context.l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry?.bestDate; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; diff --git a/lib/widgets/map/info_row.dart b/lib/widgets/map/info_row.dart index fc58e1387..2bbb4eb25 100644 --- a/lib/widgets/map/info_row.dart +++ b/lib/widgets/map/info_row.dart @@ -3,7 +3,6 @@ import 'package:aves/widgets/map/address_row.dart'; import 'package:aves/widgets/map/date_row.dart'; import 'package:aves_map/aves_map.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class MapInfoRow extends StatelessWidget { final ValueNotifier entryNotifier; @@ -18,12 +17,11 @@ class MapInfoRow extends StatelessWidget { @override Widget build(BuildContext context) { - final orientation = context.select((v) => v.orientation); - return ValueListenableBuilder( valueListenable: entryNotifier, builder: (context, entry, child) { - final content = orientation == Orientation.portrait + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; + final content = isPortrait ? [ Expanded( child: Column( @@ -59,5 +57,8 @@ class MapInfoRow extends StatelessWidget { ); } - static double getIconSize(BuildContext context) => 16.0 * context.select((mq) => mq.textScaleFactor); + static double getIconSize(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + return 16 * textScaleFactor; + } } diff --git a/lib/widgets/map/map_page.dart b/lib/widgets/map/map_page.dart index 63a463d09..665ccc8ca 100644 --- a/lib/widgets/map/map_page.dart +++ b/lib/widgets/map/map_page.dart @@ -247,6 +247,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin controller: _mapController, collectionListenable: openingCollection, entries: openingCollection.sortedEntries, + availableSize: MediaQuery.sizeOf(context), initialCenter: widget.initialEntry?.latLng ?? widget.overlayEntry?.center, isAnimatingNotifier: _isPageAnimatingNotifier, dotLocationNotifier: _dotLocationNotifier, @@ -487,10 +488,8 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin } _mapController.moveTo(location); } - break; case MapClusterAction.removeLocation: await delegate.removeLocation(context, clusterEntries); - break; } } } diff --git a/lib/widgets/map/scroller.dart b/lib/widgets/map/scroller.dart index 54c9a1c6b..467503432 100644 --- a/lib/widgets/map/scroller.dart +++ b/lib/widgets/map/scroller.dart @@ -7,7 +7,6 @@ import 'package:aves/widgets/common/identity/empty.dart'; import 'package:aves/widgets/common/thumbnail/scroller.dart'; import 'package:aves/widgets/map/info_row.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class MapEntryScroller extends StatefulWidget { final ValueNotifier regionCollectionNotifier; @@ -71,30 +70,27 @@ class _MapEntryScrollerState extends State { child: MapInfoRow(entryNotifier: _infoEntryNotifier), ), const SizedBox(height: 8), - Selector( - selector: (context, mq) => mq.size.width, - builder: (context, mqWidth, child) => ValueListenableBuilder( - valueListenable: widget.regionCollectionNotifier, - builder: (context, regionCollection, child) { - return AnimatedBuilder( - // update when entries are added/removed - animation: regionCollection ?? ChangeNotifier(), - builder: (context, child) { - final regionEntries = regionCollection?.sortedEntries ?? []; - return ThumbnailScroller( - availableWidth: mqWidth, - entryCount: regionEntries.length, - entryBuilder: (index) => index < regionEntries.length ? regionEntries[index] : null, - indexNotifier: widget.selectedIndexNotifier, - onTap: widget.onTap, - heroTagger: (entry) => Object.hashAll([regionCollection?.id, entry.id]), - highlightable: true, - showLocation: false, - ); - }, - ); - }, - ), + ValueListenableBuilder( + valueListenable: widget.regionCollectionNotifier, + builder: (context, regionCollection, child) { + return AnimatedBuilder( + // update when entries are added/removed + animation: regionCollection ?? ChangeNotifier(), + builder: (context, child) { + final regionEntries = regionCollection?.sortedEntries ?? []; + return ThumbnailScroller( + availableWidth: MediaQuery.sizeOf(context).width, + entryCount: regionEntries.length, + entryBuilder: (index) => index < regionEntries.length ? regionEntries[index] : null, + indexNotifier: widget.selectedIndexNotifier, + onTap: widget.onTap, + heroTagger: (entry) => Object.hashAll([regionCollection?.id, entry.id]), + highlightable: true, + showLocation: false, + ); + }, + ); + }, ), ], ), diff --git a/lib/widgets/navigation/drawer/app_drawer.dart b/lib/widgets/navigation/drawer/app_drawer.dart index 8bb449524..37ac737cf 100644 --- a/lib/widgets/navigation/drawer/app_drawer.dart +++ b/lib/widgets/navigation/drawer/app_drawer.dart @@ -85,6 +85,7 @@ class _AppDrawerState extends State { child: Selector( selector: (context, mq) => mq.effectiveBottomPadding, builder: (context, mqPaddingBottom, child) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); final iconTheme = IconTheme.of(context); return SingleChildScrollView( controller: _scrollController, @@ -93,7 +94,7 @@ class _AppDrawerState extends State { padding: EdgeInsets.only(bottom: mqPaddingBottom), child: IconTheme( data: iconTheme.copyWith( - size: iconTheme.size! * MediaQuery.textScaleFactorOf(context), + size: iconTheme.size! * textScaleFactor, ), child: Column( children: drawerItems, @@ -238,25 +239,21 @@ class _AppDrawerState extends State { stream: source.eventBus.on(), builder: (context, _) => Text('${source.rawAlbums.length}'), ); - break; case CountryListPage.routeName: trailing = StreamBuilder( stream: source.eventBus.on(), builder: (context, _) => Text('${source.sortedCountries.length}'), ); - break; case PlaceListPage.routeName: trailing = StreamBuilder( stream: source.eventBus.on(), builder: (context, _) => Text('${source.sortedPlaces.length}'), ); - break; case TagListPage.routeName: trailing = StreamBuilder( stream: source.eventBus.on(), builder: (context, _) => Text('${source.sortedTags.length}'), ); - break; } return PageNavTile( diff --git a/lib/widgets/navigation/nav_bar/floating.dart b/lib/widgets/navigation/nav_bar/floating.dart index 6ebb4bfdd..85d729eb3 100644 --- a/lib/widgets/navigation/nav_bar/floating.dart +++ b/lib/widgets/navigation/nav_bar/floating.dart @@ -113,10 +113,8 @@ class _FloatingNavBarState extends State with SingleTickerProvid switch (event) { case DraggableScrollbarEvent.dragStart: _isDragging = true; - break; case DraggableScrollbarEvent.dragEnd: _isDragging = false; - break; } } } diff --git a/lib/widgets/settings/app_export/items.dart b/lib/widgets/settings/app_export/items.dart index 3a94614b4..5ee21faa5 100644 --- a/lib/widgets/settings/app_export/items.dart +++ b/lib/widgets/settings/app_export/items.dart @@ -34,13 +34,10 @@ extension ExtraAppExportItem on AppExportItem { switch (this) { case AppExportItem.covers: covers.import(jsonMap, source); - break; case AppExportItem.favourites: favourites.import(jsonMap, source); - break; case AppExportItem.settings: await settings.import(jsonMap); - break; } } } diff --git a/lib/widgets/settings/common/quick_actions/editor_page.dart b/lib/widgets/settings/common/quick_actions/editor_page.dart index 0bec2c037..4ba51136c 100644 --- a/lib/widgets/settings/common/quick_actions/editor_page.dart +++ b/lib/widgets/settings/common/quick_actions/editor_page.dart @@ -317,13 +317,10 @@ class _QuickActionEditorBodyState extends State { case _PickerAction.toggleHiddenView: settings.filePickerShowHiddenFiles = !showHidden; setState(() {}); - break; } }, ), diff --git a/lib/widgets/settings/settings_mobile_page.dart b/lib/widgets/settings/settings_mobile_page.dart index 2950b0148..354e613f0 100644 --- a/lib/widgets/settings/settings_mobile_page.dart +++ b/lib/widgets/settings/settings_mobile_page.dart @@ -124,7 +124,6 @@ class _SettingsMobilePageState extends State with FeedbackMi showFeedback(context, context.l10n.genericFailureFeedback); } } - break; case SettingsAction.import: // specifying the JSON MIME type to restrict openable files is correct in theory, // but older devices (e.g. SM-P580, API 27) that do not recognize JSON files as such would filter them out @@ -172,7 +171,6 @@ class _SettingsMobilePageState extends State with FeedbackMi showFeedback(context, context.l10n.genericFailureFeedback); } } - break; } } diff --git a/lib/widgets/settings/thumbnails/overlay.dart b/lib/widgets/settings/thumbnails/overlay.dart index 3f8be2e1d..d136ddbe1 100644 --- a/lib/widgets/settings/thumbnails/overlay.dart +++ b/lib/widgets/settings/thumbnails/overlay.dart @@ -89,7 +89,10 @@ class ThumbnailOverlayPage extends StatelessWidget { ); } - static double _getIconSize(BuildContext context) => IconTheme.of(context).size! * MediaQuery.textScaleFactorOf(context); + static double _getIconSize(BuildContext context) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); + return IconTheme.of(context).size! * textScaleFactor; + } static Color _getIconColor(BuildContext context) => context.select((v) => v.neutral); diff --git a/lib/widgets/stats/date/histogram.dart b/lib/widgets/stats/date/histogram.dart index 772c07310..69acdcc41 100644 --- a/lib/widgets/stats/date/histogram.dart +++ b/lib/widgets/stats/date/histogram.dart @@ -68,13 +68,10 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi switch (_level) { case DateLevel.ymd: normalizeDate = (v) => DateTime(v.year, v.month, v.day); - break; case DateLevel.ym: normalizeDate = (v) => DateTime(v.year, v.month); - break; default: normalizeDate = (v) => DateTime(v.year); - break; } _firstDate = normalizeDate(firstDate); _lastDate = normalizeDate(lastDate); @@ -118,15 +115,12 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi case DateLevel.ymd: xCount = xRange.inDays; incrementDate = (date) => DateTime(date.year, date.month, date.day + 1); - break; case DateLevel.ym: xCount = (xRange.inDays / 30.5).round(); incrementDate = (date) => DateTime(date.year, date.month + 1); - break; default: xCount = lastDate.year - firstDate.year; incrementDate = (date) => DateTime(date.year + 1); - break; } final yMax = entryCountPerDate.values.reduce(max).toDouble(); final xInterval = yMax / xCount; diff --git a/lib/widgets/viewer/action/entry_action_delegate.dart b/lib/widgets/viewer/action/entry_action_delegate.dart index d4e099a93..d31760d64 100644 --- a/lib/widgets/viewer/action/entry_action_delegate.dart +++ b/lib/widgets/viewer/action/entry_action_delegate.dart @@ -181,61 +181,44 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix switch (action) { case EntryAction.info: ShowInfoPageNotification().dispatch(context); - break; case EntryAction.addShortcut: _addShortcut(context, targetEntry); - break; case EntryAction.copyToClipboard: appService.copyToClipboard(targetEntry.uri, targetEntry.bestTitle).then((success) { showFeedback(context, success ? context.l10n.genericSuccessFeedback : context.l10n.genericFailureFeedback); }); - break; case EntryAction.delete: _delete(context, targetEntry); - break; case EntryAction.restore: _move(context, targetEntry, moveType: MoveType.fromBin); - break; case EntryAction.convert: convert(context, {targetEntry}); - break; case EntryAction.print: EntryPrinter(targetEntry).print(context); - break; case EntryAction.rename: _rename(context, targetEntry); - break; case EntryAction.copy: _move(context, targetEntry, moveType: MoveType.copy); - break; case EntryAction.move: _move(context, targetEntry, moveType: MoveType.move); - break; case EntryAction.share: appService.shareEntries({targetEntry}).then((success) { if (!success) showNoMatchingAppDialog(context); }); - break; case EntryAction.toggleFavourite: targetEntry.toggleFavourite(); - break; // raster case EntryAction.rotateCCW: _rotate(context, targetEntry, clockwise: false); - break; case EntryAction.rotateCW: _rotate(context, targetEntry, clockwise: true); - break; case EntryAction.flip: _flip(context, targetEntry); - break; // vector case EntryAction.viewSource: _goToSourceViewer(context, targetEntry); - break; case EntryAction.lockViewer: const LockViewNotification(locked: true).dispatch(context); - break; // video case EntryAction.videoCaptureFrame: case EntryAction.videoToggleMute: @@ -254,31 +237,25 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix action: action, ).dispatch(context); } - break; case EntryAction.edit: appService.edit(targetEntry.uri, targetEntry.mimeType).then((success) { if (!success) showNoMatchingAppDialog(context); }); - break; case EntryAction.open: appService.open(targetEntry.uri, targetEntry.mimeTypeAnySubtype, forceChooser: true).then((success) { if (!success) showNoMatchingAppDialog(context); }); - break; case EntryAction.openMap: appService.openMap(targetEntry.latLng!).then((success) { if (!success) showNoMatchingAppDialog(context); }); - break; case EntryAction.setAs: appService.setAs(targetEntry.uri, targetEntry.mimeType).then((success) { if (!success) showNoMatchingAppDialog(context); }); - break; // platform case EntryAction.rotateScreen: _rotateScreen(context); - break; // metadata case EntryAction.editDate: case EntryAction.editLocation: @@ -291,11 +268,9 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix case EntryAction.convertMotionPhotoToStillImage: case EntryAction.viewMotionPhotoVideo: _metadataActionDelegate.onActionSelected(context, targetEntry, collection, action); - break; // debug case EntryAction.debug: _goToDebug(context, targetEntry); - break; } } @@ -321,13 +296,11 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix final fields = await embeddedDataService.extractMotionPhotoImage(mainEntry); await _shareMotionPhotoPart(context, fields); } - break; case ShareAction.videoOnly: if (mainEntry.isMotionPhoto) { final fields = await embeddedDataService.extractMotionPhotoVideo(mainEntry); await _shareMotionPhotoPart(context, fields); } - break; } } @@ -379,14 +352,8 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix } Future _rotateScreen(BuildContext context) async { - switch (context.read().orientation) { - case Orientation.landscape: - await windowService.requestOrientation(Orientation.portrait); - break; - case Orientation.portrait: - await windowService.requestOrientation(Orientation.landscape); - break; - } + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; + await windowService.requestOrientation(isPortrait ? Orientation.landscape : Orientation.portrait); } Future _delete(BuildContext context, AvesEntry targetEntry) async { diff --git a/lib/widgets/viewer/action/entry_info_action_delegate.dart b/lib/widgets/viewer/action/entry_info_action_delegate.dart index 33bb488e0..0487d219e 100644 --- a/lib/widgets/viewer/action/entry_info_action_delegate.dart +++ b/lib/widgets/viewer/action/entry_info_action_delegate.dart @@ -99,40 +99,29 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi // general case EntryAction.editDate: await _editDate(context, targetEntry, collection); - break; case EntryAction.editLocation: await _editLocation(context, targetEntry, collection); - break; case EntryAction.editTitleDescription: await _editTitleDescription(context, targetEntry); - break; case EntryAction.editRating: await _editRating(context, targetEntry); - break; case EntryAction.editTags: await _editTags(context, targetEntry); - break; case EntryAction.removeMetadata: await _removeMetadata(context, targetEntry); - break; case EntryAction.exportMetadata: await _exportMetadata(context, targetEntry); - break; // GeoTIFF case EntryAction.showGeoTiffOnMap: await _showGeoTiffOnMap(context, targetEntry, collection); - break; // motion photo case EntryAction.convertMotionPhotoToStillImage: await _convertMotionPhotoToStillImage(context, targetEntry); - break; case EntryAction.viewMotionPhotoVideo: OpenEmbeddedDataNotification.motionPhotoVideo().dispatch(context); - break; // debug case EntryAction.debug: _goToDebug(context, targetEntry); - break; default: break; } @@ -262,6 +251,7 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi final mappedGeoTiff = MappedGeoTiff( info: info, entry: targetEntry, + devicePixelRatio: View.of(context).devicePixelRatio, ); if (!mappedGeoTiff.canOverlay) return; diff --git a/lib/widgets/viewer/action/video_action_delegate.dart b/lib/widgets/viewer/action/video_action_delegate.dart index bff1f5412..e9a9d454f 100644 --- a/lib/widgets/viewer/action/video_action_delegate.dart +++ b/lib/widgets/viewer/action/video_action_delegate.dart @@ -45,33 +45,24 @@ class VideoActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix switch (action) { case EntryAction.videoCaptureFrame: await _captureFrame(context, entry, controller); - break; case EntryAction.videoToggleMute: await controller.mute(!controller.isMuted); - break; case EntryAction.videoSelectStreams: await _showStreamSelectionDialog(context, controller); - break; case EntryAction.videoSetSpeed: await _showSpeedDialog(context, controller); - break; case EntryAction.videoSettings: await _showSettings(context, controller); - break; case EntryAction.videoTogglePlay: await _togglePlayPause(context, controller); - break; case EntryAction.videoReplay10: await controller.seekTo(controller.currentPosition - 10000); - break; case EntryAction.videoSkip10: await controller.seekTo(controller.currentPosition + 10000); - break; case EntryAction.openVideo: await appService.open(entry.uri, entry.mimeTypeAnySubtype, forceChooser: false).then((success) { if (!success) showNoMatchingAppDialog(context); }); - break; default: throw UnsupportedError('$action is not a video action'); } diff --git a/lib/widgets/viewer/entry_horizontal_pager.dart b/lib/widgets/viewer/entry_horizontal_pager.dart index c491edad4..c6a11a9f2 100644 --- a/lib/widgets/viewer/entry_horizontal_pager.dart +++ b/lib/widgets/viewer/entry_horizontal_pager.dart @@ -12,7 +12,6 @@ import 'package:aves/widgets/viewer/page_entry_builder.dart'; import 'package:aves/widgets/viewer/visual/entry_page_view.dart'; import 'package:aves_magnifier/aves_magnifier.dart'; import 'package:collection/collection.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -57,7 +56,7 @@ class _MultiEntryScrollerState extends State with AutomaticK scrollDirection: Axis.horizontal, controller: pageController, physics: MagnifierScrollerPhysics( - gestureSettings: context.select((mq) => mq.gestureSettings), + gestureSettings: MediaQuery.gestureSettingsOf(context), parent: const BouncingScrollPhysics(), ), onPageChanged: widget.onPageChanged, diff --git a/lib/widgets/viewer/entry_vertical_pager.dart b/lib/widgets/viewer/entry_vertical_pager.dart index f48286da9..7e6cd8129 100644 --- a/lib/widgets/viewer/entry_vertical_pager.dart +++ b/lib/widgets/viewer/entry_vertical_pager.dart @@ -22,7 +22,6 @@ import 'package:aves/widgets/viewer/multipage/conductor.dart'; import 'package:aves/widgets/viewer/video/conductor.dart'; import 'package:aves_magnifier/aves_magnifier.dart'; import 'package:aves_model/aves_model.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; @@ -187,7 +186,7 @@ class _ViewerVerticalPageViewState extends State { scrollDirection: Axis.vertical, controller: widget.verticalPager, physics: MagnifierScrollerPhysics( - gestureSettings: context.select((mq) => mq.gestureSettings), + gestureSettings: MediaQuery.gestureSettingsOf(context), parent: SpringyScrollPhysics( spring: ViewerVerticalPageView.spring, ), @@ -384,13 +383,10 @@ class _ViewerVerticalPageViewState extends State { switch (intent.type) { case TvPlayPauseType.play: toggle = !controller.isPlaying; - break; case TvPlayPauseType.pause: toggle = controller.isPlaying; - break; case TvPlayPauseType.toggle: toggle = true; - break; } if (toggle) { VideoActionNotification( diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index f5c601b0d..03093cb45 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -286,14 +286,11 @@ class _EntryViewerStackState extends State with EntryViewContr switch (AvesApp.lifecycleStateNotifier.value) { case AppLifecycleState.inactive: _onAppInactive(); - break; case AppLifecycleState.paused: case AppLifecycleState.detached: pauseVideoControllers(); - break; case AppLifecycleState.resumed: availability.onResume(); - break; } } @@ -525,19 +522,16 @@ class _EntryViewerStackState extends State with EntryViewContr switch (notification.moveType) { case MoveType.move: _onEntryRemoved(context, entries); - break; case MoveType.toBin: if (!isBin) { _onEntryRemoved(context, entries); } - break; case MoveType.fromBin: if (isBin) { _onEntryRemoved(context, entries); } else { _onEntryRestored(entries); } - break; case MoveType.copy: case MoveType.export: break; @@ -639,15 +633,12 @@ class _EntryViewerStackState extends State with EntryViewContr case transitionPage: dismissFeedback(context); _popVisual(); - break; case imagePage: reportService.log('Nav move to Image page'); - break; case infoPage: reportService.log('Nav move to Info page'); // prevent hero when viewer is offscreen _heroInfoNotifier.value = null; - break; } } @@ -821,10 +812,8 @@ class _EntryViewerStackState extends State with EntryViewContr case MaxBrightness.never: case MaxBrightness.viewerOnly: await ScreenBrightness().resetScreenBrightness(); - break; case MaxBrightness.always: await ScreenBrightness().setScreenBrightness(1); - break; } if (settings.keepScreenOn == KeepScreenOn.viewerOnly) { await windowService.keepScreenOn(false); @@ -843,8 +832,7 @@ class _EntryViewerStackState extends State with EntryViewContr final entrySize = videoController.entry.displaySize; final aspectRatio = Rational(entrySize.width.round(), entrySize.height.round()); - final mq = context.read(); - final viewSize = mq.size * mq.devicePixelRatio; + final viewSize = MediaQuery.sizeOf(context) * MediaQuery.devicePixelRatioOf(context); final fittedSize = applyBoxFit(BoxFit.contain, entrySize, viewSize).destination; final sourceRectHint = Rectangle( ((viewSize.width - fittedSize.width) / 2).round(), diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index db32c6994..ec7de8dde 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -202,21 +202,18 @@ class _BasicSectionState extends State { onChooserValue: (rating) => actionDelegate.quickRate(context, entry, rating), onPressed: onPressed, ); - break; case EntryAction.editTags: button = TagButton( blurred: false, onChooserValue: (filter) => actionDelegate.quickTag(context, entry, filter), onPressed: onPressed, ); - break; default: button = IconButton( icon: action.getIcon(), onPressed: onPressed, tooltip: action.getText(context), ); - break; } return Stack( children: [ @@ -306,7 +303,7 @@ class _BasicInfoState extends State<_BasicInfo> { final l10n = context.l10n; final infoUnknown = l10n.viewerInfoUnknown; final locale = l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); // TODO TLAD line break on all characters for the following fields when this is fixed: https://github.com/flutter/flutter/issues/61081 // inserting ZWSP (\u200B) between characters does help, but it messes with width and height computation (another Flutter issue) diff --git a/lib/widgets/viewer/info/embedded/embedded_data_opener.dart b/lib/widgets/viewer/info/embedded/embedded_data_opener.dart index 287a712fb..54faa81f6 100644 --- a/lib/widgets/viewer/info/embedded/embedded_data_opener.dart +++ b/lib/widgets/viewer/info/embedded/embedded_data_opener.dart @@ -42,16 +42,12 @@ class EmbeddedDataOpener extends StatelessWidget with FeedbackMixin { switch (notification.source) { case EmbeddedDataSource.googleDevice: fields = await embeddedDataService.extractGoogleDeviceItem(entry, notification.dataUri!); - break; case EmbeddedDataSource.motionPhotoVideo: fields = await embeddedDataService.extractMotionPhotoVideo(entry); - break; case EmbeddedDataSource.videoCover: fields = await embeddedDataService.extractVideoEmbeddedPicture(entry); - break; case EmbeddedDataSource.xmp: fields = await embeddedDataService.extractXmpDataProp(entry, notification.props, notification.mimeType); - break; } if (!fields.containsKey('mimeType') || !fields.containsKey('uri')) { showFeedback(context, context.l10n.viewerInfoOpenEmbeddedFailureFeedback); diff --git a/lib/widgets/viewer/info/info_page.dart b/lib/widgets/viewer/info/info_page.dart index 440427f9f..1529e11bb 100644 --- a/lib/widgets/viewer/info/info_page.dart +++ b/lib/widgets/viewer/info/info_page.dart @@ -61,39 +61,34 @@ class _InfoPageState extends State { bottom: false, child: NotificationListener( onNotification: _handleTopScroll, - child: Selector( - selector: (context, mq) => mq.size.width, - builder: (context, mqWidth, child) { - return ValueListenableBuilder( - valueListenable: widget.entryNotifier, - builder: (context, mainEntry, child) { - if (mainEntry == null) return const SizedBox(); + child: ValueListenableBuilder( + valueListenable: widget.entryNotifier, + builder: (context, mainEntry, child) { + if (mainEntry == null) return const SizedBox(); - final isSelecting = context.select?, bool>((v) => v?.isSelecting ?? false); - Widget _buildContent({AvesEntry? pageEntry}) { - final targetEntry = pageEntry ?? mainEntry; - return EmbeddedDataOpener( - enabled: !isSelecting, - entry: targetEntry, - child: _InfoPageContent( - collection: widget.collection, - entry: targetEntry, - isScrollingNotifier: widget.isScrollingNotifier, - scrollController: _scrollController, - split: mqWidth > splitScreenWidthThreshold, - goToViewer: _goToViewer, - ), - ); - } + final isSelecting = context.select?, bool>((v) => v?.isSelecting ?? false); + Widget _buildContent({AvesEntry? pageEntry}) { + final targetEntry = pageEntry ?? mainEntry; + return EmbeddedDataOpener( + enabled: !isSelecting, + entry: targetEntry, + child: _InfoPageContent( + collection: widget.collection, + entry: targetEntry, + isScrollingNotifier: widget.isScrollingNotifier, + scrollController: _scrollController, + split: MediaQuery.sizeOf(context).width > splitScreenWidthThreshold, + goToViewer: _goToViewer, + ), + ); + } - return mainEntry.isBurst - ? PageEntryBuilder( - multiPageController: context.read().getController(mainEntry), - builder: (pageEntry) => _buildContent(pageEntry: pageEntry), - ) - : _buildContent(); - }, - ); + return mainEntry.isBurst + ? PageEntryBuilder( + multiPageController: context.read().getController(mainEntry), + builder: (pageEntry) => _buildContent(pageEntry: pageEntry), + ) + : _buildContent(); }, ), ), diff --git a/lib/widgets/viewer/info/location_section.dart b/lib/widgets/viewer/info/location_section.dart index 6e5abc3f4..1010fc999 100644 --- a/lib/widgets/viewer/info/location_section.dart +++ b/lib/widgets/viewer/info/location_section.dart @@ -89,6 +89,7 @@ class _LocationSectionState extends State { child: GeoMap( controller: _mapController, entries: [entry], + availableSize: MediaQuery.sizeOf(context), isAnimatingNotifier: widget.isScrollingNotifier, onUserZoomChange: (zoom) => settings.infoMapZoom = zoom.roundToDouble(), onMarkerTap: collection != null && canNavigate ? (location, entry) => _openMapPage(context) : null, diff --git a/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart b/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart index b999e44ce..0fa09df08 100644 --- a/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart +++ b/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart @@ -98,16 +98,13 @@ class MetadataDirTileBody extends StatelessWidget { switch (dirName) { case SvgMetadataService.metadataDirectory: linkHandlers = getSvgLinkHandlers(tags); - break; case MetadataDirectory.coverDirectory: linkHandlers = getVideoCoverLinkHandlers(tags); - break; case MetadataDirectory.geoTiffDirectory: tags = SplayTreeMap.from(tags.map((name, value) { final tag = GeoTiffDirectory.tagForName(name); return MapEntry(name, GeoTiffDirectory.formatValue(tag, value)); })); - break; } children = [ diff --git a/lib/widgets/viewer/info/metadata/metadata_thumbnail.dart b/lib/widgets/viewer/info/metadata/metadata_thumbnail.dart index 77d0407fc..f4d3f2ba5 100644 --- a/lib/widgets/viewer/info/metadata/metadata_thumbnail.dart +++ b/lib/widgets/viewer/info/metadata/metadata_thumbnail.dart @@ -4,7 +4,6 @@ import 'dart:typed_data'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/services/common/services.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class MetadataThumbnails extends StatefulWidget { final AvesEntry entry; @@ -44,7 +43,7 @@ class _MetadataThumbnailsState extends State { children: snapshot.data!.map((bytes) { return Image.memory( bytes, - scale: context.select((mq) => mq.devicePixelRatio), + scale: MediaQuery.devicePixelRatioOf(context), ); }).toList(), ), diff --git a/lib/widgets/viewer/overlay/bottom.dart b/lib/widgets/viewer/overlay/bottom.dart index d80348978..cb9339f2a 100644 --- a/lib/widgets/viewer/overlay/bottom.dart +++ b/lib/widgets/viewer/overlay/bottom.dart @@ -20,7 +20,6 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; -import 'package:tuple/tuple.dart'; class ViewerBottomOverlay extends StatefulWidget { final List entries; @@ -297,19 +296,14 @@ class ExtraBottomOverlay extends StatelessWidget { @override Widget build(BuildContext context) { - final mq = context.select>((mq) => Tuple3(mq.size.width, mq.viewInsets, mq.viewPadding)); - final mqWidth = mq.item1; - final mqViewInsets = mq.item2; - final mqViewPadding = mq.item3; - - final viewInsets = this.viewInsets ?? mqViewInsets; - final viewPadding = this.viewPadding ?? mqViewPadding; + final viewInsets = this.viewInsets ?? MediaQuery.viewInsetsOf(context); + final viewPadding = this.viewPadding ?? MediaQuery.viewPaddingOf(context); final safePadding = (viewInsets + viewPadding).copyWith(bottom: 8) + const EdgeInsets.symmetric(horizontal: 8.0); return Padding( padding: safePadding, child: SizedBox( - width: mqWidth - safePadding.horizontal, + width: MediaQuery.sizeOf(context).width - safePadding.horizontal, child: child, ), ); diff --git a/lib/widgets/viewer/overlay/details/date.dart b/lib/widgets/viewer/overlay/details/date.dart index 62abba441..e6e77fb55 100644 --- a/lib/widgets/viewer/overlay/details/date.dart +++ b/lib/widgets/viewer/overlay/details/date.dart @@ -9,7 +9,6 @@ import 'package:aves/widgets/viewer/multipage/controller.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:decorated_icon/decorated_icon.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class OverlayDateRow extends StatelessWidget { final AvesEntry entry; @@ -24,7 +23,7 @@ class OverlayDateRow extends StatelessWidget { @override Widget build(BuildContext context) { final locale = context.l10n.localeName; - final use24hour = context.select((v) => v.alwaysUse24HourFormat); + final use24hour = MediaQuery.alwaysUse24HourFormatOf(context); final date = entry.bestDate; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable; diff --git a/lib/widgets/viewer/overlay/details/details.dart b/lib/widgets/viewer/overlay/details/details.dart index c7b4bba56..b84fc33f4 100644 --- a/lib/widgets/viewer/overlay/details/details.dart +++ b/lib/widgets/viewer/overlay/details/details.dart @@ -150,81 +150,79 @@ class ViewerDetailOverlayContent extends StatelessWidget { @override Widget build(BuildContext context) { + return AnimatedBuilder( + animation: pageEntry.metadataChangeNotifier, + builder: (context, child) => DefaultTextStyle( + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + shadows: shadows(context), + ), + softWrap: false, + overflow: TextOverflow.fade, + maxLines: 1, + child: Padding( + padding: padding, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildRows(context), + ), + ), + ), + ); + } + + List _buildRows(BuildContext context) { final infoMaxWidth = availableWidth - padding.horizontal; final showRatingTags = settings.showOverlayRatingTags; final showShootingDetails = settings.showOverlayShootingDetails; final showDescription = settings.showOverlayDescription; - return AnimatedBuilder( - animation: pageEntry.metadataChangeNotifier, - builder: (context, child) { - final positionTitle = OverlayPositionTitleRow( - entry: pageEntry, - collectionPosition: position, - multiPageController: multiPageController, - ); - return DefaultTextStyle( - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - shadows: shadows(context), - ), - softWrap: false, - overflow: TextOverflow.fade, - maxLines: 1, - child: Padding( - padding: padding, - child: Selector( - selector: (context, mq) => mq.orientation, - builder: (context, orientation, child) { - final twoColumns = orientation == Orientation.landscape && infoMaxWidth / 2 > _subRowMinWidth; - final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth; - final collapsedShooting = twoColumns && showShootingDetails; - final collapsedLocation = twoColumns && !showShootingDetails; + final isLandscape = MediaQuery.orientationOf(context) == Orientation.landscape; + final twoColumns = isLandscape && infoMaxWidth / 2 > _subRowMinWidth; + final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth; + final collapsedShooting = twoColumns && showShootingDetails; + final collapsedLocation = twoColumns && !showShootingDetails; - final rows = []; - if (positionTitle.isNotEmpty) { - rows.add(OverlayRowExpander( - expandedNotifier: expandedNotifier, - child: positionTitle, - )); - rows.add(const SizedBox(height: _interRowPadding)); - } - if (twoColumns) { - rows.add( - Row( - children: [ - _buildDateSubRow(subRowWidth), - if (collapsedShooting) _buildShootingSubRow(context, subRowWidth), - if (collapsedLocation) _buildLocationSubRow(context, subRowWidth), - ], - ), - ); - } else { - rows.add(_buildDateSubRow(subRowWidth)); - if (showShootingDetails) { - rows.add(_buildShootingFullRow(context, subRowWidth)); - } - } - if (!collapsedLocation) { - rows.add(_buildLocationFullRow(context)); - } - if (showRatingTags) { - rows.add(_buildRatingTagsFullRow(context)); - } - if (showDescription) { - rows.add(_buildDescriptionFullRow(context)); - } - - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: rows, - ); - }, - ), - ), - ); - }, + final positionTitle = OverlayPositionTitleRow( + entry: pageEntry, + collectionPosition: position, + multiPageController: multiPageController, ); + + final rows = []; + if (positionTitle.isNotEmpty) { + rows.add(OverlayRowExpander( + expandedNotifier: expandedNotifier, + child: positionTitle, + )); + rows.add(const SizedBox(height: _interRowPadding)); + } + if (twoColumns) { + rows.add( + Row( + children: [ + _buildDateSubRow(subRowWidth), + if (collapsedShooting) _buildShootingSubRow(context, subRowWidth), + if (collapsedLocation) _buildLocationSubRow(context, subRowWidth), + ], + ), + ); + } else { + rows.add(_buildDateSubRow(subRowWidth)); + if (showShootingDetails) { + rows.add(_buildShootingFullRow(context, subRowWidth)); + } + } + if (!collapsedLocation) { + rows.add(_buildLocationFullRow(context)); + } + if (showRatingTags) { + rows.add(_buildRatingTagsFullRow(context)); + } + if (showDescription) { + rows.add(_buildDescriptionFullRow(context)); + } + return rows; } Widget _buildDateSubRow(double subRowWidth) => SizedBox( diff --git a/lib/widgets/viewer/overlay/details/rating_tags.dart b/lib/widgets/viewer/overlay/details/rating_tags.dart index 8cda1194d..f2a93d3f5 100644 --- a/lib/widgets/viewer/overlay/details/rating_tags.dart +++ b/lib/widgets/viewer/overlay/details/rating_tags.dart @@ -23,13 +23,10 @@ class OverlayRatingTagsRow extends AnimatedWidget { switch (rating) { case -1: ratingString = context.l10n.filterRatingRejectedLabel; - break; case 0: ratingString = ''; - break; default: ratingString = '${'★' * rating}${'☆' * (5 - rating)}'; - break; } final textScaleFactor = MediaQuery.textScaleFactorOf(context); diff --git a/lib/widgets/viewer/overlay/video/progress_bar.dart b/lib/widgets/viewer/overlay/video/progress_bar.dart index 62a21c974..cdf245690 100644 --- a/lib/widgets/viewer/overlay/video/progress_bar.dart +++ b/lib/widgets/viewer/overlay/video/progress_bar.dart @@ -9,7 +9,6 @@ import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves_video/aves_video.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class VideoProgressBar extends StatefulWidget { final AvesVideoController? controller; @@ -155,16 +154,14 @@ class _VideoProgressBarState extends State { Widget _buildMuteIndicator() => StreamBuilder( stream: controller?.volumeStream ?? Stream.value(1.0), builder: (context, snapshot) { + final textScaleFactor = MediaQuery.textScaleFactorOf(context); final isMuted = controller?.isMuted ?? false; return isMuted ? Padding( padding: const EdgeInsetsDirectional.only(end: 8), - child: Selector( - selector: (context, mq) => mq.textScaleFactor, - builder: (context, textScaleFactor, child) => Icon( - AIcons.mute, - size: 16 * textScaleFactor, - ), + child: Icon( + AIcons.mute, + size: 16 * textScaleFactor, ), ) : const SizedBox(); diff --git a/lib/widgets/viewer/overlay/viewer_buttons.dart b/lib/widgets/viewer/overlay/viewer_buttons.dart index fbb31c322..b64a91f6c 100644 --- a/lib/widgets/viewer/overlay/viewer_buttons.dart +++ b/lib/widgets/viewer/overlay/viewer_buttons.dart @@ -327,19 +327,14 @@ class ViewerButtonRowContent extends StatelessWidget { switch (action) { case EntryAction.videoCaptureFrame: enabled = videoController?.canCaptureFrameNotifier.value ?? false; - break; case EntryAction.videoToggleMute: enabled = videoController?.canMuteNotifier.value ?? false; - break; case EntryAction.videoSelectStreams: enabled = videoController?.canSelectStreamNotifier.value ?? false; - break; case EntryAction.videoSetSpeed: enabled = videoController?.canSetSpeedNotifier.value ?? false; - break; default: enabled = true; - break; } Widget? child; @@ -349,22 +344,18 @@ class ViewerButtonRowContent extends StatelessWidget { entries: {favouriteTargetEntry}, isMenuItem: true, ); - break; case EntryAction.videoToggleMute: child = MuteToggler( controller: videoController, isMenuItem: true, ); - break; case EntryAction.videoTogglePlay: child = PlayToggler( controller: videoController, isMenuItem: true, ); - break; default: child = MenuRow(text: action.getText(context), icon: action.getIcon()); - break; } return PopupMenuItem( value: action, @@ -448,7 +439,6 @@ class ViewerButtonRowContent extends StatelessWidget { onChooserValue: (album) => actionDelegate.quickMove(context, album, copy: true), onPressed: onPressed, ); - break; case EntryAction.move: child = MoveButton( copy: false, @@ -456,7 +446,6 @@ class ViewerButtonRowContent extends StatelessWidget { onChooserValue: (album) => actionDelegate.quickMove(context, album, copy: false), onPressed: onPressed, ); - break; case EntryAction.share: child = ShareButton( blurred: blurred, @@ -465,7 +454,6 @@ class ViewerButtonRowContent extends StatelessWidget { focusNode: focusNode, onPressed: onPressed, ); - break; case EntryAction.toggleFavourite: final favouriteTargetEntry = mainEntry.isBurst ? pageEntry : mainEntry; child = FavouriteToggler( @@ -473,30 +461,24 @@ class ViewerButtonRowContent extends StatelessWidget { focusNode: focusNode, onPressed: onPressed, ); - break; case EntryAction.videoToggleMute: child = MuteToggler( controller: videoController, focusNode: focusNode, onPressed: onPressed, ); - break; case EntryAction.videoTogglePlay: child = PlayToggler( controller: videoController, focusNode: focusNode, onPressed: onPressed, ); - break; case EntryAction.videoCaptureFrame: child = _buildFromListenable(videoController?.canCaptureFrameNotifier); - break; case EntryAction.videoSelectStreams: child = _buildFromListenable(videoController?.canSelectStreamNotifier); - break; case EntryAction.videoSetSpeed: child = _buildFromListenable(videoController?.canSetSpeedNotifier); - break; case EntryAction.editRating: child = RateButton( blurred: blurred, @@ -504,7 +486,6 @@ class ViewerButtonRowContent extends StatelessWidget { focusNode: focusNode, onPressed: onPressed, ); - break; case EntryAction.editTags: child = TagButton( blurred: blurred, @@ -512,7 +493,6 @@ class ViewerButtonRowContent extends StatelessWidget { focusNode: focusNode, onPressed: onPressed, ); - break; default: child = IconButton( icon: action.getIcon(), @@ -520,7 +500,6 @@ class ViewerButtonRowContent extends StatelessWidget { focusNode: focusNode, tooltip: action.getText(context), ); - break; } return child; } diff --git a/lib/widgets/viewer/overlay/wallpaper_buttons.dart b/lib/widgets/viewer/overlay/wallpaper_buttons.dart index 2ff880700..fdec17399 100644 --- a/lib/widgets/viewer/overlay/wallpaper_buttons.dart +++ b/lib/widgets/viewer/overlay/wallpaper_buttons.dart @@ -209,14 +209,11 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin { case 90: canvas.translate(-imageDisplaySize.width, imageDisplaySize.height); canvas.rotate(degToRadian(270)); - break; case 180: canvas.translate(0, imageDisplaySize.height); canvas.rotate(degToRadian(180)); - break; case 270: canvas.rotate(degToRadian(90)); - break; } } else { switch (rotationDegrees) { @@ -224,13 +221,10 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin { canvas.translate(imageDisplaySize.width, 0); cropDx = -displayRegion.top.toDouble(); cropDy = displayRegion.left.toDouble(); - break; case 180: canvas.translate(imageDisplaySize.width, imageDisplaySize.height); - break; case 270: canvas.translate(0, imageDisplaySize.height); - break; } if (rotationDegrees != 0) { canvas.rotate(degToRadian(rotationDegrees.toDouble())); diff --git a/lib/widgets/viewer/panorama_page.dart b/lib/widgets/viewer/panorama_page.dart index 71067e16d..464dc5dc8 100644 --- a/lib/widgets/viewer/panorama_page.dart +++ b/lib/widgets/viewer/panorama_page.dart @@ -156,11 +156,9 @@ class _PanoramaPageState extends State { switch (_sensorControl.value) { case SensorControl.None: _sensorControl.value = SensorControl.AbsoluteOrientation; - break; case SensorControl.AbsoluteOrientation: case SensorControl.Orientation: _sensorControl.value = SensorControl.None; - break; } } diff --git a/lib/widgets/viewer/slideshow_page.dart b/lib/widgets/viewer/slideshow_page.dart index d4139d669..d05186d6f 100644 --- a/lib/widgets/viewer/slideshow_page.dart +++ b/lib/widgets/viewer/slideshow_page.dart @@ -124,13 +124,10 @@ class _SlideshowPageState extends State { switch (action) { case SlideshowAction.resume: _viewerController.autopilot = true; - break; case SlideshowAction.showInCollection: _showInCollection(); - break; case SlideshowAction.settings: _showSettings(context); - break; } } diff --git a/lib/widgets/viewer/video/fijkplayer.dart b/lib/widgets/viewer/video/fijkplayer.dart index bd373c087..80d65934e 100644 --- a/lib/widgets/viewer/video/fijkplayer.dart +++ b/lib/widgets/viewer/video/fijkplayer.dart @@ -270,13 +270,10 @@ class IjkPlayerAvesVideoController extends AvesVideoController { if (width != null && height != null) { videoStreamCount++; } - break; case MediaStreamType.audio: audioStreamCount++; - break; case MediaStreamType.text: textStreamCount++; - break; } } }); @@ -303,9 +300,6 @@ class IjkPlayerAvesVideoController extends AvesVideoController { if (fields == null) return; final event = fields['event'] as String?; switch (event) { - case 'volume': - // ignore - break; case 'audiofocus': final value = fields['value'] as int?; if (value != null) { @@ -313,9 +307,10 @@ class IjkPlayerAvesVideoController extends AvesVideoController { case _audioFocusLoss: case _audioFocusRequestFailed: pause(); - break; } } + case 'volume': + // ignore break; } } @@ -538,11 +533,9 @@ extension ExtraFijkPlayer on FijkPlayer { case FijkState.prepared: removeListener(onChanged); completer.complete(); - break; case FijkState.error: removeListener(onChanged); completer.completeError(value.exception); - break; default: break; } diff --git a/lib/widgets/viewer/video/flutter_vlc_player.dart b/lib/widgets/viewer/video/flutter_vlc_player.dart index f9de65fbe..6fb16fe06 100644 --- a/lib/widgets/viewer/video/flutter_vlc_player.dart +++ b/lib/widgets/viewer/video/flutter_vlc_player.dart @@ -83,7 +83,7 @@ // // do not use `Magnifier` with `applyScale` enabled when using this widget, // // as the original video size will be used to create the `PlatformView` // // and a virtual display larger than the device screen may crash the app -// final mqWidth = context.select((mq) => mq.size.width); +// final mqWidth = MediaQuery.sizeOf(context).width; // final displaySize = entry.displaySize; // final ratio = mqWidth / displaySize.width; // return SizedBox.fromSize( diff --git a/lib/widgets/viewer/visual/entry_page_view.dart b/lib/widgets/viewer/visual/entry_page_view.dart index 30bf70574..fd1cfe61f 100644 --- a/lib/widgets/viewer/visual/entry_page_view.dart +++ b/lib/widgets/viewer/visual/entry_page_view.dart @@ -419,16 +419,12 @@ class _EntryPageViewState extends State with SingleTickerProvider switch (direction) { case AxisDirection.left: const ShowPreviousEntryNotification(animate: true).dispatch(context); - break; case AxisDirection.right: const ShowNextEntryNotification(animate: true).dispatch(context); - break; case AxisDirection.up: PopVisualNotification().dispatch(context); - break; case AxisDirection.down: ShowInfoPageNotification().dispatch(context); - break; } } @@ -456,24 +452,18 @@ class _EntryPageViewState extends State with SingleTickerProvider switch (event.command) { case MediaCommand.play: videoController.play(); - break; case MediaCommand.pause: videoController.pause(); - break; case MediaCommand.skipToNext: ShowNextVideoNotification().dispatch(context); - break; case MediaCommand.skipToPrevious: ShowPreviousVideoNotification().dispatch(context); - break; case MediaCommand.stop: videoController.pause(); - break; case MediaCommand.seek: if (event is MediaSeekCommandEvent) { videoController.seekTo(event.position); } - break; } } @@ -492,14 +482,8 @@ class _EntryPageViewState extends State with SingleTickerProvider } double? _getSideRatio() { - switch (context.read()?.orientation) { - case Orientation.portrait: - return 1 / 5; - case Orientation.landscape: - return 1 / 8; - case null: - return null; - } + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; + return isPortrait ? 1 / 5 : 1 / 8; } static ScaleState _vectorScaleStateCycle(ScaleState actual) { diff --git a/lib/widgets/viewer/visual/vector.dart b/lib/widgets/viewer/visual/vector.dart index 5a198cc43..19503373b 100644 --- a/lib/widgets/viewer/visual/vector.dart +++ b/lib/widgets/viewer/visual/vector.dart @@ -1,5 +1,4 @@ import 'dart:math'; -import 'dart:ui'; import 'package:aves/image_providers/region_provider.dart'; import 'package:aves/model/entry/entry.dart'; @@ -103,12 +102,18 @@ class _VectorImageViewState extends State { Widget build(BuildContext context) { if (_displaySize == Size.zero) return widget.errorBuilder(context, 'Not sized', null); + final devicePixelRatio = View.of(context).devicePixelRatio; return ValueListenableBuilder( valueListenable: viewStateNotifier, builder: (context, viewState, child) { final viewportSize = viewState.viewportSize; final viewportSized = viewportSize?.isEmpty == false; - if (viewportSized && !_isTilingInitialized) _initTiling(viewportSize!); + if (viewportSized && !_isTilingInitialized) { + _initTiling( + viewportSize: viewportSize!, + devicePixelRatio: devicePixelRatio, + ); + } return SizedBox.fromSize( size: _displaySize * viewState.scale!, @@ -116,7 +121,7 @@ class _VectorImageViewState extends State { alignment: Alignment.center, children: [ _buildLoading(), - ..._getTiles(), + ..._getTiles(devicePixelRatio), ], ), ); @@ -124,11 +129,14 @@ class _VectorImageViewState extends State { ); } - void _initTiling(Size viewportSize) { + void _initTiling({ + required Size viewportSize, + required double devicePixelRatio, + }) { _tileSide = _displaySize.longestSide; // scale for initial state `contained` final containedScale = min(viewportSize.width / _displaySize.width, viewportSize.height / _displaySize.height); - _minScale = _imageScaleForViewScale(containedScale); + _minScale = _imageScaleForViewScale(scale: containedScale, devicePixelRatio: devicePixelRatio); _isTilingInitialized = true; _registerFullImage(); @@ -154,7 +162,7 @@ class _VectorImageViewState extends State { ); } - List _getTiles() { + List _getTiles(double devicePixelRatio) { if (!_isTilingInitialized) return []; final displayWidth = _displaySize.width; @@ -205,7 +213,7 @@ class _VectorImageViewState extends State { ); final tiles = [fullImageRegionTile]; - final maxSvgScale = max(_imageScaleForViewScale(viewScale), _minScale); + final maxSvgScale = max(_imageScaleForViewScale(scale: viewScale, devicePixelRatio: devicePixelRatio), _minScale); double nextScale(double scale) => scale * 2; // add `alpha` to the region side so that tiles do not align across layers, // which helps the checkered background deflation workaround @@ -273,7 +281,11 @@ class _VectorImageViewState extends State { return Tuple2>(tileRect, regionRect); } - double _imageScaleForViewScale(double scale) => smallestPowerOf2(scale * window.devicePixelRatio).toDouble(); + double _imageScaleForViewScale({ + required double scale, + required double devicePixelRatio, + }) => + smallestPowerOf2(scale * devicePixelRatio).toDouble(); } typedef _BackgroundFrameBuilder = Widget Function(Widget child, int? frame, Rect tileRect); diff --git a/lib/widgets/viewer/visual/video/cover.dart b/lib/widgets/viewer/visual/video/cover.dart index 6091cbd69..d3438159d 100644 --- a/lib/widgets/viewer/visual/video/cover.dart +++ b/lib/widgets/viewer/visual/video/cover.dart @@ -144,6 +144,7 @@ class _VideoCoverState extends State { child: ThumbnailImage( entry: entry, extent: extent, + devicePixelRatio: MediaQuery.devicePixelRatioOf(context), fit: BoxFit.contain, showLoadingBackground: false, ), diff --git a/lib/widgets/viewer/visual/video/subtitle/ass_parser.dart b/lib/widgets/viewer/visual/video/subtitle/ass_parser.dart index e6b78b844..06bba15df 100644 --- a/lib/widgets/viewer/visual/video/subtitle/ass_parser.dart +++ b/lib/widgets/viewer/visual/video/subtitle/ass_parser.dart @@ -88,21 +88,18 @@ class AssParser { borderColor: extraStyle.borderColor?.withAlpha(a), ); } - break; } case '1a': { // \1a: fill alpha final a = _parseAlpha(param); if (a != null) textStyle = textStyle.copyWith(color: textStyle.color?.withAlpha(a)); - break; } case '3a': { // \3a: border alpha final a = _parseAlpha(param); if (a != null) extraStyle = extraStyle.copyWith(borderColor: extraStyle.borderColor?.withAlpha(a)); - break; } case '4a': { @@ -118,43 +115,36 @@ class AssParser { )) .toList()); } - break; } case 'a': // \a: line alignment (legacy) extraStyle = _copyWithAlignment(_parseLegacyAlignment(param), extraStyle); - break; case 'an': // \an: line alignment extraStyle = _copyWithAlignment(_parseNewAlignment(param), extraStyle); - break; case 'b': { // \b: bold final weight = _parseFontWeight(param); if (weight != null) textStyle = textStyle.copyWith(fontWeight: weight); - break; } case 'be': { // \be: blurs the edges of the text final times = int.tryParse(param); if (times != null) extraStyle = extraStyle.copyWith(edgeBlur: times == 0 ? 0 : 1); - break; } case 'blur': { // \blur: blurs the edges of the text (Gaussian kernel) final strength = double.tryParse(param); if (strength != null) extraStyle = extraStyle.copyWith(edgeBlur: strength / 2); - break; } case 'bord': { // \bord: border width final size = double.tryParse(param); if (size != null) extraStyle = extraStyle.copyWith(borderWidth: size); - break; } case 'c': case '1c': @@ -164,7 +154,6 @@ class AssParser { if (color != null) { textStyle = textStyle.copyWith(color: color.withAlpha(textStyle.color?.alpha ?? 0xFF)); } - break; } case '3c': { @@ -175,7 +164,6 @@ class AssParser { borderColor: color.withAlpha(extraStyle.borderColor?.alpha ?? 0xFF), ); } - break; } case '4c': { @@ -191,12 +179,10 @@ class AssParser { )) .toList()); } - break; } case 'clip': // \clip: clip (within rectangle or path) line = line.copyWith(clip: _parseClip(param)); - break; case 'fax': { final factor = double.tryParse(param); @@ -204,7 +190,6 @@ class AssParser { if (factor != null && (line.position == null || extraStyle.shearX == null)) { extraStyle = extraStyle.copyWith(shearX: factor); } - break; } case 'fay': { @@ -213,28 +198,24 @@ class AssParser { if (factor != null && (line.position == null || extraStyle.shearY == null)) { extraStyle = extraStyle.copyWith(shearY: factor); } - break; } case 'fn': { final name = param; // TODO TLAD [subtitles] extract fonts from attachment streams, and load these fonts in Flutter if (name.isNotEmpty) textStyle = textStyle.copyWith(fontFamily: name); - break; } case 'frx': { // \frx: text rotation (X axis) final amount = double.tryParse(param); if (amount != null) extraStyle = extraStyle.copyWith(rotationX: amount); - break; } case 'fry': { // \fry: text rotation (Y axis) final amount = double.tryParse(param); if (amount != null) extraStyle = extraStyle.copyWith(rotationY: amount); - break; } case 'fr': case 'frz': @@ -242,40 +223,34 @@ class AssParser { // \frz: text rotation (Z axis) final amount = double.tryParse(param); if (amount != null) extraStyle = extraStyle.copyWith(rotationZ: amount); - break; } case 'fs': { // \fs: font size final size = int.tryParse(param); if (size != null) textStyle = textStyle.copyWith(fontSize: size * scale); - break; } case 'fscx': { // \fscx: font scale (horizontal) final scale = int.tryParse(param); if (scale != null) extraStyle = extraStyle.copyWith(scaleX: scale.toDouble() / 100); - break; } case 'fscy': { // \fscx: font scale (vertical) final scale = int.tryParse(param); if (scale != null) extraStyle = extraStyle.copyWith(scaleY: scale.toDouble() / 100); - break; } case 'fsp': { // \fsp: letter spacing final spacing = double.tryParse(param); textStyle = textStyle.copyWith(letterSpacing: spacing); - break; } case 'i': // \i: italics textStyle = textStyle.copyWith(fontStyle: param == '1' ? FontStyle.italic : FontStyle.normal); - break; case 'p': { // \p drawing paths @@ -290,7 +265,6 @@ class AssParser { extraStyle = extraStyle.copyWith(drawingPaths: null); } } - break; } case 'pos': { @@ -309,20 +283,16 @@ class AssParser { } } } - break; } case 'r': // \r: reset textStyle = baseStyle; - break; case 's': // \s: strikeout textStyle = textStyle.copyWith(decoration: param == '1' ? TextDecoration.lineThrough : TextDecoration.none); - break; case 'u': // \u: underline textStyle = textStyle.copyWith(decoration: param == '1' ? TextDecoration.underline : TextDecoration.none); - break; // TODO TLAD [subtitles] SHOULD support the following case 'shad': case 't': // \t: animated transform @@ -512,13 +482,11 @@ class AssParser { path!.cubicTo(points[0], points[1], points[2], points[3], points[4], points[5]); } } - break; case 'c': if (path != null) { path!.close(); } path = null; - break; case 'l': if (path != null) { const lParamCount = 2; @@ -528,7 +496,6 @@ class AssParser { path!.lineTo(points[0], points[1]); } } - break; case 'm': if (params.length == 2) { if (path != null) { @@ -538,16 +505,13 @@ class AssParser { paths.add(path!); path!.moveTo(params[0], params[1]); } - break; case 'n': if (params.length == 2 && path != null) { path!.moveTo(params[0], params[1]); } - break; case 's': case 'p': debugPrint('unhandled ASS drawing command=$command'); - break; } } }); diff --git a/lib/widgets/viewer/visual/video/subtitle/subtitle.dart b/lib/widgets/viewer/visual/video/subtitle/subtitle.dart index 48919273c..bbf86b845 100644 --- a/lib/widgets/viewer/visual/video/subtitle/subtitle.dart +++ b/lib/widgets/viewer/visual/video/subtitle/subtitle.dart @@ -4,11 +4,11 @@ import 'package:aves/model/settings/enums/subtitle_position.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/widgets/common/basic/text/background_painter.dart'; import 'package:aves/widgets/common/basic/text/outlined.dart'; -import 'package:aves_video/aves_video.dart'; import 'package:aves/widgets/viewer/visual/state.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/ass_parser.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/span.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/style.dart'; +import 'package:aves_video/aves_video.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -53,234 +53,217 @@ class VideoSubtitles extends StatelessWidget { shadows: settings.subtitleShowOutline ? baseShadows : null, ); - return Selector( - selector: (context, mq) => mq.orientation, - builder: (context, orientation, child) { - final bottom = orientation == Orientation.portrait ? .5 : .8; - final viewportSize = context.read().size; + final viewportSize = MediaQuery.sizeOf(context); + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; + final bottom = isPortrait ? .5 : .8; + return ValueListenableBuilder( + valueListenable: viewStateNotifier, + builder: (context, viewState, child) { + final viewPosition = viewState.position; + final viewScale = viewState.scale ?? 1; + final viewSize = videoDisplaySize * viewScale; + final viewOffset = Offset( + (viewportSize.width - viewSize.width) / 2, + (viewportSize.height - viewSize.height) / 2, + ); - return ValueListenableBuilder( - valueListenable: viewStateNotifier, - builder: (context, viewState, child) { - final viewPosition = viewState.position; - final viewScale = viewState.scale ?? 1; - final viewSize = videoDisplaySize * viewScale; - final viewOffset = Offset( - (viewportSize.width - viewSize.width) / 2, - (viewportSize.height - viewSize.height) / 2, - ); + return StreamBuilder( + stream: controller.timedTextStream, + builder: (context, snapshot) { + final text = snapshot.data; + if (text == null) return const SizedBox(); - return StreamBuilder( - stream: controller.timedTextStream, - builder: (context, snapshot) { - final text = snapshot.data; - if (text == null) return const SizedBox(); + if (debugMode) { + return Padding( + padding: const EdgeInsets.only(top: 100.0), + child: Align( + alignment: Alignment.topLeft, + child: OutlinedText( + textSpans: [ + TextSpan( + text: text, + style: const TextStyle(fontSize: 14), + ) + ], + outlineWidth: 1, + outlineColor: Colors.black, + ), + ), + ); + } - if (debugMode) { - return Padding( - padding: const EdgeInsets.only(top: 100.0), + final styledLine = AssParser.parse(text, baseStyle, viewScale); + final position = styledLine.position; + final clip = styledLine.clip; + final styledSpans = styledLine.spans; + final byExtraStyle = groupBy(styledSpans, (v) => v.extraStyle); + return Stack( + children: byExtraStyle.entries.map((kv) { + final extraStyle = kv.key; + final spans = kv.value.map((v) { + final span = v.textSpan; + final style = span.style; + if (position == null || style == null) return span; + + final letterSpacing = style.letterSpacing; + final shadows = style.shadows; + return TextSpan( + text: span.text, + style: style.copyWith( + letterSpacing: letterSpacing != null ? letterSpacing * viewScale : null, + shadows: shadows + ?.map((v) => Shadow( + color: v.color, + offset: v.offset * viewScale, + blurRadius: v.blurRadius * viewScale, + )) + .toList(), + ), + ); + }).toList(); + final drawingPaths = extraStyle.drawingPaths; + final textHAlign = extraStyle.hAlign ?? (position != null ? TextAlign.center : baseTextAlign); + final textVAlign = extraStyle.vAlign ?? (position != null ? TextAlignVertical.bottom : baseTextAlignY); + + Widget child; + if (drawingPaths != null) { + child = CustomPaint( + painter: SubtitlePathPainter( + paths: drawingPaths, + scale: viewScale, + fillColor: spans.firstOrNull?.style?.color ?? Colors.white, + strokeColor: extraStyle.borderColor, + ), + ); + } else { + final outlineWidth = extraStyle.borderWidth ?? (extraStyle.edgeBlur != null ? 2 : 1); + child = OutlinedText( + textSpans: spans, + outlineWidth: outlineWidth * (position != null ? viewScale : baseOutlineWidth), + outlineColor: extraStyle.borderColor ?? baseOutlineColor, + outlineBlurSigma: extraStyle.edgeBlur ?? 0, + textAlign: textHAlign, + ); + } + + var transform = Matrix4.identity(); + + if (position != null) { + final para = RenderParagraph( + TextSpan(children: spans), + textDirection: TextDirection.ltr, + textScaleFactor: MediaQuery.textScaleFactorOf(context), + )..layout(const BoxConstraints()); + final textWidth = para.getMaxIntrinsicWidth(double.infinity); + final textHeight = para.getMaxIntrinsicHeight(double.infinity); + + late double anchorOffsetX, anchorOffsetY; + switch (textHAlign) { + case TextAlign.left: + anchorOffsetX = 0; + case TextAlign.right: + anchorOffsetX = -textWidth; + case TextAlign.center: + default: + anchorOffsetX = -textWidth / 2; + } + switch (textVAlign) { + case TextAlignVertical.top: + anchorOffsetY = 0; + case TextAlignVertical.center: + anchorOffsetY = -textHeight / 2; + case TextAlignVertical.bottom: + anchorOffsetY = -textHeight; + } + final alignOffset = Offset(anchorOffsetX, anchorOffsetY); + final lineOffset = position * viewScale + viewPosition; + final translateOffset = viewOffset + lineOffset + alignOffset; + transform.translate(translateOffset.dx, translateOffset.dy); + } + + if (extraStyle.rotating) { + // for perspective + transform.setEntry(3, 2, 0.001); + final x = -angles.degToRadian(extraStyle.rotationX ?? 0); + final y = -angles.degToRadian(extraStyle.rotationY ?? 0); + final z = -angles.degToRadian(extraStyle.rotationZ ?? 0); + if (x != 0) transform.rotateX(x); + if (y != 0) transform.rotateY(y); + if (z != 0) transform.rotateZ(z); + } + if (extraStyle.scaling) { + final x = extraStyle.scaleX ?? 1; + final y = extraStyle.scaleY ?? 1; + transform.scale(x, y); + } + if (extraStyle.shearing) { + final x = extraStyle.shearX ?? 0; + final y = extraStyle.shearY ?? 0; + transform.multiply(Matrix4(1, y, 0, 0, x, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)); + } + + if (!transform.isIdentity()) { + child = Transform( + transform: transform, + alignment: Alignment.center, + child: child, + ); + } + + if (position == null) { + late double alignX; + switch (textHAlign) { + case TextAlign.left: + alignX = -1; + case TextAlign.right: + alignX = 1; + case TextAlign.center: + default: + alignX = 0; + } + late double alignY; + switch (textVAlign) { + case TextAlignVertical.top: + alignY = -bottom; + case TextAlignVertical.center: + alignY = 0; + case TextAlignVertical.bottom: + default: + alignY = bottom; + } + child = Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), child: Align( - alignment: Alignment.topLeft, - child: OutlinedText( - textSpans: [ - TextSpan( - text: text, - style: const TextStyle(fontSize: 14), - ) - ], - outlineWidth: 1, - outlineColor: Colors.black, + alignment: Alignment(alignX, alignY), + child: TextBackgroundPainter( + spans: spans, + style: DefaultTextStyle.of(context).style.merge(spans.first.style!.copyWith( + backgroundColor: settings.subtitleBackgroundColor, + )), + textAlign: textHAlign, + child: child, ), ), ); } - final styledLine = AssParser.parse(text, baseStyle, viewScale); - final position = styledLine.position; - final clip = styledLine.clip; - final styledSpans = styledLine.spans; - final byExtraStyle = groupBy(styledSpans, (v) => v.extraStyle); - return Stack( - children: byExtraStyle.entries.map((kv) { - final extraStyle = kv.key; - final spans = kv.value.map((v) { - final span = v.textSpan; - final style = span.style; - if (position == null || style == null) return span; + if (clip != null) { + final clipOffset = viewOffset + viewPosition; + final matrix = Matrix4.identity() + ..translate(clipOffset.dx, clipOffset.dy) + ..scale(viewScale, viewScale); + final transform = matrix.storage; + child = ClipPath( + clipper: SubtitlePathClipper( + paths: clip.map((v) => v.transform(transform)).toList(), + scale: viewScale, + ), + child: child, + ); + } - final letterSpacing = style.letterSpacing; - final shadows = style.shadows; - return TextSpan( - text: span.text, - style: style.copyWith( - letterSpacing: letterSpacing != null ? letterSpacing * viewScale : null, - shadows: shadows - ?.map((v) => Shadow( - color: v.color, - offset: v.offset * viewScale, - blurRadius: v.blurRadius * viewScale, - )) - .toList(), - ), - ); - }).toList(); - final drawingPaths = extraStyle.drawingPaths; - final textHAlign = extraStyle.hAlign ?? (position != null ? TextAlign.center : baseTextAlign); - final textVAlign = extraStyle.vAlign ?? (position != null ? TextAlignVertical.bottom : baseTextAlignY); - - Widget child; - if (drawingPaths != null) { - child = CustomPaint( - painter: SubtitlePathPainter( - paths: drawingPaths, - scale: viewScale, - fillColor: spans.firstOrNull?.style?.color ?? Colors.white, - strokeColor: extraStyle.borderColor, - ), - ); - } else { - final outlineWidth = extraStyle.borderWidth ?? (extraStyle.edgeBlur != null ? 2 : 1); - child = OutlinedText( - textSpans: spans, - outlineWidth: outlineWidth * (position != null ? viewScale : baseOutlineWidth), - outlineColor: extraStyle.borderColor ?? baseOutlineColor, - outlineBlurSigma: extraStyle.edgeBlur ?? 0, - textAlign: textHAlign, - ); - } - - var transform = Matrix4.identity(); - - if (position != null) { - final para = RenderParagraph( - TextSpan(children: spans), - textDirection: TextDirection.ltr, - textScaleFactor: context.read().textScaleFactor, - )..layout(const BoxConstraints()); - final textWidth = para.getMaxIntrinsicWidth(double.infinity); - final textHeight = para.getMaxIntrinsicHeight(double.infinity); - - late double anchorOffsetX, anchorOffsetY; - switch (textHAlign) { - case TextAlign.left: - anchorOffsetX = 0; - break; - case TextAlign.right: - anchorOffsetX = -textWidth; - break; - case TextAlign.center: - default: - anchorOffsetX = -textWidth / 2; - break; - } - switch (textVAlign) { - case TextAlignVertical.top: - anchorOffsetY = 0; - break; - case TextAlignVertical.center: - anchorOffsetY = -textHeight / 2; - break; - case TextAlignVertical.bottom: - anchorOffsetY = -textHeight; - break; - } - final alignOffset = Offset(anchorOffsetX, anchorOffsetY); - final lineOffset = position * viewScale + viewPosition; - final translateOffset = viewOffset + lineOffset + alignOffset; - transform.translate(translateOffset.dx, translateOffset.dy); - } - - if (extraStyle.rotating) { - // for perspective - transform.setEntry(3, 2, 0.001); - final x = -angles.degToRadian(extraStyle.rotationX ?? 0); - final y = -angles.degToRadian(extraStyle.rotationY ?? 0); - final z = -angles.degToRadian(extraStyle.rotationZ ?? 0); - if (x != 0) transform.rotateX(x); - if (y != 0) transform.rotateY(y); - if (z != 0) transform.rotateZ(z); - } - if (extraStyle.scaling) { - final x = extraStyle.scaleX ?? 1; - final y = extraStyle.scaleY ?? 1; - transform.scale(x, y); - } - if (extraStyle.shearing) { - final x = extraStyle.shearX ?? 0; - final y = extraStyle.shearY ?? 0; - transform.multiply(Matrix4(1, y, 0, 0, x, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)); - } - - if (!transform.isIdentity()) { - child = Transform( - transform: transform, - alignment: Alignment.center, - child: child, - ); - } - - if (position == null) { - late double alignX; - switch (textHAlign) { - case TextAlign.left: - alignX = -1; - break; - case TextAlign.right: - alignX = 1; - break; - case TextAlign.center: - default: - alignX = 0; - break; - } - late double alignY; - switch (textVAlign) { - case TextAlignVertical.top: - alignY = -bottom; - break; - case TextAlignVertical.center: - alignY = 0; - break; - case TextAlignVertical.bottom: - default: - alignY = bottom; - break; - } - child = Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Align( - alignment: Alignment(alignX, alignY), - child: TextBackgroundPainter( - spans: spans, - style: DefaultTextStyle.of(context).style.merge(spans.first.style!.copyWith( - backgroundColor: settings.subtitleBackgroundColor, - )), - textAlign: textHAlign, - child: child, - ), - ), - ); - } - - if (clip != null) { - final clipOffset = viewOffset + viewPosition; - final matrix = Matrix4.identity() - ..translate(clipOffset.dx, clipOffset.dy) - ..scale(viewScale, viewScale); - final transform = matrix.storage; - child = ClipPath( - clipper: SubtitlePathClipper( - paths: clip.map((v) => v.transform(transform)).toList(), - scale: viewScale, - ), - child: child, - ); - } - - return child; - }).toList(), - ); - }, + return child; + }).toList(), ); }, ); diff --git a/lib/widgets/viewer/visual/video/swipe_action.dart b/lib/widgets/viewer/visual/video/swipe_action.dart index a921cca38..30b049672 100644 --- a/lib/widgets/viewer/visual/video/swipe_action.dart +++ b/lib/widgets/viewer/visual/video/swipe_action.dart @@ -22,10 +22,8 @@ extension ExtraSwipeAction on SwipeAction { switch (this) { case SwipeAction.brightness: await ScreenBrightness().setScreenBrightness(value); - break; case SwipeAction.volume: VolumeController().setVolume(value, showSystemUI: false); - break; } } } diff --git a/lib/widgets/welcome_page.dart b/lib/widgets/welcome_page.dart index a06e1f902..9a03e5a52 100644 --- a/lib/widgets/welcome_page.dart +++ b/lib/widgets/welcome_page.dart @@ -59,7 +59,7 @@ class _WelcomePageState extends State { if (snapshot.hasError || snapshot.connectionState != ConnectionState.done) return const SizedBox(); final terms = snapshot.data!; final durations = context.watch(); - final isPortrait = context.select((mq) => mq.orientation) == Orientation.portrait; + final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; return Column( mainAxisSize: MainAxisSize.min, children: _toStaggeredList( diff --git a/plugins/aves_magnifier/lib/src/core/core.dart b/plugins/aves_magnifier/lib/src/core/core.dart index de9829584..d2f95bad9 100644 --- a/plugins/aves_magnifier/lib/src/core/core.dart +++ b/plugins/aves_magnifier/lib/src/core/core.dart @@ -11,7 +11,6 @@ import 'package:aves_magnifier/src/scale/state.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; -import 'package:provider/provider.dart'; import 'package:tuple/tuple.dart'; /// Internal widget in which controls all animations lifecycle, core responses @@ -272,7 +271,7 @@ class _MagnifierCoreState extends State with TickerProviderStateM } bool _isFlingGesture(VelocityEstimate estimate, PointerDeviceKind kind, Axis axis) { - final gestureSettings = context.read().gestureSettings; + final gestureSettings = MediaQuery.gestureSettingsOf(context); const minVelocity = kMinFlingVelocity; final minDistance = computeHitSlop(kind, gestureSettings); diff --git a/plugins/aves_magnifier/lib/src/core/gesture_detector.dart b/plugins/aves_magnifier/lib/src/core/gesture_detector.dart index e18c4283f..f28710d4b 100644 --- a/plugins/aves_magnifier/lib/src/core/gesture_detector.dart +++ b/plugins/aves_magnifier/lib/src/core/gesture_detector.dart @@ -3,7 +3,6 @@ import 'package:aves_magnifier/src/pan/edge_hit_detector.dart'; import 'package:aves_magnifier/src/pan/gesture_detector_scope.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; -import 'package:provider/provider.dart'; class MagnifierGestureDetector extends StatefulWidget { const MagnifierGestureDetector({ @@ -40,7 +39,7 @@ class _MagnifierGestureDetectorState extends State { @override Widget build(BuildContext context) { - final gestureSettings = context.select((mq) => mq.gestureSettings); + final gestureSettings = MediaQuery.gestureSettingsOf(context); final gestures = {}; if (widget.onTapDown != null || widget.onTapUp != null) { diff --git a/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart b/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart index 85b7cfcae..9aa5ebca1 100644 --- a/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart +++ b/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart @@ -93,10 +93,8 @@ class MagnifierGestureRecognizer extends ScaleGestureRecognizer { // when it should yield to other recognizers final canAccept = _areMultiPointers() || _isPriorityGesture() || _canPanX() || _canPanY(); super.resolve(canAccept ? GestureDisposition.accepted : GestureDisposition.rejected); - break; case GestureDisposition.rejected: super.resolve(disposition); - break; } } diff --git a/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart b/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart index 150bf45bb..256612d9f 100644 --- a/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart +++ b/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart @@ -1,10 +1,9 @@ import 'dart:math'; -import 'dart:ui'; import 'package:aves_magnifier/src/controller/controller.dart'; import 'package:aves_magnifier/src/scale/scale_level.dart'; import 'package:equatable/equatable.dart'; -import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; /// Internal class to wrap custom scale boundaries (min, max and initial) /// Also, stores values regarding the two sizes: the container and the child. @@ -58,7 +57,10 @@ class ScaleBoundaries extends Equatable { } } - double get originalScale => 1.0 / window.devicePixelRatio; + double get originalScale { + final view = WidgetsBinding.instance.platformDispatcher.views.firstOrNull; + return 1.0 / (view?.devicePixelRatio ?? 1.0); + } double get minScale => { scaleForLevel(_minScale), diff --git a/plugins/aves_magnifier/pubspec.lock b/plugins/aves_magnifier/pubspec.lock index 03b594497..318c61e2c 100644 --- a/plugins/aves_magnifier/pubspec.lock +++ b/plugins/aves_magnifier/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" equatable: dependency: "direct main" description: @@ -42,18 +42,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -66,10 +66,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" nested: dependency: transitive description: @@ -108,5 +108,5 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=1.16.0" diff --git a/plugins/aves_magnifier/pubspec.yaml b/plugins/aves_magnifier/pubspec.yaml index a45d38ae6..b60a8df8c 100644 --- a/plugins/aves_magnifier/pubspec.yaml +++ b/plugins/aves_magnifier/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_map/lib/src/marker/generator.dart b/plugins/aves_map/lib/src/marker/generator.dart index 3efff1ebe..ca536b32f 100644 --- a/plugins/aves_map/lib/src/marker/generator.dart +++ b/plugins/aves_map/lib/src/marker/generator.dart @@ -4,7 +4,6 @@ import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:provider/provider.dart'; // generate bitmap from widget, for Google map class MarkerGeneratorWidget extends StatefulWidget { @@ -35,8 +34,12 @@ class _MarkerGeneratorWidgetState extends State oldWidget) { super.didUpdateWidget(oldWidget); + final devicePixelRatio = View.of(context).devicePixelRatio; widget.markers.forEach((markerWidget) { - final item = getOrCreate(markerWidget.key as T); + final item = _getOrCreate( + markerKey: markerWidget.key as T, + devicePixelRatio: devicePixelRatio, + ); item.globalKey = GlobalKey(); }); _checkNextFrame(); @@ -63,7 +66,7 @@ class _MarkerGeneratorWidgetState extends State((mq) => mq.size.width), 0), + offset: Offset(MediaQuery.sizeOf(context).width, 0), child: Material( type: MaterialType.transparency, child: Stack( @@ -78,11 +81,17 @@ class _MarkerGeneratorWidgetState extends State v.markerKey == markerKey); if (existingItem != null) return existingItem; - final newItem = _MarkerGeneratorItem(markerKey); + final newItem = _MarkerGeneratorItem( + markerKey: markerKey, + devicePixelRatio: devicePixelRatio, + ); _items.add(newItem); return newItem; } @@ -92,10 +101,14 @@ enum MarkerGeneratorItemState { waiting, rendering, done } class _MarkerGeneratorItem { final T markerKey; + final double devicePixelRatio; GlobalKey? globalKey; MarkerGeneratorItemState state = MarkerGeneratorItemState.waiting; - _MarkerGeneratorItem(this.markerKey); + _MarkerGeneratorItem({ + required this.markerKey, + required this.devicePixelRatio, + }); bool get isWaiting => state == MarkerGeneratorItemState.waiting; @@ -107,7 +120,7 @@ class _MarkerGeneratorItem { final boundary = _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary; if (boundary.hasSize && boundary.size != Size.zero) { try { - final image = await boundary.toImage(pixelRatio: ui.window.devicePixelRatio); + final image = await boundary.toImage(pixelRatio: devicePixelRatio); final byteData = await image.toByteData(format: ui.ImageByteFormat.png); bytes = byteData?.buffer.asUint8List(); } catch (error) { diff --git a/plugins/aves_map/pubspec.lock b/plugins/aves_map/pubspec.lock index d19fe7fac..41b0e3bf4 100644 --- a/plugins/aves_map/pubspec.lock +++ b/plugins/aves_map/pubspec.lock @@ -20,10 +20,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -36,10 +36,10 @@ packages: dependency: "direct main" description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" custom_rounded_rectangle_border: dependency: "direct main" description: @@ -113,10 +113,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" latlong2: dependency: "direct main" description: @@ -129,10 +129,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" lists: dependency: transitive description: @@ -153,10 +153,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mgrs_dart: dependency: transitive description: @@ -246,10 +246,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -275,5 +275,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.3.0" diff --git a/plugins/aves_map/pubspec.yaml b/plugins/aves_map/pubspec.yaml index 25099293f..a6cdca279 100644 --- a/plugins/aves_map/pubspec.yaml +++ b/plugins/aves_map/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_model/pubspec.lock b/plugins/aves_model/pubspec.lock index 206fcaf52..32248f33f 100644 --- a/plugins/aves_model/pubspec.lock +++ b/plugins/aves_model/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" equatable: dependency: "direct main" description: @@ -42,18 +42,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -66,10 +66,10 @@ packages: dependency: "direct main" description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -84,4 +84,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_model/pubspec.yaml b/plugins/aves_model/pubspec.yaml index 4ce8c1284..d24556f14 100644 --- a/plugins/aves_model/pubspec.yaml +++ b/plugins/aves_model/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_platform_meta/android/build.gradle b/plugins/aves_platform_meta/android/build.gradle index cded37549..757ddd31e 100644 --- a/plugins/aves_platform_meta/android/build.gradle +++ b/plugins/aves_platform_meta/android/build.gradle @@ -2,14 +2,18 @@ group 'deckers.thibault.aves.aves_platform_meta' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.8.0' + ext { + kotlin_version = '1.8.21' + agp_version = '8.0.1' + } + repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath "com.android.tools.build:gradle:$agp_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties b/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties index cb92fa5fd..34953c675 100644 --- a/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties +++ b/plugins/aves_platform_meta/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip \ No newline at end of file diff --git a/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml b/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml index 36fa2e6a5..cc947c567 100644 --- a/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml +++ b/plugins/aves_platform_meta/android/src/main/AndroidManifest.xml @@ -1,3 +1 @@ - - + diff --git a/plugins/aves_platform_meta/pubspec.lock b/plugins/aves_platform_meta/pubspec.lock index 10b974b12..d5b51cbb3 100644 --- a/plugins/aves_platform_meta/pubspec.lock +++ b/plugins/aves_platform_meta/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" flutter: dependency: "direct main" description: flutter @@ -34,18 +34,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" plugin_platform_interface: dependency: "direct main" description: @@ -84,4 +84,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_platform_meta/pubspec.yaml b/plugins/aves_platform_meta/pubspec.yaml index 7bfc472b6..c87c30f04 100644 --- a/plugins/aves_platform_meta/pubspec.yaml +++ b/plugins/aves_platform_meta/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_report/pubspec.lock b/plugins/aves_report/pubspec.lock index c656d7419..65a37f405 100644 --- a/plugins/aves_report/pubspec.lock +++ b/plugins/aves_report/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" flutter: dependency: "direct main" description: flutter @@ -34,18 +34,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -76,4 +76,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_report/pubspec.yaml b/plugins/aves_report/pubspec.yaml index 638daa043..60ad239de 100644 --- a/plugins/aves_report/pubspec.yaml +++ b/plugins/aves_report/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_report_console/pubspec.lock b/plugins/aves_report_console/pubspec.lock index 9be92d272..d6ef00fa4 100644 --- a/plugins/aves_report_console/pubspec.lock +++ b/plugins/aves_report_console/pubspec.lock @@ -12,18 +12,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" flutter: dependency: "direct main" description: flutter @@ -41,18 +41,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -65,10 +65,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -83,4 +83,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_report_console/pubspec.yaml b/plugins/aves_report_console/pubspec.yaml index 337e24999..369f1c8b5 100644 --- a/plugins/aves_report_console/pubspec.yaml +++ b/plugins/aves_report_console/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index bdbe2b15a..716168085 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018" + sha256: d687576bb973e8d2539d0b4615d985336269a0dbe1b3984e937fd22d31406fb8 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" async: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" aves_report: dependency: "direct main" description: @@ -36,10 +36,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -52,10 +52,10 @@ packages: dependency: "direct main" description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" fake_async: dependency: transitive description: @@ -68,42 +68,42 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0 + sha256: "4491238f4fddc885bc994e304a035eb8aba2c935816b2c0b31d87f3ec6e96682" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48 + sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.8.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444 + sha256: "8c0f4c87d20e2d001a5915df238c1f9c88704231f591324205f5a5d2a7740a45" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics - sha256: e8424f75c0fd466a6ae4d069b313ec84133ef275c00a5a3a416b75b99fb3e831 + sha256: cc6cab05d4de3257408c167ec1e2e410f21c0764aea22f78481314496a1cc4ca url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.3.0" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "381e28f33d5255a698ac7755c3c4fdff42382be0154f375564e6852aa46f9d8f" + sha256: b3b6017045866b981b566896a0de6114181bf9e91465221f2e89996f47a160b4 url: "https://pub.dev" source: hosted - version: "3.5.0" + version: "3.6.0" flutter: dependency: "direct main" description: flutter @@ -131,26 +131,26 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" matcher: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -163,18 +163,18 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" path: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" plugin_platform_interface: dependency: transitive description: @@ -232,10 +232,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" vector_math: dependency: transitive description: @@ -245,5 +245,5 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" - flutter: ">=1.20.0" + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" diff --git a/plugins/aves_report_crashlytics/pubspec.yaml b/plugins/aves_report_crashlytics/pubspec.yaml index 2a4875ff3..acaa8bdca 100644 --- a/plugins/aves_report_crashlytics/pubspec.yaml +++ b/plugins/aves_report_crashlytics/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_screen_state/android/build.gradle b/plugins/aves_screen_state/android/build.gradle index 4aae7446c..f8ca69e20 100644 --- a/plugins/aves_screen_state/android/build.gradle +++ b/plugins/aves_screen_state/android/build.gradle @@ -2,14 +2,18 @@ group 'deckers.thibault.aves.aves_screen_state' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.8.21' + ext { + kotlin_version = '1.8.21' + agp_version = '8.0.1' + } + repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath "com.android.tools.build:gradle:$agp_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/plugins/aves_screen_state/android/gradle/wrapper/gradle-wrapper.properties b/plugins/aves_screen_state/android/gradle/wrapper/gradle-wrapper.properties index 3c472b99c..41681a771 100644 --- a/plugins/aves_screen_state/android/gradle/wrapper/gradle-wrapper.properties +++ b/plugins/aves_screen_state/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip \ No newline at end of file diff --git a/plugins/aves_screen_state/android/src/main/AndroidManifest.xml b/plugins/aves_screen_state/android/src/main/AndroidManifest.xml index 0c066880c..cc947c567 100644 --- a/plugins/aves_screen_state/android/src/main/AndroidManifest.xml +++ b/plugins/aves_screen_state/android/src/main/AndroidManifest.xml @@ -1,3 +1 @@ - - + diff --git a/plugins/aves_screen_state/pubspec.lock b/plugins/aves_screen_state/pubspec.lock index 10b974b12..d5b51cbb3 100644 --- a/plugins/aves_screen_state/pubspec.lock +++ b/plugins/aves_screen_state/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" flutter: dependency: "direct main" description: flutter @@ -34,18 +34,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" plugin_platform_interface: dependency: "direct main" description: @@ -84,4 +84,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_screen_state/pubspec.yaml b/plugins/aves_screen_state/pubspec.yaml index 16d083441..9b6570b39 100644 --- a/plugins/aves_screen_state/pubspec.yaml +++ b/plugins/aves_screen_state/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services/pubspec.lock b/plugins/aves_services/pubspec.lock index c1769f099..6332d2e3f 100644 --- a/plugins/aves_services/pubspec.lock +++ b/plugins/aves_services/pubspec.lock @@ -27,10 +27,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -43,10 +43,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" custom_rounded_rectangle_border: dependency: transitive description: @@ -120,10 +120,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" latlong2: dependency: "direct main" description: @@ -136,10 +136,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" lists: dependency: transitive description: @@ -160,10 +160,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mgrs_dart: dependency: transitive description: @@ -253,10 +253,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -282,5 +282,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.3.0" diff --git a/plugins/aves_services/pubspec.yaml b/plugins/aves_services/pubspec.yaml index 02ad742fe..b19e726a8 100644 --- a/plugins/aves_services/pubspec.yaml +++ b/plugins/aves_services/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services_google/lib/src/map.dart b/plugins/aves_services_google/lib/src/map.dart index b3f50548d..d80565c08 100644 --- a/plugins/aves_services_google/lib/src/map.dart +++ b/plugins/aves_services_google/lib/src/map.dart @@ -118,7 +118,6 @@ class _EntryGoogleMapState extends State> with WidgetsBindi // workaround for blank map when resuming app // cf https://github.com/flutter/flutter/issues/40284 _serviceMapController?.setMapStyle(null); - break; } } diff --git a/plugins/aves_services_google/pubspec.lock b/plugins/aves_services_google/pubspec.lock index 5e08d6ef0..181f9a0a9 100644 --- a/plugins/aves_services_google/pubspec.lock +++ b/plugins/aves_services_google/pubspec.lock @@ -34,10 +34,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -50,10 +50,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" custom_rounded_rectangle_border: dependency: transitive description: @@ -66,10 +66,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: f52ab3b76b36ede4d135aab80194df8925b553686f0fa12226b4e2d658e45903 + sha256: "9b1a0c32b2a503f8fe9f8764fac7b5fcd4f6bd35d8f49de5350bccf9e2a33b8a" url: "https://pub.dev" source: hosted - version: "8.2.2" + version: "9.0.0" device_info_plus_platform_interface: dependency: transitive description: @@ -90,10 +90,10 @@ packages: dependency: transitive description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" file: dependency: transitive description: @@ -180,10 +180,10 @@ packages: dependency: "direct main" description: name: google_maps_flutter_android - sha256: b1aeab571b33e983ced9977f2f0eca2b25925f6319e99e3901cfc1675e1b5ada + sha256: "640419bb8bf1353c6698c5ca0eb3773e58b08e820eb111e84a648e6de2b3f4a0" url: "https://pub.dev" source: hosted - version: "2.4.13" + version: "2.4.14" google_maps_flutter_ios: dependency: transitive description: @@ -228,10 +228,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" latlong2: dependency: "direct main" description: @@ -244,10 +244,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" lists: dependency: transitive description: @@ -268,10 +268,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mgrs_dart: dependency: transitive description: @@ -377,10 +377,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -405,6 +405,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.4" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae" + url: "https://pub.dev" + source: hosted + version: "1.1.0" wkt_parser: dependency: transitive description: @@ -414,5 +422,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.3.0" diff --git a/plugins/aves_services_google/pubspec.yaml b/plugins/aves_services_google/pubspec.yaml index dc926c15b..c072898a4 100644 --- a/plugins/aves_services_google/pubspec.yaml +++ b/plugins/aves_services_google/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services_huawei/pubspec.lock b/plugins/aves_services_huawei/pubspec.lock index 338b36941..0eda3f593 100644 --- a/plugins/aves_services_huawei/pubspec.lock +++ b/plugins/aves_services_huawei/pubspec.lock @@ -41,10 +41,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -57,10 +57,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" custom_rounded_rectangle_border: dependency: transitive description: @@ -150,10 +150,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" latlong2: dependency: "direct main" description: @@ -166,10 +166,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" lists: dependency: transitive description: @@ -190,10 +190,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mgrs_dart: dependency: transitive description: @@ -291,10 +291,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -320,5 +320,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.3.0" diff --git a/plugins/aves_services_huawei/pubspec.yaml b/plugins/aves_services_huawei/pubspec.yaml index 8043804ce..45c94edd3 100644 --- a/plugins/aves_services_huawei/pubspec.yaml +++ b/plugins/aves_services_huawei/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_services_none/pubspec.lock b/plugins/aves_services_none/pubspec.lock index a67767953..5ccd3af10 100644 --- a/plugins/aves_services_none/pubspec.lock +++ b/plugins/aves_services_none/pubspec.lock @@ -34,10 +34,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -50,10 +50,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" custom_rounded_rectangle_border: dependency: transitive description: @@ -127,10 +127,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" latlong2: dependency: "direct main" description: @@ -143,10 +143,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" lists: dependency: transitive description: @@ -167,10 +167,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mgrs_dart: dependency: transitive description: @@ -260,10 +260,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -289,5 +289,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.3.0" diff --git a/plugins/aves_services_none/pubspec.yaml b/plugins/aves_services_none/pubspec.yaml index 8ef4e9ad0..c189e084e 100644 --- a/plugins/aves_services_none/pubspec.yaml +++ b/plugins/aves_services_none/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_ui/pubspec.lock b/plugins/aves_ui/pubspec.lock index c656d7419..65a37f405 100644 --- a/plugins/aves_ui/pubspec.lock +++ b/plugins/aves_ui/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" flutter: dependency: "direct main" description: flutter @@ -34,18 +34,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -76,4 +76,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_ui/pubspec.yaml b/plugins/aves_ui/pubspec.yaml index 526345b23..bc1256456 100644 --- a/plugins/aves_ui/pubspec.yaml +++ b/plugins/aves_ui/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_utils/pubspec.lock b/plugins/aves_utils/pubspec.lock index c656d7419..65a37f405 100644 --- a/plugins/aves_utils/pubspec.lock +++ b/plugins/aves_utils/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" flutter: dependency: "direct main" description: flutter @@ -34,18 +34,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -76,4 +76,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_utils/pubspec.yaml b/plugins/aves_utils/pubspec.yaml index 65152ff34..dd19f728c 100644 --- a/plugins/aves_utils/pubspec.yaml +++ b/plugins/aves_utils/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/plugins/aves_video/pubspec.lock b/plugins/aves_video/pubspec.lock index 35cc0e9c3..bde974666 100644 --- a/plugins/aves_video/pubspec.lock +++ b/plugins/aves_video/pubspec.lock @@ -12,18 +12,18 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" equatable: dependency: transitive description: @@ -49,18 +49,18 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" material_color_utilities: dependency: transitive description: @@ -73,10 +73,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -91,4 +91,4 @@ packages: source: hosted version: "2.1.4" sdks: - dart: ">=2.19.6 <3.0.0" + dart: ">=3.0.0 <4.0.0" diff --git a/plugins/aves_video/pubspec.yaml b/plugins/aves_video/pubspec.yaml index 51a036afd..7c477db6e 100644 --- a/plugins/aves_video/pubspec.yaml +++ b/plugins/aves_video/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=2.19.6 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: flutter: diff --git a/pubspec.lock b/pubspec.lock index 4b4eea797..b2210d693 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,34 +5,34 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "8880b4cfe7b5b17d57c052a5a3a8cc1d4f546261c7cc8fbd717bd53f48db0568" + sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07" url: "https://pub.dev" source: hosted - version: "59.0.0" + version: "60.0.0" _flutterfire_internals: dependency: transitive description: name: _flutterfire_internals - sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018" + sha256: d687576bb973e8d2539d0b4615d985336269a0dbe1b3984e937fd22d31406fb8 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" analyzer: dependency: transitive description: name: analyzer - sha256: a89627f49b0e70e068130a36571409726b04dab12da7e5625941d2c8ec278b96 + sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3" url: "https://pub.dev" source: hosted - version: "5.11.1" + version: "5.12.0" archive: dependency: transitive description: name: archive - sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb" + sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a" url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.3.7" args: dependency: transitive description: @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" aves_magnifier: dependency: "direct main" description: @@ -154,25 +154,26 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" charts_common: dependency: transitive description: - name: charts_common - sha256: "7b8922f9b0d9b134122756a787dab1c3946ae4f3fc5022ff323ba0014998ea02" - url: "https://pub.dev" - source: hosted + path: charts_common + ref: aves + resolved-ref: "6c44dc05289c1a5dbf0b027dbba083669843072c" + url: "https://github.com/deckerst/flutter_google_charts.git" + source: git version: "0.12.0" charts_flutter: dependency: "direct main" description: path: charts_flutter - ref: master - resolved-ref: de76a46c1908b0c35aaf60823100fe9bfa26ae4d - url: "https://github.com/fzyzcjy/charts.git" + ref: aves + resolved-ref: "6c44dc05289c1a5dbf0b027dbba083669843072c" + url: "https://github.com/deckerst/flutter_google_charts.git" source: git version: "0.12.0" clock: @@ -187,18 +188,18 @@ packages: dependency: "direct main" description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" connectivity_plus: dependency: "direct main" description: name: connectivity_plus - sha256: b74247fad72c171381dbe700ca17da24deac637ab6d43c343b42867acb95c991 + sha256: "45262924896ff72a8cd92b722bb7e3d5020f9e0724531a3e10e22ddae2005991" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "4.0.0" connectivity_plus_platform_interface: dependency: transitive description: @@ -235,10 +236,10 @@ packages: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" custom_rounded_rectangle_border: dependency: transitive description: @@ -266,11 +267,12 @@ packages: device_info_plus: dependency: "direct main" description: - name: device_info_plus - sha256: f52ab3b76b36ede4d135aab80194df8925b553686f0fa12226b4e2d658e45903 - url: "https://pub.dev" - source: hosted - version: "8.2.2" + path: "packages/device_info_plus/device_info_plus" + ref: main + resolved-ref: e8d3b445ce52012456126a3844ddb49b92c5c850 + url: "https://github.com/fluttercommunity/plus_plugins.git" + source: git + version: "9.0.0" device_info_plus_platform_interface: dependency: transitive description: @@ -283,10 +285,10 @@ packages: dependency: "direct main" description: name: dynamic_color - sha256: bbebb1b7ebed819e0ec83d4abdc2a8482d934f6a85289ffc1c6acf7589fa2aad + sha256: "1ffc93e3794696af22ff11d75adcd6f5fb67b45bd54f9d8735a5d1cf8c013841" url: "https://pub.dev" source: hosted - version: "1.6.3" + version: "1.6.4" equatable: dependency: "direct main" description: @@ -324,16 +326,16 @@ packages: dependency: transitive description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" fijkplayer: dependency: "direct main" description: path: "." ref: aves - resolved-ref: aebc9d7f14c8226885b6e02d7955ba6a696d454b + resolved-ref: "935a2d86ebf45fbdbaf8b4a0921d5eaea87410d6" url: "https://github.com/deckerst/fijkplayer.git" source: git version: "0.10.0" @@ -349,65 +351,66 @@ packages: dependency: transitive description: name: firebase_core - sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0 + sha256: "4491238f4fddc885bc994e304a035eb8aba2c935816b2c0b31d87f3ec6e96682" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48 + sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.8.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444 + sha256: "8c0f4c87d20e2d001a5915df238c1f9c88704231f591324205f5a5d2a7740a45" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" firebase_crashlytics: dependency: transitive description: name: firebase_crashlytics - sha256: e8424f75c0fd466a6ae4d069b313ec84133ef275c00a5a3a416b75b99fb3e831 + sha256: cc6cab05d4de3257408c167ec1e2e410f21c0764aea22f78481314496a1cc4ca url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.3.0" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "381e28f33d5255a698ac7755c3c4fdff42382be0154f375564e6852aa46f9d8f" + sha256: b3b6017045866b981b566896a0de6114181bf9e91465221f2e89996f47a160b4 url: "https://pub.dev" source: hosted - version: "3.5.0" + version: "3.6.0" flex_color_picker: dependency: "direct main" description: name: flex_color_picker - sha256: fc035dbef0975dd2650f9db1335c552e3b0ce87da4900b00f6b98cd6c78cbe42 + sha256: d8279250820ad279123fa8ee94151dd99400dd9ef4fb096589fcf956765d39a9 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" flex_seed_scheme: dependency: transitive description: name: flex_seed_scheme - sha256: b3678d82403c13dec2ee2721e078b26f14577712411b6aa981b0f4269df3fabb + sha256: e4168a6fc88a3e5bc3d6b7a748c6a6083eedc193d343ddc26bbad7fb1b258555 url: "https://pub.dev" source: hosted - version: "1.2.4" + version: "1.3.0" floating: dependency: "direct main" description: - name: floating - sha256: c6380d9cbf628370c68749fa1f0675bc5b69d9a5b923b84660e79b3e6c9a47ec - url: "https://pub.dev" - source: hosted + path: "." + ref: kotlin-jvm-target + resolved-ref: "4781520e090c3a104e2478cfe8e8cb97235341ec" + url: "https://github.com/deckerst/floating.git" + source: git version: "2.0.0" fluster: dependency: "direct main" @@ -523,10 +526,10 @@ packages: dependency: "direct main" description: name: get_it - sha256: "43133b45f32f1d96bbaeb43ea35a50ce854981baa80f47c3e26ee2ad23bef113" + sha256: "529de303c739fca98cd7ece5fca500d8ff89649f1bb4b4e94fb20954abcd7468" url: "https://pub.dev" source: hosted - version: "7.5.0" + version: "7.6.0" glob: dependency: transitive description: @@ -544,12 +547,13 @@ packages: source: hosted version: "5.0.0" google_api_availability_android: - dependency: transitive + dependency: "direct overridden" description: - name: google_api_availability_android - sha256: eb309bc0b435731d18f306b598e176a9afcf642089a7d7c5cbb48e393afda345 - url: "https://pub.dev" - source: hosted + path: google_api_availability_android + ref: agp8-compat + resolved-ref: d227c28fed8dff3bc6afb1d09248cf0ab8824473 + url: "https://github.com/deckerst/flutter-google-api-availability.git" + source: git version: "1.0.0+1" google_api_availability_platform_interface: dependency: transitive @@ -571,10 +575,10 @@ packages: dependency: transitive description: name: google_maps_flutter_android - sha256: b1aeab571b33e983ced9977f2f0eca2b25925f6319e99e3901cfc1675e1b5ada + sha256: "640419bb8bf1353c6698c5ca0eb3773e58b08e820eb111e84a648e6de2b3f4a0" url: "https://pub.dev" source: hosted - version: "2.4.13" + version: "2.4.14" google_maps_flutter_ios: dependency: transitive description: @@ -635,10 +639,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.0" io: dependency: transitive description: @@ -651,10 +655,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" latlong2: dependency: "direct main" description: @@ -667,10 +671,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" lists: dependency: transitive description: @@ -699,10 +703,10 @@ packages: dependency: transitive description: name: local_auth_ios - sha256: "604078f6492fe7730fc5bb8e4f2cfe2bc287a9b499ea0ff30a29925fc1873728" + sha256: "503a938c4edde6b244c6ee3b1e2e675ddb7e37e79d5056658dbed1997cf04785" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" local_auth_platform_interface: dependency: transitive description: @@ -739,18 +743,18 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: "direct main" description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" material_design_icons_flutter: dependency: "direct main" description: @@ -763,10 +767,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mgrs_dart: dependency: transitive description: @@ -788,7 +792,7 @@ packages: description: path: "." ref: aves - resolved-ref: f05bca5ca9d74c65ae966f6e6f88c511ceedbef8 + resolved-ref: "45e13ba987b00261d00488d29fa6f97ed0bcb96a" url: "https://github.com/deckerst/aves_panorama_motion_sensors.git" source: git version: "0.1.0" @@ -835,11 +839,12 @@ packages: package_info_plus: dependency: "direct main" description: - name: package_info_plus - sha256: "10259b111176fba5c505b102e3a5b022b51dd97e30522e906d6922c745584745" - url: "https://pub.dev" - source: hosted - version: "3.1.2" + path: "packages/package_info_plus/package_info_plus" + ref: main + resolved-ref: e8d3b445ce52012456126a3844ddb49b92c5c850 + url: "https://github.com/fluttercommunity/plus_plugins.git" + source: git + version: "4.0.0" package_info_plus_platform_interface: dependency: transitive description: @@ -869,10 +874,10 @@ packages: dependency: "direct main" description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_parsing: dependency: transitive description: @@ -917,10 +922,18 @@ packages: dependency: "direct main" description: name: pdf - sha256: "586d3debf5432e5377044754032cfa53ab45e9abf371d4865e9ad5019570e246" + sha256: "70d84154dc5b6ddf28eee6c012510a4cbbebb3a1879c0957e05364a95e8f3832" url: "https://pub.dev" source: hosted - version: "3.10.1" + version: "3.10.3" + pdf_widget_wrapper: + dependency: transitive + description: + name: pdf_widget_wrapper + sha256: e9d31fd7782ce28ae346b127ea7d1cd748d799bddee379f31191693610e23749 + url: "https://pub.dev" + source: hosted + version: "1.0.1" percent_indicator: dependency: "direct main" description: @@ -938,12 +951,13 @@ packages: source: hosted version: "10.2.0" permission_handler_android: - dependency: transitive + dependency: "direct overridden" description: - name: permission_handler_android - sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2" - url: "https://pub.dev" - source: hosted + path: permission_handler_android + ref: agp8-compat + resolved-ref: ad409917f0db1b1ad6a2c74d3c6b3b35f331a81e + url: "https://github.com/deckerst/flutter-permission-handler.git" + source: git version: "10.2.0" permission_handler_apple: dependency: transitive @@ -973,10 +987,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.4.0" pin_code_fields: dependency: "direct main" description: @@ -1001,6 +1015,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + url: "https://pub.dev" + source: hosted + version: "3.7.3" polylabel: dependency: transitive description: @@ -1021,10 +1043,10 @@ packages: dependency: "direct main" description: name: printing - sha256: c5c19dd852e95aa140141df13fa304f079a20c4a14a66de5275a0f811240aeec + sha256: "6aa86779d51f1c60608defee7b231e1133ab9b00f63b3b71abfa85cb39898571" url: "https://pub.dev" source: hosted - version: "5.10.3" + version: "5.10.4" process: dependency: transitive description: @@ -1077,10 +1099,10 @@ packages: dependency: transitive description: name: screen_brightness_android - sha256: "69231ea2cf83a627120302a82e98e739ee7e97c1077b58fd0ff0ad954e95a36e" + sha256: "3df10961e3a9e968a5e076fe27e7f4741fa8a1d3950bdeb48cf121ed529d0caf" url: "https://pub.dev" source: hosted - version: "0.1.0+1" + version: "0.1.0+2" screen_brightness_ios: dependency: transitive description: @@ -1117,10 +1139,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b" + sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" shared_preferences_android: dependency: transitive description: @@ -1133,10 +1155,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "0c1c16c56c9708aa9c361541a6f0e5cc6fc12a3232d866a687a7b7db30032b07" + sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_linux: dependency: transitive description: @@ -1242,10 +1264,10 @@ packages: dependency: "direct main" description: name: sqflite - sha256: acf091c6e55c50d00b30b8532b2dd23e393cf775861665ebd0f15cdd6ebfb079 + sha256: "3a82c9a216b46b88617e3714dd74227eaca20c501c4abcc213e56db26b9caa00" url: "https://pub.dev" source: hosted - version: "2.2.8+1" + version: "2.2.8+2" sqflite_common: dependency: transitive description: @@ -1283,7 +1305,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "3c3471b548b3e8a2fbeefb9eb761f442b5cc9fbf" + resolved-ref: "096f964597703830f384d1a336e7752a6531f2a2" url: "https://github.com/deckerst/aves_streams_channel.git" source: git version: "0.3.0" @@ -1323,26 +1345,26 @@ packages: dependency: "direct dev" description: name: test - sha256: a5fcd2d25eeadbb6589e80198a47d6a464ba3e2049da473943b8af9797900c2d + sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4" url: "https://pub.dev" source: hosted - version: "1.22.0" + version: "1.24.1" test_api: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" test_core: dependency: transitive description: name: test_core - sha256: "0ef9755ec6d746951ba0aabe62f874b707690b5ede0fecc818b138fcc9b14888" + sha256: "5138dbffb77b2289ecb12b81c11ba46036590b72a64a7a90d6ffb880f1a29e93" url: "https://pub.dev" source: hosted - version: "0.4.20" + version: "0.5.1" transparent_image: dependency: "direct main" description: @@ -1363,10 +1385,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -1379,18 +1401,18 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e" + sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3 url: "https://pub.dev" source: hosted - version: "6.1.10" + version: "6.1.11" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "22f8db4a72be26e9e3a4aa3f194b1f7afbc76d20ec141f84be1d787db2155cbd" + sha256: "7aac14be5f4731b923cc697ae2d42043945076cd0dbb8806baecc92c1dc88891" url: "https://pub.dev" source: hosted - version: "6.0.31" + version: "6.0.33" url_launcher_ios: dependency: transitive description: @@ -1451,26 +1473,27 @@ packages: dependency: transitive description: name: vm_service - sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7 + sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe url: "https://pub.dev" source: hosted - version: "9.4.0" + version: "11.3.0" volume_controller: dependency: "direct main" description: - name: volume_controller - sha256: "3bcaadd0e3298286c4ef3b758a3ea44fc98a9abe24d0e7ef087bfab72a4b6924" - url: "https://pub.dev" - source: hosted + path: "." + ref: agp8-compat + resolved-ref: b5eddb8c3501e16814f39873d7fba4a73aa0f080 + url: "https://github.com/deckerst/volume_controller.git" + source: git version: "2.0.6" watcher: dependency: transitive description: name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.0" web_socket_channel: dependency: transitive description: @@ -1483,10 +1506,10 @@ packages: dependency: transitive description: name: webdriver - sha256: ef67178f0cc7e32c1494645b11639dd1335f1d18814aa8435113a92e9ef9d841 + sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" webkit_inspection_protocol: dependency: transitive description: @@ -1503,6 +1526,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.4" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae" + url: "https://pub.dev" + source: hosted + version: "1.1.0" wkt_parser: dependency: transitive description: @@ -1523,10 +1554,10 @@ packages: dependency: "direct main" description: name: xml - sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" yaml: dependency: transitive description: @@ -1536,5 +1567,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=2.19.6 <3.0.0" - flutter: ">=3.7.12" + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index e1cf79658..639a13adc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,8 +13,8 @@ publish_to: none environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper - flutter: 3.7.12 - sdk: ">=2.19.6 <4.0.0" + flutter: 3.10.0 + sdk: ">=3.0.0 <4.0.0" # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor dependencies: @@ -46,8 +46,11 @@ dependencies: path: plugins/aves_utils charts_flutter: git: - url: https://github.com/fzyzcjy/charts.git - ref: master + #url: https://github.com/fzyzcjy/charts.git + #ref: master + url: https://github.com/deckerst/flutter_google_charts.git + # fzyzcjy's master commit de76a46 (Sep 26, 2022) is incompatible with Flutter v3.10 + ref: aves path: charts_flutter collection: connectivity_plus: @@ -66,6 +69,12 @@ dependencies: ref: aves flex_color_picker: floating: + git: + # url: https://github.com/wrbl606/floating.git + # # v2.0.0 is incompatible with AGP8 + # ref: main + url: https://github.com/deckerst/floating.git + ref: kotlin-jvm-target fluster: flutter_displaymode: flutter_highlight: @@ -116,6 +125,41 @@ dev_dependencies: shared_preferences_platform_interface: test: +dependency_overrides: + # as of Flutter beta v3.10.0-1.5.pre, `flutter_driver` + # constrains `material_color_utilities` to v0.2.0, which + # constrains `dynamic_color` to v1.6.4, which is incompatible with AGP8 + material_color_utilities: ^0.5.0 + device_info_plus: + git: + url: https://github.com/fluttercommunity/plus_plugins.git + # v9:0:0 is incompatible with AGP8 + ref: main + path: packages/device_info_plus/device_info_plus + package_info_plus: + git: + url: https://github.com/fluttercommunity/plus_plugins.git + # v4:0:0 is incompatible with AGP8 + ref: main + path: packages/package_info_plus/package_info_plus + # cf https://github.com/Baseflow/flutter-google-api-availability/pull/43 + google_api_availability_android: + git: + url: https://github.com/deckerst/flutter-google-api-availability.git + ref: agp8-compat + path: google_api_availability_android + # cf https://github.com/Baseflow/flutter-permission-handler/pull/1039 + permission_handler_android: + git: + url: https://github.com/deckerst/flutter-permission-handler.git + ref: agp8-compat + path: permission_handler_android + # cf https://github.com/kurenai7968/volume_controller/pull/19 + volume_controller: + git: + url: https://github.com/deckerst/volume_controller.git + ref: agp8-compat + flutter: assets: - assets/ @@ -155,27 +199,27 @@ flutter: # adapts from package `flutter_highlight` v0.7.0 # # `OutputBuffer` in `/services/common/output_buffer.dart` -# adapts from Flutter v3.3.3 `_OutputBuffer` in `/foundation/consolidate_response.dart` +# adapts from Flutter v3.10.0 `_OutputBuffer` in `/foundation/consolidate_response.dart` # # `TvLicensePage` in `/widgets/about/tv_license_page.dart` -# adapts from Flutter v3.7.7 `_LicenseData` in `/material/about.dart` +# adapts from Flutter v3.10.0 `_LicenseData` in `/material/about.dart` # and `_PackageLicensePage` in `/material/about.dart` # # `OverlaySnackBar` in `/widgets/common/action_mixins/overlay_snack_bar.dart` -# adapts from Flutter v3.3.3 `SnackBar` in `/material/snack_bar.dart` +# adapts from Flutter v3.10.0 `SnackBar` in `/material/snack_bar.dart` # # `EagerScaleGestureRecognizer` in `/widgets/common/behaviour/eager_scale_gesture_recognizer.dart` -# adapts from Flutter v3.3.3 `ScaleGestureRecognizer` in `/gestures/scale.dart` +# adapts from Flutter v3.10.0 `ScaleGestureRecognizer` in `/gestures/scale.dart` # # `KnownExtentScrollPhysics` in `/widgets/common/behaviour/known_extent_scroll_physics.dart` -# adapts from Flutter v3.3.3 `FixedExtentScrollPhysics` in `/widgets/list_wheel_scroll_view.dart` +# adapts from Flutter v3.10.0 `FixedExtentScrollPhysics` in `/widgets/list_wheel_scroll_view.dart` # # `TransitionImage` in `/widgets/common/fx/transition_image.dart` -# adapts from Flutter v3.3.3 `_ImageState` in `/widgets/image.dart` +# adapts from Flutter v3.10.0 `_ImageState` in `/widgets/image.dart` # and `DecorationImagePainter` in `/painting/decoration_image.dart` # # `_RenderSliverKnownExtentBoxAdaptor` in `/widgets/common/grid/sliver.dart` -# adapts from Flutter v3.3.3 `RenderSliverFixedExtentBoxAdaptor` in `/rendering/sliver_fixed_extent_list.dart` +# adapts from Flutter v3.10.0 `RenderSliverFixedExtentBoxAdaptor` in `/rendering/sliver_fixed_extent_list.dart` # # `CollectionSearchDelegate`, `SearchPageRoute` in `/widgets/search/search_delegate.dart` -# adapts from Flutter v3.3.3 `SearchDelegate`, `_SearchPageRoute` in `/material/search.dart` +# adapts from Flutter v3.10.0 `SearchDelegate`, `_SearchPageRoute` in `/material/search.dart` diff --git a/shaders.sksl.json b/shaders.sksl.json index 3d907597d..5e5087ff8 100644 --- a/shaders.sksl.json +++ b/shaders.sksl.json @@ -1 +1 @@ -{"platform":"android","name":"SM G970N","engineRevision":"1a65d409c7a1438a34d21b60bf30a6fd5db59314","data":{"DASAAAAAQAAWAABAYAAQBYH7777Z6QQBAEAAAAAAEAAAAAAAEBSAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADgAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCk7Cgl9CglvdXRwdXRDb2xvcl9TMCA9IG91dHB1dENvbG9yX1MwICogdGV4Q29sb3I7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAABAEAAAABJYQAAAAAACAIAAAAAWCBAAAIBAAAAANAECAZAAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IHN1YnNldENvb3JkLng7CgljbGFtcGVkQ29vcmQueSA9IGNsYW1wKHN1YnNldENvb3JkLnksIHVjbGFtcF9TMV9jMF9jMF9jMC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAudyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABYQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB5AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAsQEAAHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAWXW3ZEQAAAADAAAAAGATHIBICYCAAAEBP2LBIPAAAAAIAAAAAEARRALJ3F5SMAAAABQAAAABABTUEURMBAAACAH5FYUHQAAAAAAAEAAAAAZ4RGGRCQFAEAAAAAAAAAGARP2LVJPAAAAAAAAEAAAABSKRXZFAUHQAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"CgAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAHSADQAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAQAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAAAAEAAAABJYQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAPAEAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxM107CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IFNtb290aF9TMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBjb29yZCwgaGFsZjIgb2Zmc2V0QW5kS2VybmVsKSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfaW5wdXQsIChjb29yZCArIG9mZnNldEFuZEtlcm5lbC54ICogdUluY3JlbWVudF9TMV9jMCkpICogb2Zmc2V0QW5kS2VybmVsLnk7Cn0KaGFsZjQgR2F1c3NpYW5Db252b2x1dGlvbl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBjb2xvciA9IGhhbGY0KDApOwoJZmxvYXQyIGNvb3JkID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7Cglmb3IgKGludCBpPTA7IGk8MTM7ICsraSkgCgl7CgkJY29sb3IgKz0gU21vb3RoX1MxX2MwKF9pbnB1dCwgY29vcmQsIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldKTsKCX0KCXJldHVybiBjb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"CgAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQAAEAQAAAAGQCBAMQAAAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzAueSwgdWNsYW1wX1MxX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"CgAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADQAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpICogb3V0cHV0Q29sb3JfUzApKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAFBQATAAAAAAFAAMAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAABABAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgRWxsaXB0aWNhbFJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJZmxvYXQyIFogPSBkeHkgKiB1aW52UmFkaWlYWV9TMS54eTsKCWhhbGYgaW1wbGljaXQgPSBoYWxmKGRvdChaLCBkeHkpIC0gMS4wKTsKCWhhbGYgZ3JhZF9kb3QgPSBoYWxmKDQuMCAqIGRvdChaLCBaKSk7CglncmFkX2RvdCA9IG1heChncmFkX2RvdCwgMS4wZS00KTsKCWhhbGYgYXBwcm94X2Rpc3QgPSBpbXBsaWNpdCAqIGhhbGYoaW52ZXJzZXNxcnQoZ3JhZF9kb3QpKTsKCWhhbGYgYWxwaGEgPSBjbGFtcCgwLjUgKyBhcHByb3hfZGlzdCwgMC4wLCAxLjApOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRWxsaXB0aWNhbFJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAA3AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9ICgoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCkgKiBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQHEB4XIQAQAADQAAAABAAAAAAABAEMVDOMCJKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABRBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSA/IDEgOiAwKSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MxX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IHhfcGx1c18xPXZhcmNjb29yZF9TMC54LCB5PXZhcmNjb29yZF9TMC55OwoJaGFsZiBjb3ZlcmFnZTsKCWlmICgwID09IHhfcGx1c18xKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoeSk7Cgl9CgllbHNlIAoJewoJCWZsb2F0IGZuID0geF9wbHVzXzEgKiAoeF9wbHVzXzEgLSAyKTsKCQlmbiA9IGZtYSh5LHksIGZuKTsKCQlmbG9hdCBmbndpZHRoID0gZndpZHRoKGZuKTsKCQljb3ZlcmFnZSA9IC41IC0gaGFsZihmbi9mbndpZHRoKTsKCQljb3ZlcmFnZSA9IGNsYW1wKGNvdmVyYWdlLCAwLCAxKTsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAIAAEAAAABJYQAAAAAQAAIAAAAAWCBACAABAAAAANAECAZAAEAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IGNsYW1wKHN1YnNldENvb3JkLngsIHVjbGFtcF9TMV9jMF9jMF9jMC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueik7CgljbGFtcGVkQ29vcmQueSA9IHN1YnNldENvb3JkLnk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAANAAAAALHCKLMRAAAAAAAAABAAAAAGJBCFLQVBWAQAAAAAAQAAAAAMACQCAACAAAAA2AIBAEIAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAeAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1Y2lyY2xlRGF0YV9TMV9jMDsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBDaXJjbGVCbHVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjIgdmVjID0gaGFsZjIoKHNrX0ZyYWdDb29yZC54eSAtIGZsb2F0Mih1Y2lyY2xlRGF0YV9TMV9jMC54eSkpICogZmxvYXQodWNpcmNsZURhdGFfUzFfYzAudykpOwoJaGFsZiBkaXN0ID0gbGVuZ3RoKHZlYykgKyAoMC41IC0gdWNpcmNsZURhdGFfUzFfYzAueikgKiB1Y2lyY2xlRGF0YV9TMV9jMC53OwoJcmV0dXJuIGhhbGY0KE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgZmxvYXQyKGhhbGYyKGRpc3QsIDAuNSkpKS53d3d3KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKENpcmNsZUJsdXJfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACfAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9ICgoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCkgKiBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAACU53QJEKAAAAAAMAAAAAIAAAAAAGIRDFB2XASAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAACrBAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjbGVfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41ID8gMSA6IDApKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShfc3JjLCBDaXJjbGVfUzFfYzAoX3NyYykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpICogaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAoAIAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAuAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9ICgoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCkgKiBoYWxmNCgxKSkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACfAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEaXN0YW5jZUZpZWxkUGF0aAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQyIHV2ID0gdlRleHR1cmVDb29yZHNfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLnJycnI7Cgl9CgloYWxmIGRpc3RhbmNlID0gNy45Njg3NSoodGV4Q29sb3IuciAtIDAuNTAxOTYwNzg0MzEpOwoJaGFsZiBhZndpZHRoOwoJYWZ3aWR0aCA9IGFicygwLjY1KmhhbGYoZEZkeCh2SW50VGV4dHVyZUNvb3Jkc19TMC54KSkpOwoJaGFsZiB2YWwgPSBzbW9vdGhzdGVwKC1hZndpZHRoLCBhZndpZHRoLCBkaXN0YW5jZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KHZhbCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"CgAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAALAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBSUmVjdFNoYWRvdwoJaGFsZjMgc2hhZG93UGFyYW1zOwoJc2hhZG93UGFyYW1zID0gdmluU2hhZG93UGFyYW1zX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZiBkID0gbGVuZ3RoKHNoYWRvd1BhcmFtcy54eSk7CglmbG9hdDIgdXYgPSBmbG9hdDIoc2hhZG93UGFyYW1zLnogKiAoMS4wIC0gZCksIDAuNSk7CgloYWxmIGZhY3RvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLjAwMHIuYTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZmFjdG9yKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAOAAAAaW5TaGFkb3dQYXJhbXMAAAAAAAA=","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAAAAAAQFV5W6JEAAAAAYAAAABQEZ2AKAWAQAABAL6SYKDYAAAACAAAAAAQEGIAAAAACAWTWL3EYAAAADAAAAACADHIJJCYCAAAEAP2LRIPAAAAAIAAAAAAABTALI3F5SOAIAABQAAAAAABTUEUZMBAAAAAH5FYUXQAAAAAAAEAAAAAZMRGOQCQFQEAAAAAAAAAGARL2LXJHAAEAAAAAEAAAABSCQX5FQUHQAAAAAAAAAACAA4AAAABAACAAAACCAYAAAAA":"CgAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc182X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAMMHAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwpoYWxmNCBTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IF9jb29yZHM7CglyZXR1cm4gaGFsZjQobWl4KHVzdGFydF9TMV9jMF9jMF9jMCwgdWVuZF9TMV9jMF9jMF9jMCwgaGFsZihfdG1wXzFfY29vcmRzLngpKSk7Cn0KaGFsZjQgTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfM19jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKCXJldHVybiBoYWxmNChoYWxmNChoYWxmKF90bXBfM19jb29yZHMueCkgKyAxZS0wNSwgMS4wLCAwLjAsIDAuMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgdCA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShfdG1wXzRfaW5Db2xvcik7CgloYWxmNCBvdXRDb2xvcjsKCWlmICghYm9vbChpbnQoMSkpICYmIHQueSA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSBoYWxmNCgwLjApOwoJfQoJZWxzZSBpZiAodC54IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IHVsZWZ0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIGlmICh0LnggPiAxLjApIAoJewoJCW91dENvbG9yID0gdXJpZ2h0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIAoJewoJCW91dENvbG9yID0gU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgY29sb3JfeGZvcm1fUzFfYzAoZmxvYXQ0IGNvbG9yKSAKewoJY29sb3IucmdiICo9IGNvbG9yLmE7CglyZXR1cm4gaGFsZjQoY29sb3IpOwp9CmhhbGY0IENvbG9yU3BhY2VYZm9ybV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gY29sb3JfeGZvcm1fUzFfYzAoQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCkpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ29sb3JTcGFjZVhmb3JtX1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gKGhhbGY0KDEuMCkgLSBvdXRwdXRfUzEpICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBQU7BTXIAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"CgAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAArAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAD2AAAAAAQAVSWGRIBAAADAAAAACAAAAAAQCGEIQOZLBIQAAAABQAAAAAAAAAAAAFAAMAAAABAAAAAAABBAMAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAARQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAAAAIAAAABLAIABAAAAABAEGABBAMAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAC2AgAAdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKE1hdHJpeEVmZmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb2xvcl9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzAueCwgdWNsYW1wX1MxX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAIBAIAAAABLCIIBAAAAABAEGABBAMAACAIAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAADJAwAAdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoTWF0cml4RWZmZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvbG9yX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEADZABYAAAIAAAAAACQAGAAAAAQAAAAAAAQQG":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAADUAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAAYQADAAAEAFEURUKQKAAAYAAAAAAAAIAAAABSCICWKY2FAEAAAMAAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB+BQAAY29uc3QgaW50IGtGaWxsQldfUzFfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzFfYzA7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgUmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMV9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzFfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MxX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAE0DAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMC54eSwgdWNsYW1wX1MxX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAKPABAAAAAAB2AAAAAAACAAAAAEBSAAAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACbBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBFbGxpcHRpY2FsUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CglmbG9hdDIgWiA9IGR4eSAqIHVpbnZSYWRpaVhZX1MxLnh5OwoJaGFsZiBpbXBsaWNpdCA9IGhhbGYoZG90KFosIGR4eSkgLSAxLjApOwoJaGFsZiBncmFkX2RvdCA9IGhhbGYoNC4wICogZG90KFosIFopKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjBlLTQpOwoJaGFsZiBhcHByb3hfZGlzdCA9IGltcGxpY2l0ICogaGFsZihpbnZlcnNlc3FydChncmFkX2RvdCkpOwoJaGFsZiBhbHBoYSA9IGNsYW1wKDAuNSArIGFwcHJveF9kaXN0LCAwLjAsIDEuMCk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEVsbGlwdGljYWxSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADgAAAHJhZGlpX3NlbGVjdG9yAAAZAAAAY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cwAAABUAAABhYV9ibG9hdF9hbmRfY292ZXJhZ2UAAAAHAAAAcmFkaWlfeAAHAAAAcmFkaWlfeQAEAAAAc2tldxkAAAB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlAAAABQAAAGNvbG9yAAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAHMCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwKS5ycnJyOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA=="}} \ No newline at end of file +{"platform":"android","name":"SM G970N","engineRevision":"d44b5a94c976fbb65815374f61ab5392a220b084","data":{"DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAHSADQAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAQAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQHEB4XIQAQAADQAAAABAAAAAAABAEMVDOMCJKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABRBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSA/IDEgOiAwKSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MxX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IHhfcGx1c18xPXZhcmNjb29yZF9TMC54LCB5PXZhcmNjb29yZF9TMC55OwoJaGFsZiBjb3ZlcmFnZTsKCWlmICgwID09IHhfcGx1c18xKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoeSk7Cgl9CgllbHNlIAoJewoJCWZsb2F0IGZuID0geF9wbHVzXzEgKiAoeF9wbHVzXzEgLSAyKTsKCQlmbiA9IGZtYSh5LHksIGZuKTsKCQlmbG9hdCBmbndpZHRoID0gZndpZHRoKGZuKTsKCQljb3ZlcmFnZSA9IC41IC0gaGFsZihmbi9mbndpZHRoKTsKCQljb3ZlcmFnZSA9IGNsYW1wKGNvdmVyYWdlLCAwLCAxKTsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAFBQATAAAAAAFAAMAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAABABAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgRWxsaXB0aWNhbFJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJZmxvYXQyIFogPSBkeHkgKiB1aW52UmFkaWlYWV9TMS54eTsKCWhhbGYgaW1wbGljaXQgPSBoYWxmKGRvdChaLCBkeHkpIC0gMS4wKTsKCWhhbGYgZ3JhZF9kb3QgPSBoYWxmKDQuMCAqIGRvdChaLCBaKSk7CglncmFkX2RvdCA9IG1heChncmFkX2RvdCwgMS4wZS00KTsKCWhhbGYgYXBwcm94X2Rpc3QgPSBpbXBsaWNpdCAqIGhhbGYoaW52ZXJzZXNxcnQoZ3JhZF9kb3QpKTsKCWhhbGYgYWxwaGEgPSBjbGFtcCgwLjUgKyBhcHByb3hfZGlzdCwgMC4wLCAxLjApOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRWxsaXB0aWNhbFJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAA7AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAAYQADAAAEAFEURUKQKAAAYAAAAAAAAIAAAABSCICWKY2FAEAAAMAAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB+BQAAY29uc3QgaW50IGtGaWxsQldfUzFfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzFfYzA7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgUmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMV9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzFfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MxX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACfAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEaXN0YW5jZUZpZWxkUGF0aAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQyIHV2ID0gdlRleHR1cmVDb29yZHNfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLnJycnI7Cgl9CgloYWxmIGRpc3RhbmNlID0gNy45Njg3NSoodGV4Q29sb3IuciAtIDAuNTAxOTYwNzg0MzEpOwoJaGFsZiBhZndpZHRoOwoJYWZ3aWR0aCA9IGFicygwLjY1KmhhbGYoZEZkeCh2SW50VGV4dHVyZUNvb3Jkc19TMC54KSkpOwoJaGFsZiB2YWwgPSBzbW9vdGhzdGVwKC1hZndpZHRoLCBhZndpZHRoLCBkaXN0YW5jZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KHZhbCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"CgAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADdAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIG91dHB1dENvbG9yX1MwKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEADZABYAAAIAAAAAACQAGAAAAAQAAAAAAAQQG":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAADUAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAAAAAAQFV5W6JEAAAAAYAAAABQEZ2AKAWAQAABAL6SYKDYAAAACAAAAAAQEGIAAAAACAWTWL3EYAAAADAAAAACADHIJJCYCAAAEAP2LRIPAAAAAIAAAAAAABTALI3F5SOAIAABQAAAAAABTUEUZMBAAAAAH5FYUXQAAAAAAAEAAAAAZMRGOQCQFQEAAAAAAAAAGARL2LXJHAAEAAAAAEAAAABSCQX5FQUHQAAAAAAAAAACAA4AAAABAACAAAACCAYAAAAA":"CgAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc182X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAMMHAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwpoYWxmNCBTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IF9jb29yZHM7CglyZXR1cm4gaGFsZjQobWl4KHVzdGFydF9TMV9jMF9jMF9jMCwgdWVuZF9TMV9jMF9jMF9jMCwgaGFsZihfdG1wXzFfY29vcmRzLngpKSk7Cn0KaGFsZjQgTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfM19jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKCXJldHVybiBoYWxmNChoYWxmNChoYWxmKF90bXBfM19jb29yZHMueCkgKyAxZS0wNSwgMS4wLCAwLjAsIDAuMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgdCA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShfdG1wXzRfaW5Db2xvcik7CgloYWxmNCBvdXRDb2xvcjsKCWlmICghYm9vbChpbnQoMSkpICYmIHQueSA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSBoYWxmNCgwLjApOwoJfQoJZWxzZSBpZiAodC54IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IHVsZWZ0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIGlmICh0LnggPiAxLjApIAoJewoJCW91dENvbG9yID0gdXJpZ2h0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIAoJewoJCW91dENvbG9yID0gU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgY29sb3JfeGZvcm1fUzFfYzAoZmxvYXQ0IGNvbG9yKSAKewoJY29sb3IucmdiICo9IGNvbG9yLmE7CglyZXR1cm4gaGFsZjQoY29sb3IpOwp9CmhhbGY0IENvbG9yU3BhY2VYZm9ybV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gY29sb3JfeGZvcm1fUzFfYzAoQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCkpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ29sb3JTcGFjZVhmb3JtX1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gKGhhbGY0KDEuMCkgLSBvdXRwdXRfUzEpICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAD2AAAAAAQAVSWGRIBAAADAAAAACAAAAAAQCGEIQOZLBIQAAAABQAAAAAAAAAAAAFAAMAAAABAAAAAAABBAMAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAARQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAACU53QJEKAAAAAAMAAAAAIAAAAAAGIRDFB2XASAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAC4BAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjbGVfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41ID8gMSA6IDApKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShfc3JjLCBDaXJjbGVfUzFfYzAoX3NyYykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQDAAAAAAAAAEAAAABJGQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAO4EAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFs0XTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgU21vb3RoX1MxX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIGNvb3JkLCBoYWxmMiBvZmZzZXRBbmRLZXJuZWwpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCwgKGNvb3JkICsgb2Zmc2V0QW5kS2VybmVsLnggKiB1SW5jcmVtZW50X1MxX2MwKSkgKiBvZmZzZXRBbmRLZXJuZWwueTsKfQpoYWxmNCBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IGNvbG9yID0gaGFsZjQoMCk7CglmbG9hdDIgY29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZvciAoaW50IGk9MDsgaTw0OyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAIBAIAAAABLCIIBAAAAABAEGABBAMAACAIAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAADJAwAAdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoTWF0cml4RWZmZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvbG9yX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAANAAAAALHCKLMRAAAAAAAAABAAAAAGJBCFLQVBWAQAAAAAAQAAAAAMACQCAACAAAAA2AIBAEIAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAeAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1Y2lyY2xlRGF0YV9TMV9jMDsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBDaXJjbGVCbHVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjIgdmVjID0gaGFsZjIoKHNrX0ZyYWdDb29yZC54eSAtIGZsb2F0Mih1Y2lyY2xlRGF0YV9TMV9jMC54eSkpICogZmxvYXQodWNpcmNsZURhdGFfUzFfYzAudykpOwoJaGFsZiBkaXN0ID0gbGVuZ3RoKHZlYykgKyAoMC41IC0gdWNpcmNsZURhdGFfUzFfYzAueikgKiB1Y2lyY2xlRGF0YV9TMV9jMC53OwoJcmV0dXJuIGhhbGY0KE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgZmxvYXQyKGhhbGYyKGRpc3QsIDAuNSkpKS53d3d3KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKENpcmNsZUJsdXJfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAIAAEAAAABJYQAAAAAQAAIAAAAAWCBACAABAAAAANAECAZAAEAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IGNsYW1wKHN1YnNldENvb3JkLngsIHVjbGFtcF9TMV9jMF9jMF9jMC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueik7CgljbGFtcGVkQ29vcmQueSA9IHN1YnNldENvb3JkLnk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAAAAEAAAABJYQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAPAEAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxM107CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IFNtb290aF9TMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBjb29yZCwgaGFsZjIgb2Zmc2V0QW5kS2VybmVsKSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfaW5wdXQsIChjb29yZCArIG9mZnNldEFuZEtlcm5lbC54ICogdUluY3JlbWVudF9TMV9jMCkpICogb2Zmc2V0QW5kS2VybmVsLnk7Cn0KaGFsZjQgR2F1c3NpYW5Db252b2x1dGlvbl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBjb2xvciA9IGhhbGY0KDApOwoJZmxvYXQyIGNvb3JkID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7Cglmb3IgKGludCBpPTA7IGk8MTM7ICsraSkgCgl7CgkJY29sb3IgKz0gU21vb3RoX1MxX2MwKF9pbnB1dCwgY29vcmQsIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldKTsKCX0KCXJldHVybiBjb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAHMCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwKS5ycnJyOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAAAAIAAAABLAIABAAAAABAEGABBAMAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAC2AgAAdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKE1hdHJpeEVmZmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb2xvcl9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAsQEAAHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAE0DAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMC54eSwgdWNsYW1wX1MxX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzAueCwgdWNsYW1wX1MxX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"CgAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAALAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBSUmVjdFNoYWRvdwoJaGFsZjMgc2hhZG93UGFyYW1zOwoJc2hhZG93UGFyYW1zID0gdmluU2hhZG93UGFyYW1zX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZiBkID0gbGVuZ3RoKHNoYWRvd1BhcmFtcy54eSk7CglmbG9hdDIgdXYgPSBmbG9hdDIoc2hhZG93UGFyYW1zLnogKiAoMS4wIC0gZCksIDAuNSk7CgloYWxmIGZhY3RvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLjAwMHIuYTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZmFjdG9yKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAOAAAAaW5TaGFkb3dQYXJhbXMAAAAAAAA=","DASAAAAAQAAWAABAYAAQBYH7777Z6QQBAEAAAAAAEAAAAAAAEBSAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADgAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCk7Cgl9CglvdXRwdXRDb2xvcl9TMCA9IG91dHB1dENvbG9yX1MwICogdGV4Q29sb3I7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBQU7BTXIAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"CgAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAArAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAABAEAAAABJYQAAAAAACAIAAAAAWCBAAAIBAAAAANAECAZAAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IHN1YnNldENvb3JkLng7CgljbGFtcGVkQ29vcmQueSA9IGNsYW1wKHN1YnNldENvb3JkLnksIHVjbGFtcF9TMV9jMF9jMF9jMC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAudyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACsAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"CgAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQAAEAQAAAAGQCBAMQAAAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzAueSwgdWNsYW1wX1MxX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAKPABAAAAAAB2AAAAAAACAAAAAEBSAAAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACbBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBFbGxpcHRpY2FsUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CglmbG9hdDIgWiA9IGR4eSAqIHVpbnZSYWRpaVhZX1MxLnh5OwoJaGFsZiBpbXBsaWNpdCA9IGhhbGYoZG90KFosIGR4eSkgLSAxLjApOwoJaGFsZiBncmFkX2RvdCA9IGhhbGYoNC4wICogZG90KFosIFopKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjBlLTQpOwoJaGFsZiBhcHByb3hfZGlzdCA9IGltcGxpY2l0ICogaGFsZihpbnZlcnNlc3FydChncmFkX2RvdCkpOwoJaGFsZiBhbHBoYSA9IGNsYW1wKDAuNSArIGFwcHJveF9kaXN0LCAwLjAsIDEuMCk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEVsbGlwdGljYWxSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADgAAAHJhZGlpX3NlbGVjdG9yAAAZAAAAY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cwAAABUAAABhYV9ibG9hdF9hbmRfY292ZXJhZ2UAAAAHAAAAcmFkaWlfeAAHAAAAcmFkaWlfeQAEAAAAc2tldxkAAAB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlAAAABQAAAGNvbG9yAAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAWXW3ZEQAAAADAAAAAGATHIBICYCAAAEBP2LBIPAAAAAIAAAAAEARRALJ3F5SMAAAABQAAAABABTUEURMBAAACAH5FYUHQAAAAAAAEAAAAAZ4RGGRCQFAEAAAAAAAAAGARP2LVJPAAAAAAAAEAAAABSKRXZFAUHQAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"CgAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABYQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB5AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA"}} \ No newline at end of file From b1920dbe1cafb0257ec04cb8e1298ca7af3fbe41 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 12:50:08 +0200 Subject: [PATCH 15/35] lab: transform --- android/app/src/main/AndroidManifest.xml | 9 + .../deckers/thibault/aves/MainActivity.kt | 13 + lib/app_mode.dart | 1 + lib/l10n/app_en.arb | 11 + lib/main_common.dart | 4 +- lib/main_play_test_editor.dart | 17 + lib/model/app/dependencies.dart | 6 + lib/model/settings/enums/widget_shape.dart | 2 +- .../state.dart => model/view_state.dart} | 14 + lib/theme/icons.dart | 324 ++++---- lib/utils/math_utils.dart | 41 + lib/view/src/editor/enums.dart | 57 ++ lib/view/view.dart | 1 + lib/widgets/aves_app.dart | 5 +- lib/widgets/collection/collection_page.dart | 1 + lib/widgets/collection/grid/tile.dart | 1 + .../common/basic/multi_cross_fader.dart | 4 + lib/widgets/common/extensions/geometry.dart | 7 + .../common/fx/checkered_decoration.dart | 2 +- .../common/fx/dashed_path_painter.dart | 142 ++++ lib/widgets/common/fx/transition_image.dart | 3 +- lib/widgets/common/grid/item_tracker.dart | 2 +- lib/widgets/editor/control_panel.dart | 137 ++++ lib/widgets/editor/entry_editor_page.dart | 136 ++++ lib/widgets/editor/image.dart | 224 ++++++ .../editor/transform/control_panel.dart | 196 +++++ lib/widgets/editor/transform/controller.dart | 88 +++ lib/widgets/editor/transform/crop_region.dart | 48 ++ lib/widgets/editor/transform/cropper.dart | 734 ++++++++++++++++++ lib/widgets/editor/transform/handles.dart | 120 +++ lib/widgets/editor/transform/painter.dart | 131 ++++ .../editor/transform/transformation.dart | 87 +++ .../filter_grids/common/filter_tile.dart | 1 + lib/widgets/home_page.dart | 226 +++--- lib/widgets/home_widget.dart | 2 +- lib/widgets/intent.dart | 24 + lib/widgets/viewer/overlay/minimap.dart | 95 ++- .../viewer/overlay/wallpaper_buttons.dart | 2 +- lib/widgets/viewer/visual/conductor.dart | 4 +- .../viewer/visual/entry_page_view.dart | 15 +- lib/widgets/viewer/visual/raster.dart | 2 +- lib/widgets/viewer/visual/vector.dart | 2 +- lib/widgets/viewer/visual/video/cover.dart | 2 +- .../visual/video/subtitle/subtitle.dart | 2 +- .../aves_magnifier/lib/aves_magnifier.dart | 2 +- .../lib/src/controller/controller.dart | 8 +- .../src/controller/controller_delegate.dart | 90 +-- .../lib/src/controller/range.dart | 15 + plugins/aves_magnifier/lib/src/core/core.dart | 168 +++- .../lib/src/core/gesture_detector.dart | 2 +- .../src/core/scale_gesture_recognizer.dart | 8 +- plugins/aves_magnifier/lib/src/magnifier.dart | 107 --- .../lib/src/pan/edge_hit_detector.dart | 39 +- .../lib/src/scale/scale_boundaries.dart | 136 +++- .../lib/src/scale/scale_level.dart | 4 +- .../aves_magnifier/lib/src/scale/state.dart | 3 - plugins/aves_magnifier/pubspec.lock | 7 + plugins/aves_magnifier/pubspec.yaml | 2 + plugins/aves_model/lib/aves_model.dart | 1 + plugins/aves_model/lib/src/editor/enums.dart | 66 ++ plugins/aves_utils/lib/aves_utils.dart | 1 + .../aves_utils/lib/src/change_notifier.dart | 2 +- plugins/aves_utils/lib/src/vector_utils.dart | 15 + plugins/aves_utils/pubspec.lock | 2 +- plugins/aves_utils/pubspec.yaml | 1 + pubspec.lock | 2 +- pubspec.yaml | 1 + test/model/view_state_test.dart | 90 +++ test/utils/math_utils_test.dart | 9 + untranslated.json | 297 +++++++ 70 files changed, 3409 insertions(+), 614 deletions(-) create mode 100644 lib/main_play_test_editor.dart rename lib/{widgets/viewer/visual/state.dart => model/view_state.dart} (66%) create mode 100644 lib/view/src/editor/enums.dart create mode 100644 lib/widgets/common/extensions/geometry.dart create mode 100644 lib/widgets/common/fx/dashed_path_painter.dart create mode 100644 lib/widgets/editor/control_panel.dart create mode 100644 lib/widgets/editor/entry_editor_page.dart create mode 100644 lib/widgets/editor/image.dart create mode 100644 lib/widgets/editor/transform/control_panel.dart create mode 100644 lib/widgets/editor/transform/controller.dart create mode 100644 lib/widgets/editor/transform/crop_region.dart create mode 100644 lib/widgets/editor/transform/cropper.dart create mode 100644 lib/widgets/editor/transform/handles.dart create mode 100644 lib/widgets/editor/transform/painter.dart create mode 100644 lib/widgets/editor/transform/transformation.dart create mode 100644 lib/widgets/intent.dart create mode 100644 plugins/aves_magnifier/lib/src/controller/range.dart delete mode 100644 plugins/aves_magnifier/lib/src/magnifier.dart create mode 100644 plugins/aves_model/lib/src/editor/enums.dart create mode 100644 plugins/aves_utils/lib/src/vector_utils.dart create mode 100644 test/model/view_state_test.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index eec888a79..014a84516 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -145,6 +145,15 @@ This change eventually prevents building the app with Flutter v3.7.11. + diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt index 2e46d64d2..abab47814 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt @@ -277,6 +277,18 @@ open class MainActivity : FlutterFragmentActivity() { } } + Intent.ACTION_EDIT -> { + (intent.data ?: intent.getParcelableExtraCompat(Intent.EXTRA_STREAM))?.let { uri -> + // MIME type is optional + val type = intent.type ?: intent.resolveType(this) + return hashMapOf( + INTENT_DATA_KEY_ACTION to INTENT_ACTION_EDIT, + INTENT_DATA_KEY_MIME_TYPE to type, + INTENT_DATA_KEY_URI to uri.toString(), + ) + } + } + Intent.ACTION_GET_CONTENT, Intent.ACTION_PICK -> { return hashMapOf( INTENT_DATA_KEY_ACTION to INTENT_ACTION_PICK_ITEMS, @@ -433,6 +445,7 @@ open class MainActivity : FlutterFragmentActivity() { const val MEDIA_WRITE_BULK_PERMISSION_REQUEST = 6 const val PICK_COLLECTION_FILTERS_REQUEST = 7 + const val INTENT_ACTION_EDIT = "edit" const val INTENT_ACTION_PICK_ITEMS = "pick_items" const val INTENT_ACTION_PICK_COLLECTION_FILTERS = "pick_collection_filters" const val INTENT_ACTION_SCREEN_SAVER = "screen_saver" diff --git a/lib/app_mode.dart b/lib/app_mode.dart index 99dd00ef4..8135170b4 100644 --- a/lib/app_mode.dart +++ b/lib/app_mode.dart @@ -9,6 +9,7 @@ enum AppMode { setWallpaper, slideshow, view, + edit, } extension ExtraAppMode on AppMode { diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index b8c620c98..a83d54d89 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -50,7 +50,9 @@ "showButtonLabel": "SHOW", "hideButtonLabel": "HIDE", "continueButtonLabel": "CONTINUE", + "saveCopyButtonLabel": "SAVE COPY", + "applyTooltip": "Apply", "cancelTooltip": "Cancel", "changeTooltip": "Change", "clearTooltip": "Clear", @@ -141,6 +143,15 @@ "entryInfoActionExportMetadata": "Export metadata", "entryInfoActionRemoveLocation": "Remove location", + "editorActionTransform": "Transform", + + "editorTransformCrop": "Crop", + "editorTransformRotate": "Rotate", + + "cropAspectRatioFree": "Free", + "cropAspectRatioOriginal": "Original", + "cropAspectRatioSquare": "Square", + "filterAspectRatioLandscapeLabel": "Landscape", "filterAspectRatioPortraitLabel": "Portrait", "filterBinLabel": "Recycle bin", diff --git a/lib/main_common.dart b/lib/main_common.dart index a02f671be..f525bab0d 100644 --- a/lib/main_common.dart +++ b/lib/main_common.dart @@ -5,7 +5,7 @@ import 'package:aves/services/common/services.dart'; import 'package:aves/widgets/aves_app.dart'; import 'package:flutter/material.dart'; -void mainCommon(AppFlavor flavor) { +void mainCommon(AppFlavor flavor, {Map? debugIntentData}) { // HttpClient.enableTimelineLogging = true; // enable network traffic logging // debugPrintGestureArenaDiagnostics = true; @@ -35,5 +35,5 @@ void mainCommon(AppFlavor flavor) { // ErrorWidget.builder = (details) => ErrorWidget(details.exception); // cf https://docs.flutter.dev/testing/errors - runApp(AvesApp(flavor: flavor)); + runApp(AvesApp(flavor: flavor, debugIntentData: debugIntentData)); } diff --git a/lib/main_play_test_editor.dart b/lib/main_play_test_editor.dart new file mode 100644 index 000000000..95e5f4d6c --- /dev/null +++ b/lib/main_play_test_editor.dart @@ -0,0 +1,17 @@ +import 'package:aves/app_flavor.dart'; +import 'package:aves/main_common.dart'; +import 'package:aves/widgets/intent.dart'; + +// https://developer.android.com/studio/command-line/adb.html#IntentSpec +// adb shell am start -n deckers.thibault.aves.debug/deckers.thibault.aves.MainActivity -a android.intent.action.EDIT -d content://media/external/images/media/183128 -t image/* + +@pragma('vm:entry-point') +void main() => mainCommon( + AppFlavor.play, + debugIntentData: { + IntentDataKeys.action: IntentActions.edit, + IntentDataKeys.mimeType: 'image/*', + IntentDataKeys.uri: 'content://media/external/images/media/183128', + // IntentDataKeys.uri: 'content://media/external/images/media/183534', + }, + ); diff --git a/lib/model/app/dependencies.dart b/lib/model/app/dependencies.dart index 48fdf5e41..794029ea8 100644 --- a/lib/model/app/dependencies.dart +++ b/lib/model/app/dependencies.dart @@ -6,6 +6,7 @@ class Dependencies { static const String bsd3 = 'BSD 3-Clause “Revised” License'; static const String eclipse1 = 'Eclipse Public License 1.0'; static const String mit = 'MIT License'; + static const String zlib = 'zlib License'; static const List androidDependencies = [ Dependency( @@ -369,6 +370,11 @@ class Dependencies { license: bsd2, sourceUrl: 'https://github.com/google/tuple.dart', ), + Dependency( + name: 'Vector Math', + license: '$zlib, $bsd3', + sourceUrl: 'https://github.com/google/vector_math.dart', + ), Dependency( name: 'XML', license: mit, diff --git a/lib/model/settings/enums/widget_shape.dart b/lib/model/settings/enums/widget_shape.dart index adb2d6730..28a64f3ab 100644 --- a/lib/model/settings/enums/widget_shape.dart +++ b/lib/model/settings/enums/widget_shape.dart @@ -4,7 +4,7 @@ import 'package:flutter/painting.dart'; extension ExtraWidgetShape on WidgetShape { Path path(Size widgetSize, double devicePixelRatio) { - final rect = Rect.fromLTWH(0, 0, widgetSize.width, widgetSize.height); + final rect = Offset.zero & widgetSize; switch (this) { case WidgetShape.rrect: return Path()..addRRect(BorderRadius.circular(24 * devicePixelRatio).toRRect(rect)); diff --git a/lib/widgets/viewer/visual/state.dart b/lib/model/view_state.dart similarity index 66% rename from lib/widgets/viewer/visual/state.dart rename to lib/model/view_state.dart index a523d7eb5..6e8c573dc 100644 --- a/lib/widgets/viewer/visual/state.dart +++ b/lib/model/view_state.dart @@ -37,4 +37,18 @@ class ViewState extends Equatable { contentSize: contentSize ?? this.contentSize, ); } + + Matrix4 get matrix { + final _viewportSize = viewportSize ?? Size.zero; + final _contentSize = contentSize ?? Size.zero; + final _scale = scale ?? 1.0; + + final scaledContentSize = _contentSize * _scale; + final viewOffset = _viewportSize.center(Offset.zero) - scaledContentSize.center(Offset.zero); + + return Matrix4.identity() + ..translate(position.dx, position.dy) + ..translate(viewOffset.dx, viewOffset.dy) + ..scale(_scale, _scale, 1); + } } diff --git a/lib/theme/icons.dart b/lib/theme/icons.dart index 4c683e908..8f46027fa 100644 --- a/lib/theme/icons.dart +++ b/lib/theme/icons.dart @@ -2,172 +2,180 @@ import 'package:flutter/material.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; class AIcons { - static const IconData allCollection = Icons.collections_outlined; - static const IconData image = Icons.photo_outlined; - static const IconData video = Icons.movie_outlined; - static const IconData vector = Icons.code_outlined; + static const allCollection = Icons.collections_outlined; + static const image = Icons.photo_outlined; + static const video = Icons.movie_outlined; + static const vector = Icons.code_outlined; - static const IconData accessibility = Icons.accessibility_new_outlined; - static const IconData android = Icons.android; - static const IconData app = Icons.apps_outlined; - static const IconData apply = Icons.done_outlined; - static const IconData aspectRatio = Icons.aspect_ratio_outlined; - static const IconData bin = Icons.delete_outlined; - static const IconData broken = Icons.broken_image_outlined; - static const IconData brightnessMin = Icons.brightness_low_outlined; - static const IconData brightnessMax = Icons.brightness_high_outlined; - static const IconData checked = Icons.done_outlined; - static const IconData count = MdiIcons.counter; - static const IconData counter = Icons.plus_one_outlined; - static const IconData date = Icons.calendar_today_outlined; - static const IconData dateByDay = Icons.today_outlined; - static const IconData dateByMonth = Icons.calendar_month_outlined; - static const IconData dateRecent = Icons.today_outlined; - static const IconData dateUndated = Icons.event_busy_outlined; - static const IconData description = Icons.description_outlined; - static const IconData descriptionUntitled = Icons.comments_disabled_outlined; - static const IconData disc = Icons.fiber_manual_record; - static const IconData display = Icons.light_mode_outlined; - static const IconData error = Icons.error_outline; - static const IconData folder = Icons.folder_outlined; - static const IconData grid = Icons.grid_on_outlined; - static const IconData home = Icons.home_outlined; - static const IconData important = Icons.label_important_outline; - static const IconData language = Icons.translate_outlined; - static const IconData location = Icons.place_outlined; - static const IconData locationUnlocated = Icons.location_off_outlined; - static const IconData country = Icons.flag_outlined; - static const IconData state = Icons.flag_outlined; - static const IconData place = Icons.place_outlined; - static const IconData mainStorage = Icons.smartphone_outlined; - static const IconData mimeType = Icons.code_outlined; - static const IconData opacity = Icons.opacity; - static const IconData privacy = MdiIcons.shieldAccountOutline; - static const IconData rating = Icons.star_border_outlined; - static const IconData ratingFull = Icons.star; - static const IconData ratingRejected = MdiIcons.starMinusOutline; - static const IconData ratingUnrated = MdiIcons.starOffOutline; - static const IconData raw = Icons.raw_on_outlined; - static const IconData shooting = Icons.camera_outlined; - static const IconData removableStorage = Icons.sd_storage_outlined; - static const IconData sensorControlEnabled = Icons.explore_outlined; - static const IconData sensorControlDisabled = Icons.explore_off_outlined; - static const IconData settings = Icons.settings_outlined; - static const IconData size = Icons.data_usage_outlined; - static const IconData text = Icons.format_quote_outlined; - static const IconData tag = Icons.local_offer_outlined; - static const IconData tagUntagged = MdiIcons.tagOffOutline; - static const IconData volumeMin = Icons.volume_mute_outlined; - static const IconData volumeMax = Icons.volume_up_outlined; + static const accessibility = Icons.accessibility_new_outlined; + static const android = Icons.android; + static const app = Icons.apps_outlined; + static const apply = Icons.done_outlined; + static const aspectRatio = Icons.aspect_ratio_outlined; + static const bin = Icons.delete_outlined; + static const broken = Icons.broken_image_outlined; + static const brightnessMin = Icons.brightness_low_outlined; + static const brightnessMax = Icons.brightness_high_outlined; + static const checked = Icons.done_outlined; + static const count = MdiIcons.counter; + static const counter = Icons.plus_one_outlined; + static const date = Icons.calendar_today_outlined; + static const dateByDay = Icons.today_outlined; + static const dateByMonth = Icons.calendar_month_outlined; + static const dateRecent = Icons.today_outlined; + static const dateUndated = Icons.event_busy_outlined; + static const description = Icons.description_outlined; + static const descriptionUntitled = Icons.comments_disabled_outlined; + static const disc = Icons.fiber_manual_record; + static const display = Icons.light_mode_outlined; + static const error = Icons.error_outline; + static const folder = Icons.folder_outlined; + static const grid = Icons.grid_on_outlined; + static const home = Icons.home_outlined; + static const important = Icons.label_important_outline; + static const language = Icons.translate_outlined; + static const location = Icons.place_outlined; + static const locationUnlocated = Icons.location_off_outlined; + static const country = Icons.flag_outlined; + static const state = Icons.flag_outlined; + static const place = Icons.place_outlined; + static const mainStorage = Icons.smartphone_outlined; + static const mimeType = Icons.code_outlined; + static const opacity = Icons.opacity; + static const privacy = MdiIcons.shieldAccountOutline; + static const rating = Icons.star_border_outlined; + static const ratingFull = Icons.star; + static const ratingRejected = MdiIcons.starMinusOutline; + static const ratingUnrated = MdiIcons.starOffOutline; + static const raw = Icons.raw_on_outlined; + static const shooting = Icons.camera_outlined; + static const removableStorage = Icons.sd_storage_outlined; + static const sensorControlEnabled = Icons.explore_outlined; + static const sensorControlDisabled = Icons.explore_off_outlined; + static const settings = Icons.settings_outlined; + static const size = Icons.data_usage_outlined; + static const text = Icons.format_quote_outlined; + static const tag = Icons.local_offer_outlined; + static const tagUntagged = MdiIcons.tagOffOutline; + static const volumeMin = Icons.volume_mute_outlined; + static const volumeMax = Icons.volume_up_outlined; // view - static const IconData group = Icons.group_work_outlined; - static const IconData layout = Icons.grid_view_outlined; - static const IconData layoutMosaic = Icons.view_comfy_outlined; - static const IconData layoutGrid = Icons.view_compact_outlined; - static const IconData layoutList = Icons.list_outlined; - static const IconData sort = Icons.sort_outlined; - static const IconData sortOrder = Icons.swap_vert_outlined; - static const IconData thumbnailLarge = Icons.photo_size_select_large_outlined; - static const IconData thumbnailSmall = Icons.photo_size_select_small_outlined; + static const group = Icons.group_work_outlined; + static const layout = Icons.grid_view_outlined; + static const layoutMosaic = Icons.view_comfy_outlined; + static const layoutGrid = Icons.view_compact_outlined; + static const layoutList = Icons.list_outlined; + static const sort = Icons.sort_outlined; + static const sortOrder = Icons.swap_vert_outlined; + static const thumbnailLarge = Icons.photo_size_select_large_outlined; + static const thumbnailSmall = Icons.photo_size_select_small_outlined; // actions - static const IconData add = Icons.add_circle_outline; - static const IconData addShortcut = Icons.add_to_home_screen_outlined; - static const IconData cancel = Icons.cancel_outlined; - static const IconData captureFrame = Icons.screenshot_outlined; - static const IconData clear = Icons.clear_outlined; - static const IconData clipboard = Icons.content_copy_outlined; - static const IconData convert = Icons.transform_outlined; - static const IconData convertToStillImage = MdiIcons.movieRemoveOutline; - static const IconData copy = Icons.file_copy_outlined; - static const IconData debug = Icons.whatshot_outlined; - static const IconData delete = Icons.delete_outlined; - static const IconData edit = Icons.edit_outlined; - static const IconData emptyBin = Icons.delete_sweep_outlined; - static const IconData export = Icons.open_with_outlined; - static const IconData fileExport = MdiIcons.fileExportOutline; - static const IconData fileImport = MdiIcons.fileImportOutline; - static const IconData flip = Icons.flip_outlined; - static const IconData favourite = Icons.favorite_border; - static const IconData favouriteActive = Icons.favorite; - static const IconData filter = MdiIcons.filterOutline; - static const IconData filterOff = MdiIcons.filterOffOutline; - static const IconData geoBounds = Icons.public_outlined; - static const IconData goUp = Icons.arrow_upward_outlined; - static const IconData hide = Icons.visibility_off_outlined; - static const IconData info = Icons.info_outlined; - static const IconData layers = Icons.layers_outlined; - static const IconData map = Icons.map_outlined; - static const IconData move = MdiIcons.fileMoveOutline; - static const IconData mute = Icons.volume_off_outlined; - static const IconData unmute = Icons.volume_up_outlined; - static const IconData name = Icons.abc_outlined; - static const IconData newTier = Icons.fiber_new_outlined; - static const IconData openOutside = Icons.open_in_new_outlined; - static const IconData openVideo = MdiIcons.moviePlayOutline; - static const IconData pin = Icons.push_pin_outlined; - static const IconData unpin = MdiIcons.pinOffOutline; - static const IconData play = Icons.play_arrow; - static const IconData pause = Icons.pause; - static const IconData print = Icons.print_outlined; - static const IconData refresh = Icons.refresh_outlined; - static const IconData replay10 = Icons.replay_10_outlined; - static const IconData reverse = Icons.invert_colors_outlined; - static const IconData skip10 = Icons.forward_10_outlined; - static const IconData reset = Icons.restart_alt_outlined; - static const IconData restore = Icons.restore_outlined; - static const IconData rotateLeft = Icons.rotate_left_outlined; - static const IconData rotateRight = Icons.rotate_right_outlined; - static const IconData rotateScreen = Icons.screen_rotation_outlined; - static const IconData search = Icons.search_outlined; - static const IconData select = Icons.select_all_outlined; - static const IconData setAs = Icons.wallpaper_outlined; - static const IconData setCover = MdiIcons.imageEditOutline; - static const IconData share = Icons.share_outlined; - static const IconData show = Icons.visibility_outlined; - static const IconData showFullscreen = MdiIcons.arrowExpand; - static const IconData slideshow = Icons.slideshow_outlined; - static const IconData speed = Icons.speed_outlined; - static const IconData stats = Icons.donut_small_outlined; - static const IconData streams = Icons.translate_outlined; - static const IconData streamVideo = Icons.movie_outlined; - static const IconData streamAudio = Icons.audiotrack_outlined; - static const IconData streamText = Icons.closed_caption_outlined; - static const IconData vaultLock = Icons.lock_outline; - static const IconData vaultAdd = Icons.enhanced_encryption_outlined; - static const IconData vaultConfigure = MdiIcons.shieldLockOutline; - static const IconData videoSettings = Icons.video_settings_outlined; - static const IconData view = Icons.grid_view_outlined; - static const IconData viewerLock = Icons.lock_outline; - static const IconData viewerUnlock = Icons.lock_open_outlined; - static const IconData zoomIn = Icons.add_outlined; - static const IconData zoomOut = Icons.remove_outlined; - static const IconData collapse = Icons.expand_less_outlined; - static const IconData expand = Icons.expand_more_outlined; - static const IconData previous = Icons.chevron_left_outlined; - static const IconData next = Icons.chevron_right_outlined; + static const add = Icons.add_circle_outline; + static const addShortcut = Icons.add_to_home_screen_outlined; + static const cancel = Icons.cancel_outlined; + static const captureFrame = Icons.screenshot_outlined; + static const clear = Icons.clear_outlined; + static const clipboard = Icons.content_copy_outlined; + static const convert = Icons.transform_outlined; + static const convertToStillImage = MdiIcons.movieRemoveOutline; + static const copy = Icons.file_copy_outlined; + static const debug = Icons.whatshot_outlined; + static const delete = Icons.delete_outlined; + static const edit = Icons.edit_outlined; + static const emptyBin = Icons.delete_sweep_outlined; + static const export = Icons.open_with_outlined; + static const fileExport = MdiIcons.fileExportOutline; + static const fileImport = MdiIcons.fileImportOutline; + static const flip = Icons.flip_outlined; + static const favourite = Icons.favorite_border; + static const favouriteActive = Icons.favorite; + static const filter = MdiIcons.filterOutline; + static const filterOff = MdiIcons.filterOffOutline; + static const geoBounds = Icons.public_outlined; + static const goUp = Icons.arrow_upward_outlined; + static const hide = Icons.visibility_off_outlined; + static const info = Icons.info_outlined; + static const layers = Icons.layers_outlined; + static const map = Icons.map_outlined; + static const move = MdiIcons.fileMoveOutline; + static const mute = Icons.volume_off_outlined; + static const unmute = Icons.volume_up_outlined; + static const name = Icons.abc_outlined; + static const newTier = Icons.fiber_new_outlined; + static const openOutside = Icons.open_in_new_outlined; + static const openVideo = MdiIcons.moviePlayOutline; + static const pin = Icons.push_pin_outlined; + static const unpin = MdiIcons.pinOffOutline; + static const play = Icons.play_arrow; + static const pause = Icons.pause; + static const print = Icons.print_outlined; + static const refresh = Icons.refresh_outlined; + static const replay10 = Icons.replay_10_outlined; + static const reverse = Icons.invert_colors_outlined; + static const skip10 = Icons.forward_10_outlined; + static const reset = Icons.restart_alt_outlined; + static const restore = Icons.restore_outlined; + static const rotateLeft = Icons.rotate_left_outlined; + static const rotateRight = Icons.rotate_right_outlined; + static const rotateScreen = Icons.screen_rotation_outlined; + static const search = Icons.search_outlined; + static const select = Icons.select_all_outlined; + static const setAs = Icons.wallpaper_outlined; + static const setCover = MdiIcons.imageEditOutline; + static const share = Icons.share_outlined; + static const show = Icons.visibility_outlined; + static const showFullscreen = MdiIcons.arrowExpand; + static const slideshow = Icons.slideshow_outlined; + static const speed = Icons.speed_outlined; + static const stats = Icons.donut_small_outlined; + static const streams = Icons.translate_outlined; + static const streamVideo = Icons.movie_outlined; + static const streamAudio = Icons.audiotrack_outlined; + static const streamText = Icons.closed_caption_outlined; + static const vaultLock = Icons.lock_outline; + static const vaultAdd = Icons.enhanced_encryption_outlined; + static const vaultConfigure = MdiIcons.shieldLockOutline; + static const videoSettings = Icons.video_settings_outlined; + static const view = Icons.grid_view_outlined; + static const viewerLock = Icons.lock_outline; + static const viewerUnlock = Icons.lock_open_outlined; + static const zoomIn = Icons.add_outlined; + static const zoomOut = Icons.remove_outlined; + static const collapse = Icons.expand_less_outlined; + static const expand = Icons.expand_more_outlined; + static const previous = Icons.chevron_left_outlined; + static const next = Icons.chevron_right_outlined; + + // editor + static const transform = Icons.crop_rotate_outlined; + static const aspectRatioFree = Icons.crop_free_outlined; + static const aspectRatioOriginal = Icons.crop_original_outlined; + static const aspectRatioSquare = Icons.crop_square_outlined; + static const aspectRatio_16_9 = Icons.crop_16_9_outlined; + static const aspectRatio_4_3 = Icons.crop_landscape_outlined; // albums - static const IconData album = Icons.photo_album_outlined; - static const IconData cameraAlbum = Icons.photo_camera_outlined; - static const IconData downloadAlbum = Icons.file_download; - static const IconData screenshotAlbum = Icons.screenshot_outlined; - static const IconData recordingAlbum = Icons.smartphone_outlined; - static const IconData locked = Icons.lock_outline; - static const IconData unlocked = Icons.lock_open_outlined; + static const album = Icons.photo_album_outlined; + static const cameraAlbum = Icons.photo_camera_outlined; + static const downloadAlbum = Icons.file_download; + static const screenshotAlbum = Icons.screenshot_outlined; + static const recordingAlbum = Icons.smartphone_outlined; + static const locked = Icons.lock_outline; + static const unlocked = Icons.lock_open_outlined; // thumbnail overlay - static const IconData animated = Icons.slideshow; - static const IconData geo = Icons.language_outlined; - static const IconData motionPhoto = Icons.motion_photos_on_outlined; - static const IconData multiPage = Icons.burst_mode_outlined; - static const IconData panorama = Icons.vrpano_outlined; - static const IconData sphericalVideo = Icons.threesixty_outlined; - static const IconData videoThumb = Icons.play_circle_outline; - static const IconData selected = Icons.check_circle_outline; - static const IconData unselected = Icons.radio_button_unchecked; + static const animated = Icons.slideshow; + static const geo = Icons.language_outlined; + static const motionPhoto = Icons.motion_photos_on_outlined; + static const multiPage = Icons.burst_mode_outlined; + static const panorama = Icons.vrpano_outlined; + static const sphericalVideo = Icons.threesixty_outlined; + static const videoThumb = Icons.play_circle_outline; + static const selected = Icons.check_circle_outline; + static const unselected = Icons.radio_button_unchecked; - static const IconData github = MdiIcons.github; - static const IconData legal = MdiIcons.scaleBalance; + static const github = MdiIcons.github; + static const legal = MdiIcons.scaleBalance; } diff --git a/lib/utils/math_utils.dart b/lib/utils/math_utils.dart index 89a0e6ed5..e882db4aa 100644 --- a/lib/utils/math_utils.dart +++ b/lib/utils/math_utils.dart @@ -1,7 +1,48 @@ import 'dart:math'; +import 'dart:ui'; + +import 'package:tuple/tuple.dart'; int highestPowerOf2(num x) => x < 1 ? 0 : pow(2, (log(x) / ln2).floor()).toInt(); int smallestPowerOf2(num x) => x < 1 ? 1 : pow(2, (log(x) / ln2).ceil()).toInt(); double roundToPrecision(final double value, {required final int decimals}) => (value * pow(10, decimals)).round() / pow(10, decimals); + +// cf https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments +Offset? segmentIntersection(Tuple2 s1, Tuple2 s2) { + final x1 = s1.item1.dx; + final y1 = s1.item1.dy; + final x2 = s1.item2.dx; + final y2 = s1.item2.dy; + + final x3 = s2.item1.dx; + final y3 = s2.item1.dy; + final x4 = s2.item2.dx; + final y4 = s2.item2.dy; + + final a1 = x2 - x1; + final b1 = -(x4 - x3); + final c1 = x3 - x1; + final a2 = y2 - y1; + final b2 = -(y4 - y3); + final c2 = y3 - y1; + + final denom = a1 * b2 - a2 * b1; + if (denom == 0) { + // lines are parallel + return null; + } + + final s0 = (c1 * b2 - c2 * b1) / denom; + final t0 = (a1 * c2 - a2 * c1) / denom; + + if (!(0 <= s0 && s0 <= 1 && 0 <= t0 && t0 <= 1)) { + // segments do not intersect + return null; + } + + final x0 = x1 + s0 * (x2 - x1); + final y0 = y1 + s0 * (y2 - y1); + return Offset(x0, y0); +} diff --git a/lib/view/src/editor/enums.dart b/lib/view/src/editor/enums.dart new file mode 100644 index 000000000..43b9fe95d --- /dev/null +++ b/lib/view/src/editor/enums.dart @@ -0,0 +1,57 @@ +import 'package:aves/ref/unicode.dart'; +import 'package:aves/theme/icons.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:flutter/widgets.dart'; + +extension ExtraEditorActionView on EditorAction { + String getText(BuildContext context) { + switch (this) { + case EditorAction.transform: + return context.l10n.editorActionTransform; + } + } + + Widget getIcon() => Icon(_getIconData()); + + IconData _getIconData() { + switch (this) { + case EditorAction.transform: + return AIcons.transform; + } + } +} + +extension ExtraCropAspectRatioView on CropAspectRatio { + String getText(BuildContext context) { + switch (this) { + case CropAspectRatio.free: + return context.l10n.cropAspectRatioFree; + case CropAspectRatio.original: + return context.l10n.cropAspectRatioOriginal; + case CropAspectRatio.square: + return context.l10n.cropAspectRatioSquare; + case CropAspectRatio.ar_16_9: + return '16${UniChars.ratio}9'; + case CropAspectRatio.ar_4_3: + return '4${UniChars.ratio}3'; + } + } + + Widget getIcon() => Icon(_getIconData()); + + IconData _getIconData() { + switch (this) { + case CropAspectRatio.free: + return AIcons.aspectRatioFree; + case CropAspectRatio.original: + return AIcons.aspectRatioOriginal; + case CropAspectRatio.square: + return AIcons.aspectRatioSquare; + case CropAspectRatio.ar_16_9: + return AIcons.aspectRatio_16_9; + case CropAspectRatio.ar_4_3: + return AIcons.aspectRatio_4_3; + } + } +} diff --git a/lib/view/view.dart b/lib/view/view.dart index 76eec0d8c..fd3cfd0ff 100644 --- a/lib/view/view.dart +++ b/lib/view/view.dart @@ -6,6 +6,7 @@ export 'src/actions/map.dart'; export 'src/actions/map_cluster.dart'; export 'src/actions/share.dart'; export 'src/actions/slideshow.dart'; +export 'src/editor/enums.dart'; export 'src/metadata/date_edit_action.dart'; export 'src/metadata/date_field_source.dart'; export 'src/metadata/fields.dart'; diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index d34dfd3a4..1c3ff2854 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -54,6 +54,7 @@ import 'package:url_launcher/url_launcher.dart' as ul; class AvesApp extends StatefulWidget { final AppFlavor flavor; + final Map? debugIntentData; // temporary exclude locales not ready yet for prime time // `ckb`: add `flutter_ckb_localization` and necessary app localization delegates when ready @@ -85,6 +86,7 @@ class AvesApp extends StatefulWidget { const AvesApp({ super.key, required this.flavor, + this.debugIntentData, }); @override @@ -227,7 +229,7 @@ class _AvesAppState extends State with WidgetsBindingObserver { AvesApp.showSystemUI(); } final home = initialized - ? _getFirstPage() + ? _getFirstPage(intentData: widget.debugIntentData) : AvesScaffold( body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(), ); @@ -390,6 +392,7 @@ class _AvesAppState extends State with WidgetsBindingObserver { case AppMode.setWallpaper: case AppMode.slideshow: case AppMode.view: + case AppMode.edit: break; } case AppLifecycleState.resumed: diff --git a/lib/widgets/collection/collection_page.dart b/lib/widgets/collection/collection_page.dart index 0c3a1ac0e..93bc20b49 100644 --- a/lib/widgets/collection/collection_page.dart +++ b/lib/widgets/collection/collection_page.dart @@ -208,6 +208,7 @@ class _CollectionPageState extends State { case AppMode.setWallpaper: case AppMode.slideshow: case AppMode.view: + case AppMode.edit: return null; } } diff --git a/lib/widgets/collection/grid/tile.dart b/lib/widgets/collection/grid/tile.dart index a4e132d0f..2a8cc56fc 100644 --- a/lib/widgets/collection/grid/tile.dart +++ b/lib/widgets/collection/grid/tile.dart @@ -54,6 +54,7 @@ class InteractiveTile extends StatelessWidget { case AppMode.setWallpaper: case AppMode.slideshow: case AppMode.view: + case AppMode.edit: break; } }, diff --git a/lib/widgets/common/basic/multi_cross_fader.dart b/lib/widgets/common/basic/multi_cross_fader.dart index 17a07ad9b..df65a57af 100644 --- a/lib/widgets/common/basic/multi_cross_fader.dart +++ b/lib/widgets/common/basic/multi_cross_fader.dart @@ -4,6 +4,7 @@ class MultiCrossFader extends StatefulWidget { final Duration duration; final Curve fadeCurve, sizeCurve; final AlignmentGeometry alignment; + final AnimatedCrossFadeBuilder layoutBuilder; final Widget child; const MultiCrossFader({ @@ -12,6 +13,7 @@ class MultiCrossFader extends StatefulWidget { this.fadeCurve = Curves.linear, this.sizeCurve = Curves.linear, this.alignment = Alignment.topCenter, + this.layoutBuilder = AnimatedCrossFade.defaultLayoutBuilder, required this.child, }); @@ -53,6 +55,8 @@ class _MultiCrossFaderState extends State { alignment: widget.alignment, crossFadeState: _fadeState, duration: widget.duration, + reverseDuration: widget.duration, + layoutBuilder: widget.layoutBuilder, ); } } diff --git a/lib/widgets/common/extensions/geometry.dart b/lib/widgets/common/extensions/geometry.dart new file mode 100644 index 000000000..3979c4ab3 --- /dev/null +++ b/lib/widgets/common/extensions/geometry.dart @@ -0,0 +1,7 @@ +import 'dart:ui'; + +extension ExtraRect on Rect { + bool containsIncludingBottomRight(Offset offset, {double tolerance = 0}) { + return offset.dx >= left - tolerance && offset.dx <= right + tolerance && offset.dy >= top - tolerance && offset.dy <= bottom + tolerance; + } +} diff --git a/lib/widgets/common/fx/checkered_decoration.dart b/lib/widgets/common/fx/checkered_decoration.dart index ad2de6e62..b7fb249fd 100644 --- a/lib/widgets/common/fx/checkered_decoration.dart +++ b/lib/widgets/common/fx/checkered_decoration.dart @@ -15,7 +15,7 @@ class CheckeredPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { - final background = Rect.fromLTWH(0, 0, size.width, size.height); + final background = Offset.zero & size; canvas.drawRect(background, lightPaint); final dx = offset.dx % (checkSize * 2); diff --git a/lib/widgets/common/fx/dashed_path_painter.dart b/lib/widgets/common/fx/dashed_path_painter.dart new file mode 100644 index 000000000..5d0c36d56 --- /dev/null +++ b/lib/widgets/common/fx/dashed_path_painter.dart @@ -0,0 +1,142 @@ +import 'dart:ui' as ui; +import 'dart:math' as math; + +import 'package:flutter/material.dart'; + +// from https://stackoverflow.com/a/71099304/786656 +class DashedPathPainter extends CustomPainter { + final Path originalPath; + final Color pathColor; + final double strokeWidth; + final double dashGapLength; + final double dashLength; + late DashedPathProperties _dashedPathProperties; + + DashedPathPainter({ + required this.originalPath, + required this.pathColor, + this.strokeWidth = 3.0, + this.dashGapLength = 5.0, + this.dashLength = 10.0, + }); + + @override + void paint(Canvas canvas, Size size) { + _dashedPathProperties = DashedPathProperties( + path: Path(), + dashLength: dashLength, + dashGapLength: dashGapLength, + ); + final dashedPath = _getDashedPath(originalPath, dashLength, dashGapLength); + canvas.drawPath( + dashedPath, + Paint() + ..style = PaintingStyle.stroke + ..color = pathColor + ..strokeWidth = strokeWidth, + ); + } + + @override + bool shouldRepaint(DashedPathPainter oldDelegate) => oldDelegate.originalPath != originalPath || oldDelegate.pathColor != pathColor || oldDelegate.strokeWidth != strokeWidth || oldDelegate.dashGapLength != dashGapLength || oldDelegate.dashLength != dashLength; + + Path _getDashedPath( + Path originalPath, + double dashLength, + double dashGapLength, + ) { + final metricsIterator = originalPath.computeMetrics().iterator; + while (metricsIterator.moveNext()) { + final metric = metricsIterator.current; + _dashedPathProperties.extractedPathLength = 0.0; + while (_dashedPathProperties.extractedPathLength < metric.length) { + if (_dashedPathProperties.addDashNext) { + _dashedPathProperties.addDash(metric, dashLength); + } else { + _dashedPathProperties.addDashGap(metric, dashGapLength); + } + } + } + return _dashedPathProperties.path; + } +} + +class DashedPathProperties { + double extractedPathLength; + Path path; + + final double _dashLength; + double _remainingDashLength; + double _remainingDashGapLength; + bool _previousWasDash; + + DashedPathProperties({ + required this.path, + required double dashLength, + required double dashGapLength, + }) : assert(dashLength > 0.0, 'dashLength must be > 0.0'), + assert(dashGapLength > 0.0, 'dashGapLength must be > 0.0'), + _dashLength = dashLength, + _remainingDashLength = dashLength, + _remainingDashGapLength = dashGapLength, + _previousWasDash = false, + extractedPathLength = 0.0; + + bool get addDashNext { + if (!_previousWasDash || _remainingDashLength != _dashLength) { + return true; + } + return false; + } + + void addDash(ui.PathMetric metric, double dashLength) { + // Calculate lengths (actual + available) + final end = _calculateLength(metric, _remainingDashLength); + final availableEnd = _calculateLength(metric, dashLength); + // Add path + final pathSegment = metric.extractPath(extractedPathLength, end); + path.addPath(pathSegment, Offset.zero); + // Update + final delta = _remainingDashLength - (end - extractedPathLength); + _remainingDashLength = _updateRemainingLength( + delta: delta, + end: end, + availableEnd: availableEnd, + initialLength: dashLength, + ); + extractedPathLength = end; + _previousWasDash = true; + } + + void addDashGap(ui.PathMetric metric, double dashGapLength) { + // Calculate lengths (actual + available) + final end = _calculateLength(metric, _remainingDashGapLength); + final availableEnd = _calculateLength(metric, dashGapLength); + // Move path's end point + ui.Tangent tangent = metric.getTangentForOffset(end)!; + path.moveTo(tangent.position.dx, tangent.position.dy); + // Update + final delta = end - extractedPathLength; + _remainingDashGapLength = _updateRemainingLength( + delta: delta, + end: end, + availableEnd: availableEnd, + initialLength: dashGapLength, + ); + extractedPathLength = end; + _previousWasDash = false; + } + + double _calculateLength(ui.PathMetric metric, double addedLength) { + return math.min(extractedPathLength + addedLength, metric.length); + } + + double _updateRemainingLength({ + required double delta, + required double end, + required double availableEnd, + required double initialLength, + }) { + return (delta > 0 && availableEnd == end) ? delta : initialLength; + } +} diff --git a/lib/widgets/common/fx/transition_image.dart b/lib/widgets/common/fx/transition_image.dart index f9aa1284c..abd417506 100644 --- a/lib/widgets/common/fx/transition_image.dart +++ b/lib/widgets/common/fx/transition_image.dart @@ -343,10 +343,11 @@ class _TransitionImagePainter extends CustomPainter { ..filterQuality = FilterQuality.low; const alignment = Alignment.center; - final rect = ui.Rect.fromLTWH(0, 0, size.width, size.height); + final rect = Offset.zero & size; if (rect.isEmpty) { return; } + final outputSize = rect.size; final inputSize = Size(image!.width.toDouble(), image!.height.toDouble()); diff --git a/lib/widgets/common/grid/item_tracker.dart b/lib/widgets/common/grid/item_tracker.dart index 74cd97101..4cd88a32f 100644 --- a/lib/widgets/common/grid/item_tracker.dart +++ b/lib/widgets/common/grid/item_tracker.dart @@ -101,7 +101,7 @@ class _GridItemTrackerState extends State> with WidgetsBin final tileRect = sectionedListLayout.getTileRect(event.item); if (tileRect == null) return; - final viewportRect = Rect.fromLTWH(0, scrollController.offset, scrollableSize.width, scrollableSize.height); + final viewportRect = Offset(0, scrollController.offset) & scrollableSize; final itemVisibility = max(0, tileRect.intersect(viewportRect).height) / tileRect.height; if (!event.predicate(itemVisibility)) return; diff --git a/lib/widgets/editor/control_panel.dart b/lib/widgets/editor/control_panel.dart new file mode 100644 index 000000000..2a3dc2711 --- /dev/null +++ b/lib/widgets/editor/control_panel.dart @@ -0,0 +1,137 @@ +import 'package:aves/model/entry/entry.dart'; +import 'package:aves/theme/durations.dart'; +import 'package:aves/view/view.dart'; +import 'package:aves/widgets/common/basic/multi_cross_fader.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/common/identity/buttons/overlay_button.dart'; +import 'package:aves/widgets/editor/transform/control_panel.dart'; +import 'package:aves/widgets/editor/transform/controller.dart'; +import 'package:aves/widgets/viewer/overlay/viewer_buttons.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class EditorControlPanel extends StatelessWidget { + final AvesEntry entry; + final ValueNotifier actionNotifier; + + static const padding = ViewerButtonRowContent.padding; + static const actions = [ + EditorAction.transform, + ]; + + const EditorControlPanel({ + super.key, + required this.entry, + required this.actionNotifier, + }); + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () { + if (actionNotifier.value != null) { + _cancelAction(context); + return SynchronousFuture(false); + } + return SynchronousFuture(true); + }, + child: Padding( + padding: const EdgeInsets.all(padding), + child: TooltipTheme( + data: TooltipTheme.of(context).copyWith( + preferBelow: false, + ), + child: ValueListenableBuilder( + valueListenable: actionNotifier, + builder: (context, action, child) { + return MultiCrossFader( + duration: context.select((v) => v.formTransition), + alignment: Alignment.bottomCenter, + layoutBuilder: (topChild, topChildKey, bottomChild, bottomChildKey) { + return Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + key: bottomChildKey, + left: 0.0, + bottom: 0.0, + right: 0.0, + child: bottomChild, + ), + Positioned( + key: topChildKey, + child: topChild, + ), + ], + ); + }, + child: action == null ? _buildTopLevelPanel(context) : _buildActionPanel(context, action), + ); + }, + ), + ), + ), + ); + } + + Widget _buildTopLevelPanel(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + ...actions.map( + (action) => Padding( + padding: const EdgeInsetsDirectional.symmetric(horizontal: padding / 2), + child: OverlayButton( + child: IconButton( + icon: action.getIcon(), + onPressed: () => actionNotifier.value = action, + tooltip: action.getText(context), + ), + ), + ), + ), + ], + ), + const SizedBox(height: padding), + Row( + children: [ + const OverlayButton( + child: CloseButton(), + ), + const Spacer(), + OverlayTextButton( + onPressed: () {}, + child: Text(context.l10n.saveCopyButtonLabel), + ), + ], + ), + ], + ); + } + + Widget _buildActionPanel(BuildContext context, EditorAction action) { + switch (action) { + case EditorAction.transform: + return TransformControlPanel( + entry: entry, + onCancel: () => _cancelAction(context), + onApply: (transformation) => _applyAction(context), + ); + } + } + + void _cancelAction(BuildContext context) { + actionNotifier.value = null; + context.read().reset(); + } + + void _applyAction(BuildContext context) { + actionNotifier.value = null; + context.read().reset(); + } +} diff --git a/lib/widgets/editor/entry_editor_page.dart b/lib/widgets/editor/entry_editor_page.dart new file mode 100644 index 000000000..f375aeb27 --- /dev/null +++ b/lib/widgets/editor/entry_editor_page.dart @@ -0,0 +1,136 @@ +import 'dart:async'; + +import 'package:aves/model/entry/entry.dart'; +import 'package:aves/model/settings/settings.dart'; +import 'package:aves/model/view_state.dart'; +import 'package:aves/widgets/editor/control_panel.dart'; +import 'package:aves/widgets/editor/image.dart'; +import 'package:aves/widgets/editor/transform/controller.dart'; +import 'package:aves/widgets/editor/transform/cropper.dart'; +import 'package:aves/widgets/viewer/overlay/minimap.dart'; +import 'package:aves_magnifier/aves_magnifier.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class ImageEditorPage extends StatefulWidget { + static const routeName = '/image_editor'; + + final AvesEntry entry; + + const ImageEditorPage({ + super.key, + required this.entry, + }); + + @override + State createState() => _ImageEditorPageState(); +} + +class _ImageEditorPageState extends State { + final List _subscriptions = []; + final ValueNotifier _actionNotifier = ValueNotifier(null); + final ValueNotifier _paddingNotifier = ValueNotifier(EdgeInsets.zero); + final ValueNotifier _viewStateNotifier = ValueNotifier(ViewState.zero); + final AvesMagnifierController _magnifierController = AvesMagnifierController(); + late final TransformController _transformController; + + @override + void initState() { + super.initState(); + _transformController = TransformController(widget.entry.displaySize); + _actionNotifier.addListener(_onActionChanged); + _subscriptions.add(_transformController.transformationStream.map((v) => v.matrix).distinct().listen(_onTransformationMatrixChanged)); + } + + @override + void dispose() { + _subscriptions + ..forEach((sub) => sub.cancel()) + ..clear(); + _actionNotifier.dispose(); + _paddingNotifier.dispose(); + _viewStateNotifier.dispose(); + _magnifierController.dispose(); + _transformController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Provider.value( + value: _transformController, + child: SafeArea( + child: Column( + children: [ + Expanded( + child: Stack( + children: [ + ClipRect( + child: EditorImage( + magnifierController: _magnifierController, + transformController: _transformController, + actionNotifier: _actionNotifier, + paddingNotifier: _paddingNotifier, + viewStateNotifier: _viewStateNotifier, + entry: widget.entry, + ), + ), + if (settings.showOverlayMinimap) + PositionedDirectional( + start: 8, + bottom: 8, + child: Minimap(viewStateNotifier: _viewStateNotifier), + ), + ValueListenableBuilder( + valueListenable: _actionNotifier, + builder: (context, action, child) { + switch (action) { + case EditorAction.transform: + return Cropper( + magnifierController: _magnifierController, + transformController: _transformController, + paddingNotifier: _paddingNotifier, + ); + case null: + return const SizedBox(); + } + }, + ), + ], + ), + ), + EditorControlPanel( + entry: widget.entry, + actionNotifier: _actionNotifier, + ), + ], + ), + ), + ), + resizeToAvoidBottomInset: false, + ); + } + + void _onActionChanged() => _updateImagePadding(); + + void _updateImagePadding() { + if (_actionNotifier.value == EditorAction.transform) { + _paddingNotifier.value = Cropper.imagePadding; + } else { + _paddingNotifier.value = EdgeInsets.zero; + } + } + + void _onTransformationMatrixChanged(Matrix4 transformationMatrix) { + final boundaries = _magnifierController.scaleBoundaries; + if (boundaries != null) { + _magnifierController.setScaleBoundaries( + boundaries.copyWith( + externalTransform: transformationMatrix, + ), + ); + } + } +} diff --git a/lib/widgets/editor/image.dart b/lib/widgets/editor/image.dart new file mode 100644 index 000000000..2b2f703ea --- /dev/null +++ b/lib/widgets/editor/image.dart @@ -0,0 +1,224 @@ +import 'dart:async'; + +import 'package:aves/model/entry/entry.dart'; +import 'package:aves/model/view_state.dart'; +import 'package:aves/theme/durations.dart'; +import 'package:aves/widgets/editor/transform/controller.dart'; +import 'package:aves/widgets/editor/transform/painter.dart'; +import 'package:aves/widgets/editor/transform/transformation.dart'; +import 'package:aves/widgets/viewer/visual/error.dart'; +import 'package:aves/widgets/viewer/visual/raster.dart'; +import 'package:aves_magnifier/aves_magnifier.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class EditorImage extends StatefulWidget { + final AvesMagnifierController magnifierController; + final TransformController transformController; + final ValueNotifier actionNotifier; + final ValueNotifier paddingNotifier; + final ValueNotifier viewStateNotifier; + final AvesEntry entry; + + const EditorImage({ + super.key, + required this.magnifierController, + required this.transformController, + required this.actionNotifier, + required this.paddingNotifier, + required this.viewStateNotifier, + required this.entry, + }); + + @override + State createState() => _EditorImageState(); +} + +class _EditorImageState extends State { + final List _subscriptions = []; + final ValueNotifier _scrimOpacityNotifier = ValueNotifier(0); + + AvesEntry get entry => widget.entry; + + TransformController get transformController => widget.transformController; + + ValueNotifier get viewStateNotifier => widget.viewStateNotifier; + + @override + void initState() { + super.initState(); + _registerWidget(widget); + } + + @override + void didUpdateWidget(covariant EditorImage oldWidget) { + super.didUpdateWidget(oldWidget); + _unregisterWidget(oldWidget); + _registerWidget(widget); + } + + @override + void dispose() { + _subscriptions + ..forEach((sub) => sub.cancel()) + ..clear(); + _unregisterWidget(widget); + super.dispose(); + } + + void _registerWidget(EditorImage widget) { + widget.actionNotifier.addListener(_onActionChanged); + _subscriptions.add(widget.magnifierController.stateStream.listen(_onViewStateChanged)); + _subscriptions.add(widget.magnifierController.scaleBoundariesStream.listen(_onViewScaleBoundariesChanged)); + _subscriptions.add(widget.transformController.eventStream.listen(_onTransformEvent)); + } + + void _unregisterWidget(EditorImage widget) { + widget.actionNotifier.removeListener(_onActionChanged); + _subscriptions + ..forEach((sub) => sub.cancel()) + ..clear(); + } + + @override + Widget build(BuildContext context) { + return MagnifierGestureDetectorScope( + axis: const [Axis.horizontal, Axis.vertical], + child: StreamBuilder( + stream: transformController.transformationStream, + builder: (context, snapshot) { + final transformation = (snapshot.data ?? Transformation.zero); + final highlightRegionCorners = transformation.region.corners; + final imageToUserMatrix = transformation.matrix; + + final mediaSize = entry.displaySize; + final canvasSize = MatrixUtils.transformRect(imageToUserMatrix, Offset.zero & mediaSize).size; + + return ValueListenableBuilder( + valueListenable: widget.paddingNotifier, + builder: (context, padding, child) { + return Transform( + alignment: Alignment.center, + transform: imageToUserMatrix, + child: ValueListenableBuilder( + valueListenable: widget.actionNotifier, + builder: (context, action, child) { + return LayoutBuilder( + builder: (context, constraints) { + final viewportSize = padding.deflateSize(constraints.biggest); + final minScale = ScaleLevel(factor: ScaleLevel.scaleForContained(viewportSize, canvasSize)); + return AvesMagnifier( + key: Key('${entry.uri}_${entry.pageId}_${entry.dateModifiedSecs}'), + controller: widget.magnifierController, + viewportPadding: padding, + contentSize: mediaSize, + allowOriginalScaleBeyondRange: false, + allowGestureScaleBeyondRange: false, + panInertia: _getActionPanInertia(action), + minScale: minScale, + maxScale: const ScaleLevel(factor: 1), + initialScale: minScale, + scaleStateCycle: defaultScaleStateCycle, + applyScale: false, + onScaleStart: (details, doubleTap, boundaries) { + transformController.activity = TransformActivity.pan; + }, + onScaleEnd: (details) { + transformController.activity = TransformActivity.none; + }, + child: child!, + ); + }, + ); + }, + child: Stack( + children: [ + RasterImageView( + entry: entry, + viewStateNotifier: viewStateNotifier, + errorBuilder: (context, error, stackTrace) => ErrorView( + entry: entry, + onTap: () {}, + ), + ), + Positioned.fill( + child: ValueListenableBuilder( + valueListenable: viewStateNotifier, + builder: (context, viewState, child) { + final scale = viewState.scale ?? 1; + final highlightRegionPath = Path()..addPolygon(highlightRegionCorners.map((v) => v * scale).toList(), true); + return ValueListenableBuilder( + valueListenable: _scrimOpacityNotifier, + builder: (context, opacity, child) { + return AnimatedOpacity( + opacity: opacity, + duration: context.read().viewerOverlayAnimation, + child: CustomPaint( + painter: ScrimPainter( + excludePath: highlightRegionPath, + opacity: opacity, + ), + ), + ); + }, + ); + }, + ), + ), + ], + ), + ), + ); + }, + ); + }, + ), + ); + } + + void _onViewStateChanged(MagnifierState v) { + viewStateNotifier.value = viewStateNotifier.value.copyWith( + position: v.position, + scale: v.scale, + ); + } + + void _onViewScaleBoundariesChanged(ScaleBoundaries v) { + viewStateNotifier.value = viewStateNotifier.value.copyWith( + viewportSize: v.viewportSize, + contentSize: v.contentSize, + ); + } + + void _onActionChanged() => _updateScrim(); + + void _onTransformEvent(TransformEvent event) => _updateScrim(); + + void _updateScrim() => _scrimOpacityNotifier.value = _getActionScrimOpacity(widget.actionNotifier.value, transformController.activity); + + static double _getActionPanInertia(EditorAction? action) { + switch (action) { + case EditorAction.transform: + return 0; + case null: + return AvesMagnifier.defaultPanInertia; + } + } + + static double _getActionScrimOpacity(EditorAction? action, TransformActivity activity) { + switch (action) { + case EditorAction.transform: + switch (activity) { + case TransformActivity.none: + return .9; + case TransformActivity.pan: + case TransformActivity.resize: + case TransformActivity.straighten: + return .6; + } + case null: + return 0; + } + } +} diff --git a/lib/widgets/editor/transform/control_panel.dart b/lib/widgets/editor/transform/control_panel.dart new file mode 100644 index 000000000..4615563bd --- /dev/null +++ b/lib/widgets/editor/transform/control_panel.dart @@ -0,0 +1,196 @@ +import 'package:aves/model/entry/entry.dart'; +import 'package:aves/theme/durations.dart'; +import 'package:aves/theme/icons.dart'; +import 'package:aves/view/view.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; +import 'package:aves/widgets/common/identity/buttons/overlay_button.dart'; +import 'package:aves/widgets/editor/control_panel.dart'; +import 'package:aves/widgets/editor/transform/controller.dart'; +import 'package:aves/widgets/editor/transform/transformation.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:tuple/tuple.dart'; + +class TransformControlPanel extends StatefulWidget { + final AvesEntry entry; + final VoidCallback onCancel; + final void Function(Transformation transformation) onApply; + + const TransformControlPanel({ + super.key, + required this.entry, + required this.onCancel, + required this.onApply, + }); + + @override + State createState() => _TransformControlPanelState(); +} + +class _TransformControlPanelState extends State with TickerProviderStateMixin { + late final List> _tabs; + late final TabController _tabController; + + static const padding = EditorControlPanel.padding; + + @override + void initState() { + super.initState(); + _tabs = [ + Tuple2( + (context) => Tab(text: context.l10n.editorTransformCrop), + (context) => const CropControlPanel(), + ), + Tuple2( + (context) => Tab(text: context.l10n.editorTransformRotate), + (context) => const RotationControlPanel(), + ), + ]; + _tabController = TabController( + length: _tabs.length, + vsync: this, + ); + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final transformController = context.watch(); + return Column( + children: [ + SizedBox( + height: CropControlPanel.preferredHeight(context), + child: AnimatedBuilder( + animation: _tabController, + builder: (context, child) { + return AnimatedSwitcher( + duration: context.select((v) => v.formTransition), + child: _tabs[_tabController.index].item2(context), + ); + }, + ), + ), + const SizedBox(height: padding), + Row( + children: [ + const OverlayButton( + child: BackButton(), + ), + Expanded( + child: TabBar( + tabs: _tabs.map((v) => v.item1(context)).toList(), + controller: _tabController, + padding: const EdgeInsets.symmetric(horizontal: padding), + indicatorSize: TabBarIndicatorSize.label, + ), + ), + OverlayButton( + child: StreamBuilder( + stream: transformController.transformationStream, + builder: (context, snapshot) { + return IconButton( + icon: const Icon(AIcons.apply), + onPressed: transformController.modified ? () => widget.onApply(transformController.transformation) : null, + tooltip: context.l10n.applyTooltip, + ); + }, + ), + ), + ], + ), + ], + ); + } +} + +class CropControlPanel extends StatelessWidget { + const CropControlPanel({super.key}); + + static double preferredHeight(BuildContext context) => CropAspectRatio.values.map((v) { + return CaptionedButton.getSize(context, v.getText(context), showCaption: true).height; + }).max; + + @override + Widget build(BuildContext context) { + final aspectRatioNotifier = context.select>((v) => v.aspectRatioNotifier); + return ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemBuilder: (context, index) { + final ratio = CropAspectRatio.values[index]; + void setAspectRatio() => aspectRatioNotifier.value = ratio; + return CaptionedButton( + iconButtonBuilder: (context, focusNode) { + return ValueListenableBuilder( + valueListenable: aspectRatioNotifier, + builder: (context, selectedRatio, child) { + return IconButton( + color: ratio == selectedRatio ? Theme.of(context).colorScheme.primary : null, + onPressed: setAspectRatio, + focusNode: focusNode, + icon: ratio.getIcon(), + ); + }, + ); + }, + caption: ratio.getText(context), + onPressed: setAspectRatio, + ); + }, + itemCount: CropAspectRatio.values.length, + ); + } +} + +class RotationControlPanel extends StatelessWidget { + const RotationControlPanel({super.key}); + + @override + Widget build(BuildContext context) { + final controller = context.watch(); + + return Row( + children: [ + _buildButton(context, EntryAction.flip, controller.flipHorizontally), + Expanded( + child: StreamBuilder( + stream: controller.transformationStream, + builder: (context, snapshot) { + final transformation = snapshot.data ?? Transformation.zero; + return Slider( + value: transformation.straightenDegrees, + min: TransformController.straightenDegreesMin, + max: TransformController.straightenDegreesMax, + divisions: 18, + onChangeStart: (v) => controller.activity = TransformActivity.straighten, + onChangeEnd: (v) => controller.activity = TransformActivity.none, + label: NumberFormat('0.0°', context.l10n.localeName).format(transformation.straightenDegrees), + onChanged: (v) => controller.straightenDegrees = v, + ); + }, + ), + ), + _buildButton(context, EntryAction.rotateCW, controller.rotateClockwise), + ], + ); + } + + Widget _buildButton(BuildContext context, EntryAction action, VoidCallback onPressed) { + return OverlayButton( + child: IconButton( + icon: action.getIcon(), + onPressed: onPressed, + tooltip: action.getText(context), + ), + ); + } +} diff --git a/lib/widgets/editor/transform/controller.dart b/lib/widgets/editor/transform/controller.dart new file mode 100644 index 000000000..0c414a326 --- /dev/null +++ b/lib/widgets/editor/transform/controller.dart @@ -0,0 +1,88 @@ +import 'dart:async'; +import 'dart:ui'; + +import 'package:aves/widgets/editor/transform/crop_region.dart'; +import 'package:aves/widgets/editor/transform/transformation.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:flutter/foundation.dart'; + +class TransformController { + ValueNotifier aspectRatioNotifier = ValueNotifier(CropAspectRatio.free); + + TransformActivity _activity = TransformActivity.none; + + TransformActivity get activity => _activity; + + Transformation _transformation = Transformation.zero; + + Transformation get transformation => _transformation; + + bool get modified => _transformation != Transformation.zero; + + final StreamController _transformationStreamController = StreamController.broadcast(); + + Stream get transformationStream => _transformationStreamController.stream; + + final StreamController _eventStreamController = StreamController.broadcast(); + + Stream get eventStream => _eventStreamController.stream; + + static const double straightenDegreesMin = -45; + static const double straightenDegreesMax = 45; + + final Size displaySize; + + TransformController(this.displaySize) { + reset(); + aspectRatioNotifier.addListener(_onAspectRatioChanged); + } + + void dispose() { + aspectRatioNotifier.dispose(); + } + + void reset() { + _transformation = Transformation.zero.copyWith( + region: CropRegion.fromRect(Offset.zero & displaySize), + ); + _transformationStreamController.add(_transformation); + } + + void flipHorizontally() { + _transformation = _transformation.copyWith( + orientation: _transformation.orientation.flipHorizontally(), + straightenDegrees: -transformation.straightenDegrees, + ); + _transformationStreamController.add(_transformation); + } + + void rotateClockwise() { + _transformation = _transformation.copyWith( + orientation: _transformation.orientation.rotateClockwise(), + ); + _transformationStreamController.add(_transformation); + } + + set straightenDegrees(double straightenDegrees) { + _transformation = _transformation.copyWith( + straightenDegrees: straightenDegrees.clamp(straightenDegreesMin, straightenDegreesMax), + ); + _transformationStreamController.add(_transformation); + } + + set cropRegion(CropRegion region) { + _transformation = _transformation.copyWith( + region: region, + ); + _transformationStreamController.add(_transformation); + } + + set activity(TransformActivity activity) { + _activity = activity; + _eventStreamController.add(TransformEvent(activity: _activity)); + } + + void _onAspectRatioChanged() { + // TODO TLAD [crop] apply + } +} diff --git a/lib/widgets/editor/transform/crop_region.dart b/lib/widgets/editor/transform/crop_region.dart new file mode 100644 index 000000000..013a12c9a --- /dev/null +++ b/lib/widgets/editor/transform/crop_region.dart @@ -0,0 +1,48 @@ +import 'dart:ui'; + +import 'package:collection/collection.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart'; + +@immutable +class CropRegion extends Equatable { + final Offset topLeft, topRight, bottomRight, bottomLeft; + + List get corners => [topLeft, topRight, bottomRight, bottomLeft]; + + Offset get center => (topLeft + bottomRight) / 2; + + Rect get outsideRect { + final xMin = corners.map((v) => v.dx).min; + final xMax = corners.map((v) => v.dx).max; + final yMin = corners.map((v) => v.dy).min; + final yMax = corners.map((v) => v.dy).max; + return Rect.fromPoints(Offset(xMin, yMin), Offset(xMax, yMax)); + } + + @override + List get props => [topLeft, topRight, bottomRight, bottomLeft]; + + const CropRegion({ + required this.topLeft, + required this.topRight, + required this.bottomRight, + required this.bottomLeft, + }); + + static const CropRegion zero = CropRegion( + topLeft: Offset.zero, + topRight: Offset.zero, + bottomRight: Offset.zero, + bottomLeft: Offset.zero, + ); + + factory CropRegion.fromRect(Rect rect) { + return CropRegion( + topLeft: rect.topLeft, + topRight: rect.topRight, + bottomRight: rect.bottomRight, + bottomLeft: rect.bottomLeft, + ); + } +} diff --git a/lib/widgets/editor/transform/cropper.dart b/lib/widgets/editor/transform/cropper.dart new file mode 100644 index 000000000..df31cc44b --- /dev/null +++ b/lib/widgets/editor/transform/cropper.dart @@ -0,0 +1,734 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:aves/model/view_state.dart'; +import 'package:aves/theme/durations.dart'; +import 'package:aves/widgets/common/extensions/geometry.dart'; +import 'package:aves/widgets/common/fx/dashed_path_painter.dart'; +import 'package:aves/widgets/editor/transform/controller.dart'; +import 'package:aves/widgets/editor/transform/crop_region.dart'; +import 'package:aves/widgets/editor/transform/handles.dart'; +import 'package:aves/widgets/editor/transform/painter.dart'; +import 'package:aves/widgets/editor/transform/transformation.dart'; +import 'package:aves_magnifier/aves_magnifier.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:aves_utils/aves_utils.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class Cropper extends StatefulWidget { + final AvesMagnifierController magnifierController; + final TransformController transformController; + final ValueNotifier paddingNotifier; + + static const double handleDimension = kMinInteractiveDimension; + static const EdgeInsets imagePadding = EdgeInsets.all(kMinInteractiveDimension); + + const Cropper({ + super.key, + required this.magnifierController, + required this.transformController, + required this.paddingNotifier, + }); + + @override + State createState() => _CropperState(); +} + +class _CropperState extends State with SingleTickerProviderStateMixin { + final List _subscriptions = []; + final ValueNotifier _viewportSizeNotifier = ValueNotifier(Size.zero); + final ValueNotifier _outlineNotifier = ValueNotifier(Rect.zero); + final ValueNotifier _gridDivisionNotifier = ValueNotifier(0); + late AnimationController _gridAnimationController; + late Animation _gridOpacity; + + static const double minDimension = Cropper.handleDimension; + static const int panResizeGridDivision = 3; + static const int straightenGridDivision = 9; + static const double overOutlineFactor = .25; + + AvesMagnifierController get magnifierController => widget.magnifierController; + + TransformController get transformController => widget.transformController; + + Transformation get transformation => transformController.transformation; + + CropAspectRatio get cropAspectRatio => transformController.aspectRatioNotifier.value; + + @override + void initState() { + super.initState(); + final initialRegion = transformation.region; + _viewportSizeNotifier.addListener(() => _initOutline(initialRegion)); + _gridAnimationController = AnimationController( + duration: context.read().viewerOverlayAnimation, + vsync: this, + ); + _gridOpacity = CurvedAnimation( + parent: _gridAnimationController, + curve: Curves.easeOutQuad, + ); + _registerWidget(widget); + _initOutline(initialRegion); + } + + @override + void didUpdateWidget(covariant Cropper oldWidget) { + super.didUpdateWidget(oldWidget); + _unregisterWidget(oldWidget); + _registerWidget(widget); + } + + @override + void dispose() { + _viewportSizeNotifier.dispose(); + _outlineNotifier.dispose(); + _gridDivisionNotifier.dispose(); + _gridAnimationController.dispose(); + _unregisterWidget(widget); + super.dispose(); + } + + void _registerWidget(Cropper widget) { + _subscriptions.add(widget.magnifierController.stateStream.listen(_onViewStateChanged)); + _subscriptions.add(widget.magnifierController.scaleBoundariesStream.listen(_onViewBoundariesChanged)); + _subscriptions.add(widget.transformController.eventStream.listen(_onTransformEvent)); + _subscriptions.add(widget.transformController.transformationStream.map((v) => v.orientation).distinct().listen(_onOrientationChanged)); + _subscriptions.add(widget.transformController.transformationStream.map((v) => v.straightenDegrees).distinct().listen(_onStraightenDegreesChanged)); + widget.transformController.aspectRatioNotifier.addListener(_onCropAspectRatioChanged); + } + + void _unregisterWidget(Cropper widget) { + _subscriptions + ..forEach((sub) => sub.cancel()) + ..clear(); + widget.transformController.aspectRatioNotifier.removeListener(_onCropAspectRatioChanged); + } + + @override + Widget build(BuildContext context) { + return Positioned.fill( + child: ValueListenableBuilder( + valueListenable: widget.paddingNotifier, + builder: (context, padding, child) { + return ValueListenableBuilder( + valueListenable: _outlineNotifier, + builder: (context, outline, child) { + if (outline.isEmpty) return const SizedBox(); + + final outlineVisualRect = outline.translate(padding.left, padding.top); + return Stack( + children: [ + Positioned.fill( + child: IgnorePointer( + child: Stack( + children: [ + _buildDashLine([outlineVisualRect.topLeft, outlineVisualRect.topRight]), + _buildDashLine([outlineVisualRect.bottomLeft, outlineVisualRect.bottomRight]), + _buildDashLine([outlineVisualRect.topLeft, outlineVisualRect.bottomLeft]), + _buildDashLine([outlineVisualRect.topRight, outlineVisualRect.bottomRight]), + Positioned.fill( + child: ValueListenableBuilder( + valueListenable: _gridDivisionNotifier, + builder: (context, gridDivision, child) { + return ValueListenableBuilder( + valueListenable: _gridOpacity, + builder: (context, gridOpacity, child) { + return CustomPaint( + painter: CropperPainter( + rect: outlineVisualRect, + gridOpacity: gridOpacity, + gridDivision: gridDivision, + ), + ); + }, + ); + }, + ), + ), + ], + ), + ), + ), + _buildVertexHandle( + padding: padding, + getPosition: () => outline.topLeft, + setPosition: (v) => _handleOutline( + topLeft: Offset(min(outline.right - minDimension, v.dx), min(outline.bottom - minDimension, v.dy)), + ), + ), + _buildVertexHandle( + padding: padding, + getPosition: () => outline.topRight, + setPosition: (v) => _handleOutline( + topRight: Offset(max(outline.left + minDimension, v.dx), min(outline.bottom - minDimension, v.dy)), + ), + ), + _buildVertexHandle( + padding: padding, + getPosition: () => outline.bottomRight, + setPosition: (v) => _handleOutline( + bottomRight: Offset(max(outline.left + minDimension, v.dx), max(outline.top + minDimension, v.dy)), + ), + ), + _buildVertexHandle( + padding: padding, + getPosition: () => outline.bottomLeft, + setPosition: (v) => _handleOutline( + bottomLeft: Offset(min(outline.right - minDimension, v.dx), max(outline.top + minDimension, v.dy)), + ), + ), + _buildEdgeHandle( + padding: padding, + getEdge: () => Rect.fromPoints(outline.bottomLeft, outline.topLeft), + setEdge: (v) { + final left = min(outline.right - minDimension, v.left); + return _handleOutline( + topLeft: Offset(left, outline.top), + bottomLeft: Offset(left, outline.bottom), + ); + }, + ), + _buildEdgeHandle( + padding: padding, + getEdge: () => Rect.fromPoints(outline.topLeft, outline.topRight), + setEdge: (v) { + final top = min(outline.bottom - minDimension, v.top); + return _handleOutline( + topLeft: Offset(outline.left, top), + topRight: Offset(outline.right, top), + ); + }, + ), + _buildEdgeHandle( + padding: padding, + getEdge: () => Rect.fromPoints(outline.bottomRight, outline.topRight), + setEdge: (v) { + final right = max(outline.left + minDimension, v.right); + return _handleOutline( + topRight: Offset(right, outline.top), + bottomRight: Offset(right, outline.bottom), + ); + }, + ), + _buildEdgeHandle( + padding: padding, + getEdge: () => Rect.fromPoints(outline.bottomLeft, outline.bottomRight), + setEdge: (v) { + final bottom = max(outline.top + minDimension, v.bottom); + return _handleOutline( + bottomLeft: Offset(outline.left, bottom), + bottomRight: Offset(outline.right, bottom), + ); + }, + ), + ], + ); + }, + ); + }, + ), + ); + } + + // use 1 painter per line so that the dashes of one line + // do not get offset depending on the previous line length + Widget _buildDashLine(List points) => CustomPaint( + painter: DashedPathPainter( + originalPath: Path()..addPolygon(points, false), + pathColor: CropperPainter.borderColor, + strokeWidth: CropperPainter.borderWidth, + ), + ); + + void _handleOutline({ + Offset? topLeft, + Offset? topRight, + Offset? bottomRight, + Offset? bottomLeft, + }) { + final currentOutline = _outlineNotifier.value; + var targetOutline = Rect.fromLTRB( + topLeft?.dx ?? bottomLeft?.dx ?? currentOutline.left, + topLeft?.dy ?? topRight?.dy ?? currentOutline.top, + topRight?.dx ?? bottomRight?.dx ?? currentOutline.right, + bottomLeft?.dy ?? bottomRight?.dy ?? currentOutline.bottom, + ); + + _RatioStrategy? ratioStrategy; + if (topLeft != null && topRight != null) { + ratioStrategy = _RatioStrategy.pinBottom; + } else if (topRight != null && bottomRight != null) { + ratioStrategy = _RatioStrategy.pinLeft; + } else if (bottomLeft != null && bottomRight != null) { + ratioStrategy = _RatioStrategy.pinTop; + } else if (topLeft != null && bottomLeft != null) { + ratioStrategy = _RatioStrategy.pinRight; + } else if (topLeft != null) { + ratioStrategy = _RatioStrategy.pinBottomRight; + } else if (topRight != null) { + ratioStrategy = _RatioStrategy.pinBottomLeft; + } else if (bottomRight != null) { + ratioStrategy = _RatioStrategy.pinTopLeft; + } else if (bottomLeft != null) { + ratioStrategy = _RatioStrategy.pinTopRight; + } + if (ratioStrategy != null) { + targetOutline = _applyCropRatioToOutline(targetOutline, ratioStrategy); + } + + // do not try to coerce outline handled outside tilted image + if (transformation.straightenDegrees != 0 && !_isOutlineContained(targetOutline)) return; + + // dismiss if we could not honour aspect ratio + if (cropAspectRatio != CropAspectRatio.free && !_isOutlineContained(targetOutline)) return; + + final currentState = _getViewState(); + final boundaries = magnifierController.scaleBoundaries; + if (currentState == null || boundaries == null) return; + + final gestureRegion = _regionFromOutline(currentState, targetOutline); + final viewportSize = boundaries.viewportSize; + + final gestureOutline = _regionToContainedOutline(currentState, gestureRegion); + final clampedOutline = Rect.fromLTRB( + max(gestureOutline.left, 0), + max(gestureOutline.top, 0), + min(gestureOutline.right, viewportSize.width), + min(gestureOutline.bottom, viewportSize.height), + ); + _setOutline(clampedOutline); + _updateCropRegion(); + + // zoom out when user gesture reaches outer edges + + if (gestureOutline.width - clampedOutline.width > precisionErrorTolerance || gestureOutline.height - clampedOutline.height > precisionErrorTolerance) { + final targetOutline = Rect.lerp(clampedOutline, gestureOutline, overOutlineFactor)!; + final targetRegion = _regionFromOutline(currentState, targetOutline); + + final nextState = _viewStateForContainedRegion(boundaries, targetRegion); + if (nextState != currentState) { + magnifierController.update( + position: nextState.position, + scale: nextState.scale, + source: ChangeSource.animation, + ); + _setOutline(_regionToContainedOutline(nextState, targetRegion)); + } + } + } + + bool _isOutlineContained(Rect outline) { + final currentState = _getViewState(); + final boundaries = magnifierController.scaleBoundaries; + if (currentState == null || boundaries == null) return false; + + final regionToOutlineMatrix = _getRegionToOutlineMatrix(currentState); + final outlineToRegionMatrix = Matrix4.inverted(regionToOutlineMatrix); + final regionCorners = { + outline.topLeft, + outline.topRight, + outline.bottomRight, + outline.bottomLeft, + }.map(outlineToRegionMatrix.transformOffset).toSet(); + + final contentRect = Offset.zero & boundaries.contentSize; + return regionCorners.every((v) => contentRect.containsIncludingBottomRight(v, tolerance: precisionErrorTolerance)); + } + + VertexHandle _buildVertexHandle({ + required EdgeInsets padding, + required ValueGetter getPosition, + required ValueSetter setPosition, + }) { + return VertexHandle( + padding: padding, + getPosition: getPosition, + setPosition: setPosition, + onDragStart: _onDragStart, + onDragEnd: _onDragEnd, + ); + } + + EdgeHandle _buildEdgeHandle({ + required EdgeInsets padding, + required ValueGetter getEdge, + required ValueSetter setEdge, + }) { + return EdgeHandle( + padding: padding, + getEdge: getEdge, + setEdge: setEdge, + onDragStart: _onDragStart, + onDragEnd: _onDragEnd, + ); + } + + void _onDragStart() { + transformController.activity = TransformActivity.resize; + } + + void _onDragEnd() { + transformController.activity = TransformActivity.none; + _showRegion(); + } + + void _showRegion() { + final boundaries = magnifierController.scaleBoundaries; + if (boundaries == null) return; + + final region = transformation.region; + final nextState = _viewStateForContainedRegion(boundaries, region); + + magnifierController.update( + position: nextState.position, + scale: nextState.scale, + source: ChangeSource.animation, + ); + _setOutline(_regionToContainedOutline(nextState, region)); + } + + ViewState _viewStateForContainedRegion(ScaleBoundaries boundaries, CropRegion region) { + final regionSize = MatrixUtils.transformRect(transformation.matrix, region.outsideRect).size; + final nextScale = boundaries.clampScale(ScaleLevel.scaleForContained(boundaries.viewportSize, regionSize)); + final nextPosition = boundaries.clampPosition( + position: boundaries.contentToStatePosition(nextScale, region.center), + scale: nextScale, + ); + return ViewState( + position: nextPosition, + scale: nextScale, + viewportSize: boundaries.viewportSize, + contentSize: boundaries.contentSize, + ); + } + + void _onTransformEvent(TransformEvent event) { + final activity = event.activity; + switch (activity) { + case TransformActivity.none: + break; + case TransformActivity.pan: + case TransformActivity.resize: + _gridDivisionNotifier.value = panResizeGridDivision; + break; + case TransformActivity.straighten: + _gridDivisionNotifier.value = straightenGridDivision; + break; + } + if (activity == TransformActivity.none) { + _gridAnimationController.reverse(); + } else { + _gridAnimationController.forward(); + } + } + + void _onOrientationChanged(TransformOrientation orientation) { + _showRegion(); + } + + void _onStraightenDegreesChanged(double degrees) { + _updateCropRegion(); + } + + void _onCropAspectRatioChanged() { + final viewState = _getViewState(); + if (viewState == null) return; + + var targetOutline = _applyCropRatioToOutline(_outlineNotifier.value, _RatioStrategy.keepArea); + if (!_isOutlineContained(targetOutline)) { + targetOutline = _applyCropRatioToOutline(_outlineNotifier.value, _RatioStrategy.contain); + } + transformController.cropRegion = _regionFromOutline(viewState, targetOutline); + _showRegion(); + } + + void _onViewStateChanged(MagnifierState state) { + final currentOutline = _outlineNotifier.value; + switch (state.source) { + case ChangeSource.internal: + case ChangeSource.animation: + _setOutline(currentOutline); + break; + case ChangeSource.gesture: + // TODO TLAD [crop] use other strat + _setOutline(_applyCropRatioToOutline(currentOutline, _RatioStrategy.contain)); + _updateCropRegion(); + break; + } + } + + void _onViewBoundariesChanged(ScaleBoundaries scaleBoundaries) { + _viewportSizeNotifier.value = scaleBoundaries.viewportSize; + } + + ViewState? _getViewState() { + final scaleBoundaries = magnifierController.scaleBoundaries; + if (scaleBoundaries == null) return null; + + final state = magnifierController.currentState; + return ViewState( + position: state.position, + scale: state.scale, + viewportSize: scaleBoundaries.viewportSize, + contentSize: scaleBoundaries.contentSize, + ); + } + + void _initOutline(CropRegion region) { + final viewState = _getViewState(); + if (viewState != null) { + _setOutline(_regionToContainedOutline(viewState, region)); + _updateCropRegion(); + } + } + + void _setOutline(Rect targetOutline) { + final viewState = _getViewState(); + final viewportSize = viewState?.viewportSize; + if (targetOutline.isEmpty || viewState == null || viewportSize == null) return; + + // ensure outline is within content + final targetRegion = _regionFromOutline(viewState, targetOutline); + var newOutline = _regionToContainedOutline(viewState, targetRegion); + + // ensure outline is large enough to be handled + newOutline = Rect.fromLTWH( + newOutline.left, + newOutline.top, + max(newOutline.width, minDimension), + max(newOutline.height, minDimension), + ); + + // ensure outline is within viewport + newOutline = Rect.fromLTRB( + max(newOutline.left, 0), + max(newOutline.top, 0), + min(newOutline.right, viewportSize.width), + min(newOutline.bottom, viewportSize.height), + ); + + _outlineNotifier.value = newOutline; + } + + void _updateCropRegion() { + final viewState = _getViewState(); + final outline = _outlineNotifier.value; + if (viewState != null && !outline.isEmpty) { + transformController.cropRegion = _regionFromOutline(viewState, outline); + } + } + + Matrix4 _getRegionToOutlineMatrix(ViewState viewState) { + final magnifierMatrix = viewState.matrix; + + final viewportCenter = viewState.viewportSize!.center(Offset.zero); + final transformOrigin = Matrix4.inverted(magnifierMatrix).transformOffset(viewportCenter); + final transformMatrix = Matrix4.identity() + ..translate(transformOrigin.dx, transformOrigin.dy) + ..multiply(transformation.matrix) + ..translate(-transformOrigin.dx, -transformOrigin.dy); + + return magnifierMatrix..multiply(transformMatrix); + } + + CropRegion _regionFromOutline(ViewState viewState, Rect outline) { + final regionToOutlineMatrix = _getRegionToOutlineMatrix(viewState); + final outlineToRegionMatrix = regionToOutlineMatrix..invert(); + + final region = CropRegion( + topLeft: outlineToRegionMatrix.transformOffset(outline.topLeft), + topRight: outlineToRegionMatrix.transformOffset(outline.topRight), + bottomRight: outlineToRegionMatrix.transformOffset(outline.bottomRight), + bottomLeft: outlineToRegionMatrix.transformOffset(outline.bottomLeft), + ); + + final rect = Offset.zero & viewState.contentSize!; + double clampX(double dx) => dx.clamp(rect.left, rect.right); + double clampY(double dy) => dy.clamp(rect.top, rect.bottom); + Offset clampPoint(Offset v) => Offset(clampX(v.dx), clampY(v.dy)); + final clampedRegion = CropRegion( + topLeft: clampPoint(region.topLeft), + topRight: clampPoint(region.topRight), + bottomRight: clampPoint(region.bottomRight), + bottomLeft: clampPoint(region.bottomLeft), + ); + return clampedRegion; + } + + Rect _regionToContainedOutline(ViewState viewState, CropRegion region) { + final matrix = _getRegionToOutlineMatrix(viewState); + final points = region.corners.map(matrix.transformOffset).toSet(); + final sortedX = points.map((v) => v.dx).toList()..sort(); + final sortedY = points.map((v) => v.dy).toList()..sort(); + final topLeft = Offset(sortedX[1], sortedY[1]); + final bottomRight = Offset(sortedX[2], sortedY[2]); + return Rect.fromPoints(topLeft, bottomRight); + } + + Rect _applyCropRatioToOutline(Rect outline, _RatioStrategy strategy) { + final currentState = _getViewState(); + final boundaries = magnifierController.scaleBoundaries; + if (currentState == null || boundaries == null) return outline; + + final contentSize = boundaries.contentSize; + + late int longCoef; + late int shortCoef; + switch (cropAspectRatio) { + case CropAspectRatio.free: + return outline; + case CropAspectRatio.original: + longCoef = contentSize.longestSide.round(); + shortCoef = contentSize.shortestSide.round(); + break; + case CropAspectRatio.square: + longCoef = 1; + shortCoef = 1; + break; + case CropAspectRatio.ar_16_9: + longCoef = 16; + shortCoef = 9; + break; + case CropAspectRatio.ar_4_3: + longCoef = 4; + shortCoef = 3; + break; + } + + final contentRect = Offset.zero & contentSize; + final isLandscape = (outline.width - outline.height).abs() > precisionErrorTolerance ? outline.width > outline.height : contentSize.width > contentSize.height; + final newRatio = isLandscape ? longCoef / shortCoef : shortCoef / longCoef; + + Size sizeToKeepArea() { + final f = (outline.longestSide + outline.shortestSide) / (longCoef + shortCoef); + final newLongest = f * longCoef; + final newShortest = f * shortCoef; + return isLandscape ? Size(newLongest, newShortest) : Size(newShortest, newLongest); + } + + final regionToOutlineMatrix = _getRegionToOutlineMatrix(currentState); + final outlineToRegionMatrix = Matrix4.inverted(regionToOutlineMatrix); + + Rect pinnedRect(Rect Function(Size targetSize) forSize) { + final targetSize = sizeToKeepArea(); + final rect = forSize(targetSize); + + // do not try to coerce outline handled outside tilted image + if (transformation.straightenDegrees != 0) return rect; + + final regionCorners = { + rect.topLeft, + rect.topRight, + rect.bottomRight, + rect.bottomLeft, + }.map(outlineToRegionMatrix.transformOffset).toSet(); + + if (regionCorners.every((v) => contentRect.containsIncludingBottomRight(v, tolerance: precisionErrorTolerance))) return rect; + + final clampedOutlineCorners = regionCorners.map((v) => regionToOutlineMatrix.transformOffset(Offset(v.dx.clamp(0, contentSize.width), v.dy.clamp(0, contentSize.height)))).toSet(); + final minX = clampedOutlineCorners.map((v) => v.dx).min; + final maxX = clampedOutlineCorners.map((v) => v.dx).max; + final minY = clampedOutlineCorners.map((v) => v.dy).min; + final maxY = clampedOutlineCorners.map((v) => v.dy).max; + + var width = rect.width; + var height = rect.height; + if (rect.left < minX - precisionErrorTolerance) { + width = rect.right - minX; + height = width / newRatio; + } else if (rect.top < minY - precisionErrorTolerance) { + height = rect.bottom - minY; + width = height * newRatio; + } else if (rect.right > maxX + precisionErrorTolerance) { + width = maxX - rect.left; + height = width / newRatio; + } else if (rect.bottom > maxY + precisionErrorTolerance) { + height = maxY - rect.top; + width = height * newRatio; + } + final clampedSize = Size(width, height); + return clampedSize < targetSize ? forSize(clampedSize) : rect; + } + + switch (strategy) { + case _RatioStrategy.keepArea: + final targetSize = sizeToKeepArea(); + return Rect.fromCenter( + center: outline.center, + width: targetSize.width, + height: targetSize.height, + ); + case _RatioStrategy.contain: + final currentRatio = outline.width / outline.height; + if ((newRatio - currentRatio).abs() < precisionErrorTolerance) { + return outline; + } else { + late final Size targetSize; + if (newRatio > currentRatio) { + targetSize = Size(outline.width, outline.width / newRatio); + } else { + targetSize = Size(outline.height * newRatio, outline.height); + } + return Rect.fromCenter( + center: outline.center, + width: targetSize.width, + height: targetSize.height, + ); + } + case _RatioStrategy.pinTopLeft: + return pinnedRect((targetSize) => Rect.fromPoints( + outline.topLeft, + outline.topLeft.translate(targetSize.width, targetSize.height), + )); + case _RatioStrategy.pinTopRight: + return pinnedRect((targetSize) => Rect.fromPoints( + outline.topRight, + outline.topRight.translate(-targetSize.width, targetSize.height), + )); + case _RatioStrategy.pinBottomRight: + return pinnedRect((targetSize) => Rect.fromPoints( + outline.bottomRight, + outline.bottomRight.translate(-targetSize.width, -targetSize.height), + )); + case _RatioStrategy.pinBottomLeft: + return pinnedRect((targetSize) => Rect.fromPoints( + outline.bottomLeft, + outline.bottomLeft.translate(targetSize.width, -targetSize.height), + )); + case _RatioStrategy.pinLeft: + return pinnedRect((targetSize) => Rect.fromLTRB( + outline.left, + outline.center.dy - targetSize.height / 2, + outline.left + targetSize.width, + outline.center.dy + targetSize.height / 2, + )); + case _RatioStrategy.pinTop: + return pinnedRect((targetSize) => Rect.fromLTRB( + outline.center.dx - targetSize.width / 2, + outline.top, + outline.center.dx + targetSize.width / 2, + outline.top + targetSize.height, + )); + case _RatioStrategy.pinRight: + return pinnedRect((targetSize) => Rect.fromLTRB( + outline.right - targetSize.width, + outline.center.dy - targetSize.height / 2, + outline.right, + outline.center.dy + targetSize.height / 2, + )); + case _RatioStrategy.pinBottom: + return pinnedRect((targetSize) => Rect.fromLTRB( + outline.center.dx - targetSize.width / 2, + outline.bottom - targetSize.height, + outline.center.dx + targetSize.width / 2, + outline.bottom, + )); + } + } +} + +enum _RatioStrategy { keepArea, contain, pinTopLeft, pinTopRight, pinBottomRight, pinBottomLeft, pinLeft, pinTop, pinRight, pinBottom } diff --git a/lib/widgets/editor/transform/handles.dart b/lib/widgets/editor/transform/handles.dart new file mode 100644 index 000000000..9bcd87ad7 --- /dev/null +++ b/lib/widgets/editor/transform/handles.dart @@ -0,0 +1,120 @@ +import 'package:aves/widgets/editor/transform/cropper.dart'; +import 'package:flutter/material.dart'; + +class VertexHandle extends StatefulWidget { + final EdgeInsets padding; + final ValueGetter getPosition; + final ValueSetter setPosition; + final VoidCallback onDragStart, onDragEnd; + + const VertexHandle({ + super.key, + required this.padding, + required this.getPosition, + required this.setPosition, + required this.onDragStart, + required this.onDragEnd, + }); + + @override + State createState() => _VertexHandleState(); +} + +class _VertexHandleState extends State { + Offset _start = Offset.zero; + Offset _totalDelta = Offset.zero; + + static const double _handleDim = Cropper.handleDimension; + + EdgeInsets get padding => widget.padding; + + @override + Widget build(BuildContext context) { + return Positioned.fromRect( + rect: Rect.fromCenter( + center: widget.getPosition().translate(padding.left, padding.right), + width: _handleDim, + height: _handleDim, + ), + child: GestureDetector( + onPanStart: (details) { + _totalDelta = Offset.zero; + _start = widget.getPosition(); + widget.onDragStart(); + }, + onPanUpdate: (details) { + _totalDelta += details.delta; + widget.setPosition(_start + _totalDelta); + }, + onPanEnd: (details) { + widget.onDragEnd(); + }, + child: const ColoredBox( + color: Colors.transparent, + ), + ), + ); + } +} + +class EdgeHandle extends StatefulWidget { + final EdgeInsets padding; + final ValueGetter getEdge; + final ValueSetter setEdge; + final VoidCallback onDragStart, onDragEnd; + + const EdgeHandle({ + super.key, + required this.padding, + required this.getEdge, + required this.setEdge, + required this.onDragStart, + required this.onDragEnd, + }); + + @override + State createState() => _EdgeHandleState(); +} + +class _EdgeHandleState extends State { + Rect _start = Rect.zero; + Offset _totalDelta = Offset.zero; + + static const double _handleDim = Cropper.handleDimension; + + EdgeInsets get padding => widget.padding; + + @override + Widget build(BuildContext context) { + var edge = widget.getEdge(); + if (edge.width > _handleDim && edge.height == 0) { + // horizontal edge + edge = Rect.fromLTWH(edge.left + _handleDim / 2, edge.top - _handleDim / 2, edge.width - _handleDim, _handleDim); + } else if (edge.height > _handleDim && edge.width == 0) { + // vertical edge + edge = Rect.fromLTWH(edge.left - _handleDim / 2, edge.top + _handleDim / 2, _handleDim, edge.height - _handleDim); + } + edge = edge.translate(padding.left, padding.right); + + return Positioned.fromRect( + rect: edge, + child: GestureDetector( + onPanStart: (details) { + _totalDelta = Offset.zero; + _start = widget.getEdge(); + widget.onDragStart(); + }, + onPanUpdate: (details) { + _totalDelta += details.delta; + widget.setEdge(Rect.fromLTWH(_start.left + _totalDelta.dx, _start.top + _totalDelta.dy, _start.width, _start.height)); + }, + onPanEnd: (details) { + widget.onDragEnd(); + }, + child: const ColoredBox( + color: Colors.transparent, + ), + ), + ); + } +} diff --git a/lib/widgets/editor/transform/painter.dart b/lib/widgets/editor/transform/painter.dart new file mode 100644 index 000000000..90f82433c --- /dev/null +++ b/lib/widgets/editor/transform/painter.dart @@ -0,0 +1,131 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +class CropperPainter extends CustomPainter { + final Rect rect; + final double gridOpacity; + final int gridDivision; + + const CropperPainter({ + required this.rect, + required this.gridOpacity, + required this.gridDivision, + }); + + static const double handleLength = kMinInteractiveDimension / 3 - 4; + static const double handleWidth = 3; + static const double borderWidth = 1; + static const double gridWidth = 1; + + static const cornerColor = Colors.white; + static final borderColor = Colors.white.withOpacity(.5); + static final gridColor = Colors.white.withOpacity(.5); + + @override + void paint(Canvas canvas, Size size) { + final cornerPaint = Paint() + ..style = PaintingStyle.fill + ..strokeCap = StrokeCap.round + ..strokeWidth = handleWidth + ..color = cornerColor; + final gridPaint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = gridWidth + ..color = gridColor.withOpacity(gridColor.opacity * gridOpacity); + + final xLeft = rect.left; + final yTop = rect.top; + final xRight = rect.right; + final yBottom = rect.bottom; + + final gridLeft = xLeft + borderWidth / 2; + final gridRight = xRight - borderWidth / 2; + final yStep = (yBottom - yTop) / gridDivision; + for (var i = 1; i < gridDivision; i++) { + canvas.drawLine( + Offset(gridLeft, yTop + i * yStep), + Offset(gridRight, yTop + i * yStep), + gridPaint, + ); + } + final gridTop = yTop + borderWidth / 2; + final gridBottom = yBottom - borderWidth / 2; + final xStep = (xRight - xLeft) / gridDivision; + for (var i = 1; i < gridDivision; i++) { + canvas.drawLine( + Offset(xLeft + i * xStep, gridTop), + Offset(xLeft + i * xStep, gridBottom), + gridPaint, + ); + } + + canvas.drawPoints( + PointMode.polygon, + [ + rect.topLeft.translate(0, handleLength), + rect.topLeft, + rect.topLeft.translate(handleLength, 0), + ], + cornerPaint); + + canvas.drawPoints( + PointMode.polygon, + [ + rect.topRight.translate(-handleLength, 0), + rect.topRight, + rect.topRight.translate(0, handleLength), + ], + cornerPaint); + + canvas.drawPoints( + PointMode.polygon, + [ + rect.bottomRight.translate(0, -handleLength), + rect.bottomRight, + rect.bottomRight.translate(-handleLength, 0), + ], + cornerPaint); + + canvas.drawPoints( + PointMode.polygon, + [ + rect.bottomLeft.translate(handleLength, 0), + rect.bottomLeft, + rect.bottomLeft.translate(0, -handleLength), + ], + cornerPaint); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +} + +class ScrimPainter extends CustomPainter { + final Path excludePath; + final double opacity; + + const ScrimPainter({ + required this.excludePath, + required this.opacity, + }); + + static const double borderWidth = 1; + + static const scrimColor = Colors.black; + + @override + void paint(Canvas canvas, Size size) { + final scrimPaint = Paint() + ..style = PaintingStyle.fill + ..color = scrimColor.withOpacity(opacity); + + final outside = Path() + ..addRect(Rect.fromLTWH(0, 0, size.width, size.height).inflate(.5)) + ..close(); + canvas.drawPath(Path.combine(PathOperation.difference, outside, excludePath), scrimPaint); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +} diff --git a/lib/widgets/editor/transform/transformation.dart b/lib/widgets/editor/transform/transformation.dart new file mode 100644 index 000000000..455b62cb6 --- /dev/null +++ b/lib/widgets/editor/transform/transformation.dart @@ -0,0 +1,87 @@ +import 'dart:math' as math; + +import 'package:aves/widgets/editor/transform/crop_region.dart'; +import 'package:aves_model/aves_model.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:vector_math/vector_math_64.dart'; + +@immutable +class Transformation extends Equatable { + final TransformOrientation orientation; + final double straightenDegrees; + final CropRegion region; + + @override + List get props => [orientation, straightenDegrees, region]; + + static const zero = Transformation( + orientation: TransformOrientation.normal, + straightenDegrees: 0, + region: CropRegion.zero, + ); + + const Transformation({ + required this.orientation, + required this.straightenDegrees, + required this.region, + }); + + Transformation copyWith({ + TransformOrientation? orientation, + double? straightenDegrees, + CropRegion? region, + }) { + return Transformation( + orientation: orientation ?? this.orientation, + straightenDegrees: straightenDegrees ?? this.straightenDegrees, + region: region ?? this.region, + ); + } + + Matrix4 get matrix => _orientationMatrix..multiply(_straightenMatrix); + + Matrix4 get _orientationMatrix { + final matrix = Matrix4.identity(); + switch (orientation) { + case TransformOrientation.normal: + break; + case TransformOrientation.rotate90: + matrix.rotateZ(math.pi / 2); + break; + case TransformOrientation.rotate180: + matrix.rotateZ(math.pi); + break; + case TransformOrientation.rotate270: + matrix.rotateZ(3 * math.pi / 2); + break; + case TransformOrientation.transverse: + matrix.scale(-1.0, 1.0, 1.0); + matrix.rotateZ(-3 * math.pi / 2); + break; + case TransformOrientation.flipVertical: + matrix.scale(1.0, -1.0, 1.0); + break; + case TransformOrientation.transpose: + matrix.scale(-1.0, 1.0, 1.0); + matrix.rotateZ(-1 * math.pi / 2); + break; + case TransformOrientation.flipHorizontal: + matrix.scale(-1.0, 1.0, 1.0); + break; + } + return matrix; + } + + Matrix4 get _straightenMatrix => Matrix4.rotationZ(degToRadian((orientation.isFlipped ? -1 : 1) * straightenDegrees)); +} + +@immutable +class TransformEvent { + final TransformActivity activity; + + const TransformEvent({ + required this.activity, + }); +} diff --git a/lib/widgets/filter_grids/common/filter_tile.dart b/lib/widgets/filter_grids/common/filter_tile.dart index b9b1b64f4..fbb72546e 100644 --- a/lib/widgets/filter_grids/common/filter_tile.dart +++ b/lib/widgets/filter_grids/common/filter_tile.dart @@ -72,6 +72,7 @@ class _InteractiveFilterTileState extends State { String? _initialRouteName, _initialSearchQuery; Set? _initialFilters; - static const actionPickItems = 'pick_items'; - static const actionPickCollectionFilters = 'pick_collection_filters'; - static const actionScreenSaver = 'screen_saver'; - static const actionScreenSaverSettings = 'screen_saver_settings'; - static const actionSearch = 'search'; - static const actionSetWallpaper = 'set_wallpaper'; - static const actionView = 'view'; - static const actionWidgetOpen = 'widget_open'; - static const actionWidgetSettings = 'widget_settings'; - - static const intentDataKeyAction = 'action'; - static const intentDataKeyAllowMultiple = 'allowMultiple'; - static const intentDataKeyFilters = 'filters'; - static const intentDataKeyMimeType = 'mimeType'; - static const intentDataKeyPage = 'page'; - static const intentDataKeyQuery = 'query'; - static const intentDataKeySafeMode = 'safeMode'; - static const intentDataKeyUri = 'uri'; - static const intentDataKeyWidgetId = 'widgetId'; - static const allowedShortcutRoutes = [ CollectionPage.routeName, AlbumListPage.routeName, @@ -104,22 +86,27 @@ class _HomePageState extends State { var appMode = AppMode.main; final intentData = widget.intentData ?? await IntentService.getIntentData(); - final safeMode = intentData[intentDataKeySafeMode] ?? false; - final intentAction = intentData[intentDataKeyAction]; + final safeMode = intentData[IntentDataKeys.safeMode] ?? false; + final intentAction = intentData[IntentDataKeys.action]; _initialFilters = null; await androidFileUtils.init(); - if (!{actionScreenSaver, actionSetWallpaper}.contains(intentAction) && settings.isInstalledAppAccessAllowed) { + if (!{ + IntentActions.edit, + IntentActions.screenSaver, + IntentActions.setWallpaper, + }.contains(intentAction) && + settings.isInstalledAppAccessAllowed) { unawaited(appInventory.initAppNames()); } if (intentData.isNotEmpty) { await reportService.log('Intent data=$intentData'); switch (intentAction) { - case actionView: - case actionWidgetOpen: + case IntentActions.view: + case IntentActions.widgetOpen: String? uri, mimeType; - final widgetId = intentData[intentDataKeyWidgetId]; + final widgetId = intentData[IntentDataKeys.widgetId]; if (widgetId != null) { // widget settings may be modified in a different process after channel setup await settings.reload(); @@ -134,8 +121,8 @@ class _HomePageState extends State { } unawaited(WidgetService.update(widgetId)); } else { - uri = intentData[intentDataKeyUri]; - mimeType = intentData[intentDataKeyMimeType]; + uri = intentData[IntentDataKeys.uri]; + mimeType = intentData[IntentDataKeys.mimeType]; } if (uri != null) { _viewerEntry = await _initViewerEntry( @@ -146,41 +133,51 @@ class _HomePageState extends State { appMode = AppMode.view; } } - case actionPickItems: + case IntentActions.edit: + _viewerEntry = await _initViewerEntry( + uri: intentData[IntentDataKeys.uri], + mimeType: intentData[IntentDataKeys.mimeType], + ); + if (_viewerEntry != null) { + appMode = AppMode.edit; + } + case IntentActions.setWallpaper: + _viewerEntry = await _initViewerEntry( + uri: intentData[IntentDataKeys.uri], + mimeType: intentData[IntentDataKeys.mimeType], + ); + if (_viewerEntry != null) { + appMode = AppMode.setWallpaper; + } + case IntentActions.pickItems: // TODO TLAD apply pick mimetype(s) // some apps define multiple types, separated by a space (maybe other signs too, like `,` `;`?) - String? pickMimeTypes = intentData[intentDataKeyMimeType]; - final multiple = intentData[intentDataKeyAllowMultiple] ?? false; + String? pickMimeTypes = intentData[IntentDataKeys.mimeType]; + final multiple = intentData[IntentDataKeys.allowMultiple] ?? false; debugPrint('pick mimeType=$pickMimeTypes multiple=$multiple'); appMode = multiple ? AppMode.pickMultipleMediaExternal : AppMode.pickSingleMediaExternal; - case actionPickCollectionFilters: + case IntentActions.pickCollectionFilters: appMode = AppMode.pickCollectionFiltersExternal; - case actionScreenSaver: + case IntentActions.screenSaver: appMode = AppMode.screenSaver; _initialRouteName = ScreenSaverPage.routeName; - case actionScreenSaverSettings: + case IntentActions.screenSaverSettings: _initialRouteName = ScreenSaverSettingsPage.routeName; - case actionSearch: + case IntentActions.search: _initialRouteName = SearchPage.routeName; - _initialSearchQuery = intentData[intentDataKeyQuery]; - case actionSetWallpaper: - appMode = AppMode.setWallpaper; - _viewerEntry = await _initViewerEntry( - uri: intentData[intentDataKeyUri], - mimeType: intentData[intentDataKeyMimeType], - ); - case actionWidgetSettings: + _initialSearchQuery = intentData[IntentDataKeys.query]; + case IntentActions.widgetSettings: _initialRouteName = HomeWidgetSettingsPage.routeName; - _widgetId = intentData[intentDataKeyWidgetId] ?? 0; + _widgetId = intentData[IntentDataKeys.widgetId] ?? 0; default: // do not use 'route' as extra key, as the Flutter framework acts on it - final extraRoute = intentData[intentDataKeyPage]; + final extraRoute = intentData[IntentDataKeys.page]; if (allowedShortcutRoutes.contains(extraRoute)) { _initialRouteName = extraRoute; } } if (_initialFilters == null) { - final extraFilters = intentData[intentDataKeyFilters]; + final extraFilters = intentData[IntentDataKeys.filters]; _initialFilters = extraFilters != null ? (extraFilters as List).cast().map(CollectionFilter.fromJson).whereNotNull().toSet() : null; } } @@ -219,6 +216,7 @@ class _HomePageState extends State { } else { await _initViewerEssentials(); } + case AppMode.edit: case AppMode.setWallpaper: await _initViewerEssentials(); case AppMode.pickMediaInternal: @@ -258,75 +256,85 @@ class _HomePageState extends State { } Future _getRedirectRoute(AppMode appMode) async { - if (appMode == AppMode.setWallpaper) { - return DirectMaterialPageRoute( - settings: const RouteSettings(name: WallpaperPage.routeName), - builder: (_) { - return WallpaperPage( - entry: _viewerEntry, - ); - }, - ); - } - - if (appMode == AppMode.view) { - AvesEntry viewerEntry = _viewerEntry!; - CollectionLens? collection; - - final source = context.read(); - if (source.initState != SourceInitializationState.none) { - final album = viewerEntry.directory; - if (album != null) { - // wait for collection to pass the `loading` state - final completer = Completer(); - void _onSourceStateChanged() { - if (source.state != SourceState.loading) { - source.stateNotifier.removeListener(_onSourceStateChanged); - completer.complete(); - } - } - - source.stateNotifier.addListener(_onSourceStateChanged); - await completer.future; - - collection = CollectionLens( - source: source, - filters: {AlbumFilter(album, source.getAlbumDisplayName(context, album))}, - listenToSource: false, - // if we group bursts, opening a burst sub-entry should: - // - identify and select the containing main entry, - // - select the sub-entry in the Viewer page. - groupBursts: false, - ); - final viewerEntryPath = viewerEntry.path; - final collectionEntry = collection.sortedEntries.firstWhereOrNull((entry) => entry.path == viewerEntryPath); - if (collectionEntry != null) { - viewerEntry = collectionEntry; - } else { - debugPrint('collection does not contain viewerEntry=$viewerEntry'); - collection = null; - } - } - } - - return DirectMaterialPageRoute( - settings: const RouteSettings(name: EntryViewerPage.routeName), - builder: (_) { - return EntryViewerPage( - collection: collection, - initialEntry: viewerEntry, - ); - }, - ); - } - String routeName; Set? filters; switch (appMode) { case AppMode.pickSingleMediaExternal: case AppMode.pickMultipleMediaExternal: routeName = CollectionPage.routeName; - default: + case AppMode.setWallpaper: + return DirectMaterialPageRoute( + settings: const RouteSettings(name: WallpaperPage.routeName), + builder: (_) { + return WallpaperPage( + entry: _viewerEntry, + ); + }, + ); + case AppMode.view: + AvesEntry viewerEntry = _viewerEntry!; + CollectionLens? collection; + + final source = context.read(); + if (source.initState != SourceInitializationState.none) { + final album = viewerEntry.directory; + if (album != null) { + // wait for collection to pass the `loading` state + final completer = Completer(); + void _onSourceStateChanged() { + if (source.state != SourceState.loading) { + source.stateNotifier.removeListener(_onSourceStateChanged); + completer.complete(); + } + } + + source.stateNotifier.addListener(_onSourceStateChanged); + await completer.future; + + collection = CollectionLens( + source: source, + filters: {AlbumFilter(album, source.getAlbumDisplayName(context, album))}, + listenToSource: false, + // if we group bursts, opening a burst sub-entry should: + // - identify and select the containing main entry, + // - select the sub-entry in the Viewer page. + groupBursts: false, + ); + final viewerEntryPath = viewerEntry.path; + final collectionEntry = collection.sortedEntries.firstWhereOrNull((entry) => entry.path == viewerEntryPath); + if (collectionEntry != null) { + viewerEntry = collectionEntry; + } else { + debugPrint('collection does not contain viewerEntry=$viewerEntry'); + collection = null; + } + } + } + + return DirectMaterialPageRoute( + settings: const RouteSettings(name: EntryViewerPage.routeName), + builder: (_) { + return EntryViewerPage( + collection: collection, + initialEntry: viewerEntry, + ); + }, + ); + case AppMode.edit: + return DirectMaterialPageRoute( + settings: const RouteSettings(name: EntryViewerPage.routeName), + builder: (_) { + return ImageEditorPage( + entry: _viewerEntry!, + ); + }, + ); + case AppMode.main: + case AppMode.pickCollectionFiltersExternal: + case AppMode.pickMediaInternal: + case AppMode.pickFilterInternal: + case AppMode.screenSaver: + case AppMode.slideshow: routeName = _initialRouteName ?? settings.homePage.routeName; filters = _initialFilters ?? {}; } diff --git a/lib/widgets/home_widget.dart b/lib/widgets/home_widget.dart index 1e81d6e77..f01bce2ce 100644 --- a/lib/widgets/home_widget.dart +++ b/lib/widgets/home_widget.dart @@ -42,7 +42,7 @@ class HomeWidgetPainter { } final recorder = ui.PictureRecorder(); - final rect = Rect.fromLTWH(0, 0, widgetSizePx.width, widgetSizePx.height); + final rect = Offset.zero & widgetSizePx; final canvas = Canvas(recorder, rect); final path = shape.path(widgetSizePx, devicePixelRatio); canvas.clipPath(path); diff --git a/lib/widgets/intent.dart b/lib/widgets/intent.dart new file mode 100644 index 000000000..639cd5526 --- /dev/null +++ b/lib/widgets/intent.dart @@ -0,0 +1,24 @@ +class IntentActions { + static const edit = 'edit'; + static const pickItems = 'pick_items'; + static const pickCollectionFilters = 'pick_collection_filters'; + static const screenSaver = 'screen_saver'; + static const screenSaverSettings = 'screen_saver_settings'; + static const search = 'search'; + static const setWallpaper = 'set_wallpaper'; + static const view = 'view'; + static const widgetOpen = 'widget_open'; + static const widgetSettings = 'widget_settings'; +} + +class IntentDataKeys { + static const action = 'action'; + static const allowMultiple = 'allowMultiple'; + static const filters = 'filters'; + static const mimeType = 'mimeType'; + static const page = 'page'; + static const query = 'query'; + static const safeMode = 'safeMode'; + static const uri = 'uri'; + static const widgetId = 'widgetId'; +} diff --git a/lib/widgets/viewer/overlay/minimap.dart b/lib/widgets/viewer/overlay/minimap.dart index b3f5de899..59ca726f8 100644 --- a/lib/widgets/viewer/overlay/minimap.dart +++ b/lib/widgets/viewer/overlay/minimap.dart @@ -1,8 +1,12 @@ import 'dart:math'; -import 'package:aves/widgets/viewer/visual/state.dart'; +import 'package:aves/model/view_state.dart'; +import 'package:aves/widgets/editor/transform/controller.dart'; +import 'package:aves/widgets/editor/transform/transformation.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class Minimap extends StatelessWidget { final ValueNotifier viewStateNotifier; @@ -23,16 +27,22 @@ class Minimap extends StatelessWidget { final viewportSize = viewState.viewportSize; final contentSize = viewState.contentSize; if (viewportSize == null || contentSize == null) return const SizedBox(); - return CustomPaint( - painter: MinimapPainter( - viewportSize: viewportSize, - contentSize: contentSize, - viewCenterOffset: viewState.position, - viewScale: viewState.scale!, - minimapBorderColor: Colors.white30, - ), - size: minimapSize, - ); + return StreamBuilder( + stream: context.select>((v) => v?.transformationStream ?? Stream.value(null)), + builder: (context, snapshot) { + final transformation = snapshot.data; + return CustomPaint( + painter: MinimapPainter( + viewportSize: viewportSize, + contentSize: contentSize, + viewCenterOffset: viewState.position, + viewScale: viewState.scale!, + transformation: transformation, + minimapBorderColor: Colors.white30, + ), + size: minimapSize, + ); + }); }, ), ); @@ -43,16 +53,30 @@ class MinimapPainter extends CustomPainter { final Size contentSize, viewportSize; final Offset viewCenterOffset; final double viewScale; + final Transformation? transformation; final Color minimapBorderColor, viewportBorderColor; - const MinimapPainter({ + late final Paint fill, minimapStroke, viewportStroke; + + MinimapPainter({ required this.viewportSize, required this.contentSize, required this.viewCenterOffset, required this.viewScale, + this.transformation, this.minimapBorderColor = Colors.white, this.viewportBorderColor = Colors.white, - }); + }) { + fill = Paint() + ..style = PaintingStyle.fill + ..color = const Color(0x33000000); + minimapStroke = Paint() + ..style = PaintingStyle.stroke + ..color = minimapBorderColor; + viewportStroke = Paint() + ..style = PaintingStyle.stroke + ..color = viewportBorderColor; + } @override void paint(Canvas canvas, Size size) { @@ -64,37 +88,56 @@ class MinimapPainter extends CustomPainter { // hide minimap when image is in full view if (viewportSize + const Offset(precisionErrorTolerance, precisionErrorTolerance) >= viewSize) return; + final canvasCenter = size.center(Offset.zero); final canvasScale = size.longestSide / viewSize.longestSide; final scaledContentSize = viewSize * canvasScale; final scaledViewportSize = viewportSize * canvasScale; final contentRect = Rect.fromCenter( - center: size.center(Offset.zero), + center: canvasCenter, width: scaledContentSize.width, height: scaledContentSize.height, ); final viewportRect = Rect.fromCenter( - center: size.center(Offset.zero) - viewCenterOffset * canvasScale, + center: canvasCenter - viewCenterOffset * canvasScale, width: min(scaledContentSize.width, scaledViewportSize.width), height: min(scaledContentSize.height, scaledViewportSize.height), ); - canvas.translate((contentRect.width - size.width) / 2, (contentRect.height - size.height) / 2); + Matrix4? transformMatrix; + if (transformation != null) { + final viewportCenter = viewportRect.center; + final transformOrigin = viewportCenter; + transformMatrix = Matrix4.identity() + ..translate(transformOrigin.dx, transformOrigin.dy) + ..multiply(transformation!.matrix) + ..translate(-transformOrigin.dx, -transformOrigin.dy); + final transViewportCenter = transformMatrix.transformOffset(viewportCenter); + final transContentCenter = transformMatrix.transformOffset(contentRect.center); - final fill = Paint() - ..style = PaintingStyle.fill - ..color = const Color(0x33000000); - final minimapStroke = Paint() - ..style = PaintingStyle.stroke - ..color = minimapBorderColor; - final viewportStroke = Paint() - ..style = PaintingStyle.stroke - ..color = viewportBorderColor; + final minimapTranslation = size / 2 + (transViewportCenter - transContentCenter - viewportCenter); + canvas.translate(minimapTranslation.width, minimapTranslation.height); + } else { + canvas.translate((contentRect.width - size.width) / 2, (contentRect.height - size.height) / 2); + } canvas.drawRect(viewportRect, fill); + + if (transformMatrix != null) { + canvas.transform(transformMatrix.storage); + _drawContentRect(canvas, contentRect); + transformMatrix.invert(); + canvas.transform(transformMatrix.storage); + } else { + _drawContentRect(canvas, contentRect); + } + + canvas.drawRect(viewportRect, viewportStroke); + } + + void _drawContentRect(Canvas canvas, Rect contentRect) { canvas.drawRect(contentRect, fill); canvas.drawRect(contentRect, minimapStroke); - canvas.drawRect(viewportRect, viewportStroke); } @override diff --git a/lib/widgets/viewer/overlay/wallpaper_buttons.dart b/lib/widgets/viewer/overlay/wallpaper_buttons.dart index fdec17399..f7e70483a 100644 --- a/lib/widgets/viewer/overlay/wallpaper_buttons.dart +++ b/lib/widgets/viewer/overlay/wallpaper_buttons.dart @@ -103,7 +103,7 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin { final center = (contentSize / 2 - viewState.position / scale) as Size; final regionSize = viewportSize / scale; final regionTopLeft = (center - regionSize / 2) as Offset; - return Rect.fromLTWH(regionTopLeft.dx, regionTopLeft.dy, regionSize.width, regionSize.height); + return regionTopLeft & regionSize; } Future _getBytes(BuildContext context, Rect displayRegion) async { diff --git a/lib/widgets/viewer/visual/conductor.dart b/lib/widgets/viewer/visual/conductor.dart index 9f07652e2..26f6a3b96 100644 --- a/lib/widgets/viewer/visual/conductor.dart +++ b/lib/widgets/viewer/visual/conductor.dart @@ -1,5 +1,5 @@ import 'package:aves/model/entry/entry.dart'; -import 'package:aves/widgets/viewer/visual/state.dart'; +import 'package:aves/model/view_state.dart'; import 'package:aves_magnifier/aves_magnifier.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; @@ -35,7 +35,7 @@ class ViewStateConductor { maxScale: initialScale, initialScale: initialScale, viewportSize: _viewportSize, - childSize: entry.displaySize, + contentSize: entry.displaySize, ).initialScale, viewportSize: _viewportSize, contentSize: entry.displaySize, diff --git a/lib/widgets/viewer/visual/entry_page_view.dart b/lib/widgets/viewer/visual/entry_page_view.dart index fd1cfe61f..12b216852 100644 --- a/lib/widgets/viewer/visual/entry_page_view.dart +++ b/lib/widgets/viewer/visual/entry_page_view.dart @@ -18,7 +18,7 @@ import 'package:aves/widgets/viewer/video/conductor.dart'; import 'package:aves/widgets/viewer/visual/conductor.dart'; import 'package:aves/widgets/viewer/visual/error.dart'; import 'package:aves/widgets/viewer/visual/raster.dart'; -import 'package:aves/widgets/viewer/visual/state.dart'; +import 'package:aves/model/view_state.dart'; import 'package:aves/widgets/viewer/visual/vector.dart'; import 'package:aves/widgets/viewer/visual/video/cover.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/subtitle.dart'; @@ -37,6 +37,8 @@ class EntryPageView extends StatefulWidget { final VoidCallback? onDisposed; static const decorationCheckSize = 20.0; + static const rasterMaxScale = ScaleLevel(factor: 5); + static const vectorMaxScale = ScaleLevel(factor: 25); const EntryPageView({ super.key, @@ -63,9 +65,6 @@ class _EntryPageViewState extends State with SingleTickerProvider ViewerController get viewerController => widget.viewerController; - static const rasterMaxScale = ScaleLevel(factor: 5); - static const vectorMaxScale = ScaleLevel(factor: 25); - @override void initState() { super.initState(); @@ -180,7 +179,7 @@ class _EntryPageViewState extends State with SingleTickerProvider Widget _buildSvgView() { return _buildMagnifier( - maxScale: vectorMaxScale, + maxScale: EntryPageView.vectorMaxScale, scaleStateCycle: _vectorScaleStateCycle, applyScale: false, child: VectorImageView( @@ -382,7 +381,7 @@ class _EntryPageViewState extends State with SingleTickerProvider Widget _buildMagnifier({ AvesMagnifierController? controller, Size? displaySize, - ScaleLevel maxScale = rasterMaxScale, + ScaleLevel maxScale = EntryPageView.rasterMaxScale, ScaleStateCycle scaleStateCycle = defaultScaleStateCycle, bool applyScale = true, MagnifierGestureScaleStartCallback? onScaleStart, @@ -398,7 +397,7 @@ class _EntryPageViewState extends State with SingleTickerProvider // key includes modified date to refresh when the image is modified by metadata (e.g. rotated) key: Key('${entry.uri}_${entry.pageId}_${entry.dateModifiedSecs}'), controller: controller ?? _magnifierController, - childSize: displaySize ?? entry.displaySize, + contentSize: displaySize ?? entry.displaySize, allowOriginalScaleBeyondRange: !isWallpaperMode, minScale: minScale, maxScale: maxScale, @@ -477,7 +476,7 @@ class _EntryPageViewState extends State with SingleTickerProvider void _onViewScaleBoundariesChanged(ScaleBoundaries v) { _viewStateNotifier.value = _viewStateNotifier.value.copyWith( viewportSize: v.viewportSize, - contentSize: v.childSize, + contentSize: v.contentSize, ); } diff --git a/lib/widgets/viewer/visual/raster.dart b/lib/widgets/viewer/visual/raster.dart index 40704ae49..0386b9128 100644 --- a/lib/widgets/viewer/visual/raster.dart +++ b/lib/widgets/viewer/visual/raster.dart @@ -8,7 +8,7 @@ import 'package:aves/model/settings/enums/entry_background.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/widgets/common/fx/checkered_decoration.dart'; import 'package:aves/widgets/viewer/visual/entry_page_view.dart'; -import 'package:aves/widgets/viewer/visual/state.dart'; +import 'package:aves/model/view_state.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; diff --git a/lib/widgets/viewer/visual/vector.dart b/lib/widgets/viewer/visual/vector.dart index 19503373b..c1502a7d9 100644 --- a/lib/widgets/viewer/visual/vector.dart +++ b/lib/widgets/viewer/visual/vector.dart @@ -8,7 +8,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/utils/math_utils.dart'; import 'package:aves/widgets/common/fx/checkered_decoration.dart'; import 'package:aves/widgets/viewer/visual/entry_page_view.dart'; -import 'package:aves/widgets/viewer/visual/state.dart'; +import 'package:aves/model/view_state.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; diff --git a/lib/widgets/viewer/visual/video/cover.dart b/lib/widgets/viewer/visual/video/cover.dart index d3438159d..5017a4a3f 100644 --- a/lib/widgets/viewer/visual/video/cover.dart +++ b/lib/widgets/viewer/visual/video/cover.dart @@ -115,7 +115,7 @@ class _VideoCoverState extends State { if (boundaries != null) { magnifierController.setScaleBoundaries( boundaries.copyWith( - childSize: videoDisplaySize, + contentSize: videoDisplaySize, ), ); } diff --git a/lib/widgets/viewer/visual/video/subtitle/subtitle.dart b/lib/widgets/viewer/visual/video/subtitle/subtitle.dart index bbf86b845..131012944 100644 --- a/lib/widgets/viewer/visual/video/subtitle/subtitle.dart +++ b/lib/widgets/viewer/visual/video/subtitle/subtitle.dart @@ -2,9 +2,9 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/settings/enums/subtitle_position.dart'; import 'package:aves/model/settings/settings.dart'; +import 'package:aves/model/view_state.dart'; import 'package:aves/widgets/common/basic/text/background_painter.dart'; import 'package:aves/widgets/common/basic/text/outlined.dart'; -import 'package:aves/widgets/viewer/visual/state.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/ass_parser.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/span.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/style.dart'; diff --git a/plugins/aves_magnifier/lib/aves_magnifier.dart b/plugins/aves_magnifier/lib/aves_magnifier.dart index dae50972d..7a387be0a 100644 --- a/plugins/aves_magnifier/lib/aves_magnifier.dart +++ b/plugins/aves_magnifier/lib/aves_magnifier.dart @@ -2,8 +2,8 @@ library aves_magnifier; export 'src/controller/controller.dart'; export 'src/controller/state.dart'; +export 'src/core/core.dart'; export 'src/core/scale_gesture_recognizer.dart'; -export 'src/magnifier.dart'; export 'src/pan/gesture_detector_scope.dart'; export 'src/pan/scroll_physics.dart'; export 'src/scale/scale_boundaries.dart'; diff --git a/plugins/aves_magnifier/lib/src/controller/controller.dart b/plugins/aves_magnifier/lib/src/controller/controller.dart index 89858643f..e57d35c10 100644 --- a/plugins/aves_magnifier/lib/src/controller/controller.dart +++ b/plugins/aves_magnifier/lib/src/controller/controller.dart @@ -116,17 +116,15 @@ class AvesMagnifierController { final boundaries = scaleBoundaries; if (boundaries == null) return null; - double _clamp(double scale) => scale.clamp(boundaries.minScale, boundaries.maxScale); - switch (scaleState) { case ScaleState.initial: case ScaleState.zoomedIn: case ScaleState.zoomedOut: - return _clamp(boundaries.initialScale); + return boundaries.clampScale(boundaries.initialScale); case ScaleState.covering: - return _clamp(ScaleLevel.scaleForCovering(boundaries.viewportSize, boundaries.childSize)); + return boundaries.clampScale(ScaleLevel.scaleForCovering(boundaries.viewportSize, boundaries.contentSize)); case ScaleState.originalSize: - return _clamp(boundaries.originalScale); + return boundaries.clampScale(boundaries.originalScale); default: return null; } diff --git a/plugins/aves_magnifier/lib/src/controller/controller_delegate.dart b/plugins/aves_magnifier/lib/src/controller/controller_delegate.dart index 21b373790..26955113c 100644 --- a/plugins/aves_magnifier/lib/src/controller/controller_delegate.dart +++ b/plugins/aves_magnifier/lib/src/controller/controller_delegate.dart @@ -10,14 +10,14 @@ import 'package:flutter/widgets.dart'; /// A class to hold internal layout logic to sync both controller states /// /// It reacts to layout changes (eg: enter landscape or widget resize) and syncs the two controllers. -mixin AvesMagnifierControllerDelegate on State { +mixin AvesMagnifierControllerDelegate on State { AvesMagnifierController get controller => widget.controller; ScaleBoundaries? get scaleBoundaries => controller.scaleBoundaries; ScaleStateCycle get scaleStateCycle => widget.scaleStateCycle; - Alignment get basePosition => Alignment.center; + Alignment get basePosition => ScaleBoundaries.basePosition; Function(double? prevScale, double? nextScale, Offset nextPosition)? _animateScale; @@ -26,12 +26,12 @@ mixin AvesMagnifierControllerDelegate on State { final List _subscriptions = []; - void registerDelegate(MagnifierCore widget) { + void registerDelegate(AvesMagnifier widget) { _subscriptions.add(widget.controller.stateStream.listen(_onMagnifierStateChange)); _subscriptions.add(widget.controller.scaleStateChangeStream.listen(_onScaleStateChange)); } - void unregisterDelegate(MagnifierCore oldWidget) { + void unregisterDelegate(AvesMagnifier oldWidget) { _animateScale = null; _subscriptions ..forEach((sub) => sub.cancel()) @@ -54,7 +54,7 @@ mixin AvesMagnifierControllerDelegate on State { final childFocalPoint = scaleStateChange.childFocalPoint; final boundaries = scaleBoundaries; if (childFocalPoint != null && boundaries != null) { - nextPosition = boundaries.childToStatePosition(nextScale!, childFocalPoint); + nextPosition = boundaries.contentToStatePosition(nextScale!, childFocalPoint); } } @@ -70,7 +70,7 @@ mixin AvesMagnifierControllerDelegate on State { final boundaries = scaleBoundaries; if (boundaries == null) return; - controller.update(position: clampPosition(), source: state.source); + controller.update(position: boundaries.clampPosition(position: position, scale: scale!), source: state.source); if (controller.scale == controller.previousState.scale) return; if (state.source == ChangeSource.internal || state.source == ChangeSource.animation) return; @@ -100,14 +100,6 @@ mixin AvesMagnifierControllerDelegate on State { void setScale(double? scale, ChangeSource source) => controller.update(scale: scale, source: source); - void updateMultiple({ - required Offset position, - required double scale, - required ChangeSource source, - }) { - controller.update(position: position, scale: scale, source: source); - } - void updateScaleStateFromNewScale(double newScale, ChangeSource source) { final boundaries = scaleBoundaries; if (boundaries == null) return; @@ -142,74 +134,4 @@ mixin AvesMagnifierControllerDelegate on State { if (originalScale == nextScale) return; controller.setScaleState(nextScaleState, source, childFocalPoint: childFocalPoint); } - - EdgeRange getXEdges({double? scale}) { - final boundaries = scaleBoundaries; - if (boundaries == null) return const EdgeRange(0, 0); - - final _scale = scale ?? this.scale!; - - final computedWidth = boundaries.childSize.width * _scale; - final screenWidth = boundaries.viewportSize.width; - - final positionX = basePosition.x; - final widthDiff = computedWidth - screenWidth; - - final minX = ((positionX - 1).abs() / 2) * widthDiff * -1; - final maxX = ((positionX + 1).abs() / 2) * widthDiff; - return EdgeRange(minX, maxX); - } - - EdgeRange getYEdges({double? scale}) { - final boundaries = scaleBoundaries; - if (boundaries == null) return const EdgeRange(0, 0); - - final _scale = scale ?? this.scale!; - - final computedHeight = boundaries.childSize.height * _scale; - final screenHeight = boundaries.viewportSize.height; - - final positionY = basePosition.y; - final heightDiff = computedHeight - screenHeight; - - final minY = ((positionY - 1).abs() / 2) * heightDiff * -1; - final maxY = ((positionY + 1).abs() / 2) * heightDiff; - return EdgeRange(minY, maxY); - } - - Offset clampPosition({Offset? position, double? scale}) { - final boundaries = scaleBoundaries; - if (boundaries == null) return Offset.zero; - - final _scale = scale ?? this.scale!; - final _position = position ?? this.position; - - final computedWidth = boundaries.childSize.width * _scale; - final computedHeight = boundaries.childSize.height * _scale; - - final screenWidth = boundaries.viewportSize.width; - final screenHeight = boundaries.viewportSize.height; - - var finalX = 0.0; - if (screenWidth < computedWidth) { - final range = getXEdges(scale: _scale); - finalX = _position.dx.clamp(range.min, range.max); - } - - var finalY = 0.0; - if (screenHeight < computedHeight) { - final range = getYEdges(scale: _scale); - finalY = _position.dy.clamp(range.min, range.max); - } - - return Offset(finalX, finalY); - } -} - -/// Simple class to store a min and a max value -class EdgeRange { - const EdgeRange(this.min, this.max); - - final double min; - final double max; } diff --git a/plugins/aves_magnifier/lib/src/controller/range.dart b/plugins/aves_magnifier/lib/src/controller/range.dart new file mode 100644 index 000000000..116ceef0d --- /dev/null +++ b/plugins/aves_magnifier/lib/src/controller/range.dart @@ -0,0 +1,15 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart'; + +@immutable +class EdgeRange extends Equatable { + final double min; + final double max; + + @override + List get props => [min, max]; + + const EdgeRange(this.min, this.max); + + static const EdgeRange zero = EdgeRange(0, 0); +} diff --git a/plugins/aves_magnifier/lib/src/core/core.dart b/plugins/aves_magnifier/lib/src/core/core.dart index d2f95bad9..53cb4da9a 100644 --- a/plugins/aves_magnifier/lib/src/core/core.dart +++ b/plugins/aves_magnifier/lib/src/core/core.dart @@ -4,22 +4,52 @@ import 'package:aves_magnifier/src/controller/controller.dart'; import 'package:aves_magnifier/src/controller/controller_delegate.dart'; import 'package:aves_magnifier/src/controller/state.dart'; import 'package:aves_magnifier/src/core/gesture_detector.dart'; -import 'package:aves_magnifier/src/magnifier.dart'; import 'package:aves_magnifier/src/pan/edge_hit_detector.dart'; import 'package:aves_magnifier/src/scale/scale_boundaries.dart'; +import 'package:aves_magnifier/src/scale/scale_level.dart'; import 'package:aves_magnifier/src/scale/state.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; import 'package:tuple/tuple.dart'; -/// Internal widget in which controls all animations lifecycle, core responses -/// to user gestures, updates to the controller state and mounts the entire Layout -class MagnifierCore extends StatefulWidget { +/* + adapted from package `photo_view` v0.9.2: + - removed image related aspects to focus on a general purpose pan/scale viewer (à la `InteractiveViewer`) + - removed rotation and many customization parameters + - removed ignorable/ignoring partial notifiers + - formatted, renamed and reorganized + - fixed gesture recognizers when used inside a scrollable widget like `PageView` + - fixed corner hit detection when in containers scrollable in both axes + - fixed corner hit detection issues due to imprecise double comparisons + - added single & double tap position feedback + - fixed focus when scaling by double-tap/pinch + */ +class AvesMagnifier extends StatefulWidget { + static const double defaultPanInertia = .2; + final AvesMagnifierController controller; + final EdgeInsets viewportPadding; + + // The size of the custom [child]. This value is used to compute the relation between the child and the container's size to calculate the scale value. + final Size contentSize; + + final bool allowOriginalScaleBeyondRange; + final bool allowGestureScaleBeyondRange; + final double panInertia; + + // Defines the minimum size in which the image will be allowed to assume, it is proportional to the original image size. + final ScaleLevel minScale; + + // Defines the maximum size in which the image will be allowed to assume, it is proportional to the original image size. + final ScaleLevel maxScale; + + // Defines the size the image will assume when the component is initialized, it is proportional to the original image size. + final ScaleLevel initialScale; + final ScaleStateCycle scaleStateCycle; final bool applyScale; - final double panInertia; final MagnifierGestureScaleStartCallback? onScaleStart; final MagnifierGestureScaleUpdateCallback? onScaleUpdate; final MagnifierGestureScaleEndCallback? onScaleEnd; @@ -28,12 +58,19 @@ class MagnifierCore extends StatefulWidget { final MagnifierDoubleTapCallback? onDoubleTap; final Widget child; - const MagnifierCore({ + const AvesMagnifier({ super.key, required this.controller, - required this.scaleStateCycle, - required this.applyScale, - this.panInertia = .2, + required this.contentSize, + this.viewportPadding = EdgeInsets.zero, + this.allowOriginalScaleBeyondRange = true, + this.allowGestureScaleBeyondRange = true, + this.minScale = const ScaleLevel(factor: .0), + this.maxScale = const ScaleLevel(factor: double.infinity), + this.initialScale = const ScaleLevel(ref: ScaleReference.contained), + this.scaleStateCycle = defaultScaleStateCycle, + this.applyScale = true, + this.panInertia = defaultPanInertia, this.onScaleStart, this.onScaleUpdate, this.onScaleEnd, @@ -44,10 +81,10 @@ class MagnifierCore extends StatefulWidget { }); @override - State createState() => _MagnifierCoreState(); + State createState() => _AvesMagnifierState(); } -class _MagnifierCoreState extends State with TickerProviderStateMixin, AvesMagnifierControllerDelegate, EdgeHitDetector { +class _AvesMagnifierState extends State with TickerProviderStateMixin, AvesMagnifierControllerDelegate, EdgeHitDetector { Offset? _startFocalPoint, _lastViewportFocalPosition; double? _startScale, _quickScaleLastY, _quickScaleLastDistance; late bool _dropped, _doubleTap, _quickScaleMoved; @@ -77,13 +114,23 @@ class _MagnifierCoreState extends State with TickerProviderStateM } @override - void didUpdateWidget(covariant MagnifierCore oldWidget) { + void didUpdateWidget(covariant AvesMagnifier oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.controller != widget.controller) { _unregisterWidget(oldWidget); _registerWidget(widget); } + + if (oldWidget.allowOriginalScaleBeyondRange != widget.allowOriginalScaleBeyondRange || oldWidget.minScale != widget.minScale || oldWidget.maxScale != widget.maxScale || oldWidget.initialScale != widget.initialScale || oldWidget.contentSize != widget.contentSize) { + controller.setScaleBoundaries((controller.scaleBoundaries ?? ScaleBoundaries.zero).copyWith( + allowOriginalScaleBeyondRange: widget.allowOriginalScaleBeyondRange, + minScale: widget.minScale, + maxScale: widget.maxScale, + initialScale: widget.initialScale, + contentSize: widget.contentSize.isEmpty == false ? widget.contentSize : null, + )); + } } @override @@ -94,13 +141,13 @@ class _MagnifierCoreState extends State with TickerProviderStateM super.dispose(); } - void _registerWidget(MagnifierCore widget) { + void _registerWidget(AvesMagnifier widget) { registerDelegate(widget); cachedScaleBoundaries = widget.controller.scaleBoundaries; setScaleStateUpdateAnimation(animateOnScaleStateUpdate); } - void _unregisterWidget(MagnifierCore oldWidget) { + void _unregisterWidget(AvesMagnifier oldWidget) { unregisterDelegate(oldWidget); cachedScaleBoundaries = null; } @@ -170,18 +217,21 @@ class _MagnifierCoreState extends State with TickerProviderStateM } else { newScale = _startScale! * details.scale; } + if (!widget.allowGestureScaleBeyondRange) { + newScale = boundaries.clampScale(newScale); + } + newScale = max(0, newScale); final scaleFocalPoint = _doubleTap ? _startFocalPoint! : details.localFocalPoint; final panPositionDelta = scaleFocalPoint - _lastViewportFocalPosition!; final scalePositionDelta = boundaries.viewportToStatePosition(controller, scaleFocalPoint) * (scale! / newScale - 1); - final newPosition = position + panPositionDelta + scalePositionDelta; + final newPosition = boundaries.clampPosition( + position: position + panPositionDelta + scalePositionDelta, + scale: newScale, + ); updateScaleStateFromNewScale(newScale, ChangeSource.gesture); - updateMultiple( - scale: max(0, newScale), - position: newPosition, - source: ChangeSource.gesture, - ); + controller.update(position: newPosition, scale: newScale, source: ChangeSource.gesture); _lastViewportFocalPosition = scaleFocalPoint; } @@ -219,32 +269,40 @@ class _MagnifierCoreState extends State with TickerProviderStateM } } - final _position = controller.position; - final _scale = controller.scale!; - final maxScale = boundaries.maxScale; - final minScale = boundaries.minScale; + final currentPosition = controller.position; + final currentScale = controller.scale!; // animate back to min/max scale if gesture yielded a scale exceeding them - if (_scale > maxScale || _scale < minScale) { - final newScale = _scale.clamp(minScale, maxScale); - final newPosition = clampPosition(position: _position * newScale / _scale, scale: newScale); - animateScale(_scale, newScale); - animatePosition(_position, newPosition); + final newScale = boundaries.clampScale(currentScale); + if (currentScale != newScale) { + final newPosition = boundaries.clampPosition( + position: currentPosition * newScale / currentScale, + scale: newScale, + ); + animateScale(currentScale, newScale); + animatePosition(currentPosition, newPosition); return; } // The gesture recognizer triggers a new `onScaleStart` every time a pointer/finger is added or removed. // Following a pinch-to-zoom gesture, a new panning gesture may start if the user does not lift both fingers at the same time, // so we dismiss such panning gestures when it looks like it followed a scaling gesture. - final isPanning = _scale == _startScale && (DateTime.now().difference(_lastScaleGestureDate)).inMilliseconds > 100; + final isPanning = currentScale == _startScale && (DateTime.now().difference(_lastScaleGestureDate)).inMilliseconds > 100; // animate position only when panning without scaling if (isPanning) { - final pps = details.velocity.pixelsPerSecond; + var pps = details.velocity.pixelsPerSecond; if (pps != Offset.zero) { - final newPosition = clampPosition(position: _position + pps * widget.panInertia); - if (_position != newPosition) { - final tween = Tween(begin: _position, end: newPosition); + final externalTransform = boundaries.externalTransform; + if (externalTransform != null) { + pps = Matrix4.inverted(externalTransform).transformOffset(pps); + } + final newPosition = boundaries.clampPosition( + position: currentPosition + pps * widget.panInertia, + scale: currentScale, + ); + if (currentPosition != newPosition) { + final tween = Tween(begin: currentPosition, end: newPosition); const curve = Curves.easeOutCubic; _positionAnimation = tween.animate(CurvedAnimation(parent: _positionAnimationController, curve: curve)); _positionAnimationController @@ -254,7 +312,7 @@ class _MagnifierCoreState extends State with TickerProviderStateM } } - if (_scale != _startScale) { + if (currentScale != _startScale) { _lastScaleGestureDate = DateTime.now(); } } @@ -307,7 +365,7 @@ class _MagnifierCoreState extends State with TickerProviderStateM final viewportTapPosition = details.localPosition; final viewportSize = boundaries.viewportSize; final alignment = Alignment(viewportTapPosition.dx / viewportSize.width, viewportTapPosition.dy / viewportSize.height); - final childTapPosition = boundaries.viewportToChildPosition(controller, viewportTapPosition); + final childTapPosition = boundaries.viewportToContentPosition(controller, viewportTapPosition); onTap(context, controller.currentState, alignment, childTapPosition); } @@ -324,7 +382,7 @@ class _MagnifierCoreState extends State with TickerProviderStateM if (onDoubleTap(alignment) == true) return; } - final childTapPosition = boundaries.viewportToChildPosition(controller, viewportTapPosition); + final childTapPosition = boundaries.viewportToContentPosition(controller, viewportTapPosition); nextScaleState(ChangeSource.gesture, childFocalPoint: childTapPosition); } @@ -375,8 +433,7 @@ class _MagnifierCoreState extends State with TickerProviderStateM stream: controller.stateStream, initialData: controller.previousState, builder: (context, snapshot) { - final boundaries = scaleBoundaries; - if (!snapshot.hasData || boundaries == null) return const SizedBox(); + if (!snapshot.hasData) return const SizedBox(); final magnifierState = snapshot.data!; final position = magnifierState.position; @@ -384,17 +441,19 @@ class _MagnifierCoreState extends State with TickerProviderStateM Widget child = CustomSingleChildLayout( delegate: _CenterWithOriginalSizeDelegate( - boundaries.childSize, + widget.contentSize, basePosition, applyScale, ), child: widget.child, ); + // `Matrix4.scale` uses dynamic typing and can throw `UnimplementedError` on wrong types + final double effectiveScale = (applyScale ? scale : null) ?? 1.0; child = Transform( transform: Matrix4.identity() ..translate(position.dx, position.dy) - ..scale(applyScale ? scale : 1.0), + ..scale(effectiveScale), alignment: basePosition, child: child, ); @@ -406,7 +465,20 @@ class _MagnifierCoreState extends State with TickerProviderStateM onScaleEnd: onScaleEnd, onTapUp: widget.onTap == null ? null : onTap, onDoubleTap: onDoubleTap, - child: child, + child: Padding( + padding: widget.viewportPadding, + child: LayoutBuilder(builder: (context, constraints) { + controller.setScaleBoundaries((controller.scaleBoundaries ?? ScaleBoundaries.zero).copyWith( + allowOriginalScaleBeyondRange: widget.allowOriginalScaleBeyondRange, + minScale: widget.minScale, + maxScale: widget.maxScale, + initialScale: widget.initialScale, + viewportSize: constraints.biggest, + contentSize: widget.contentSize.isEmpty == false ? widget.contentSize : constraints.biggest, + )); + return child; + }), + ), ); }, ); @@ -451,3 +523,15 @@ class _CenterWithOriginalSizeDelegate extends SingleChildLayoutDelegate with Equ return oldDelegate != this; } } + +typedef MagnifierTapCallback = Function( + BuildContext context, + MagnifierState state, + Alignment alignment, + Offset childTapPosition, +); +typedef MagnifierDoubleTapCallback = bool Function(Alignment alignment); +typedef MagnifierGestureScaleStartCallback = void Function(ScaleStartDetails details, bool doubleTap, ScaleBoundaries boundaries); +typedef MagnifierGestureScaleUpdateCallback = bool Function(ScaleUpdateDetails details); +typedef MagnifierGestureScaleEndCallback = void Function(ScaleEndDetails details); +typedef MagnifierGestureFlingCallback = void Function(AxisDirection direction); diff --git a/plugins/aves_magnifier/lib/src/core/gesture_detector.dart b/plugins/aves_magnifier/lib/src/core/gesture_detector.dart index f28710d4b..eac8c8e18 100644 --- a/plugins/aves_magnifier/lib/src/core/gesture_detector.dart +++ b/plugins/aves_magnifier/lib/src/core/gesture_detector.dart @@ -58,12 +58,12 @@ class _MagnifierGestureDetectorState extends State { gestures[MagnifierGestureRecognizer] = GestureRecognizerFactoryWithHandlers( () => MagnifierGestureRecognizer( debugOwner: this, - hitDetector: widget.hitDetector, scope: scope, doubleTapDetails: doubleTapDetails, ), (instance) { instance + ..hitDetector = widget.hitDetector ..onStart = widget.onScaleStart != null ? (details) => widget.onScaleStart!(details, doubleTapDetails.value != null) : null ..onUpdate = widget.onScaleUpdate ..onEnd = widget.onScaleEnd diff --git a/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart b/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart index 9aa5ebca1..8fc3186da 100644 --- a/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart +++ b/plugins/aves_magnifier/lib/src/core/scale_gesture_recognizer.dart @@ -6,13 +6,13 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; class MagnifierGestureRecognizer extends ScaleGestureRecognizer { - final EdgeHitDetector hitDetector; final MagnifierGestureDetectorScope scope; final ValueNotifier doubleTapDetails; + EdgeHitDetector? hitDetector; + MagnifierGestureRecognizer({ super.debugOwner, - required this.hitDetector, required this.scope, required this.doubleTapDetails, }); @@ -135,9 +135,9 @@ class MagnifierGestureRecognizer extends ScaleGestureRecognizer { return false; } - bool _canPanX() => hitDetector.shouldMoveX(move, scope.escapeByFling) && isXPan(move); + bool _canPanX() => hitDetector != null && hitDetector!.shouldMoveX(move, scope.escapeByFling) && isXPan(move); - bool _canPanY() => hitDetector.shouldMoveY(move, scope.escapeByFling) && isYPan(move); + bool _canPanY() => hitDetector != null && hitDetector!.shouldMoveY(move, scope.escapeByFling) && isYPan(move); bool _isOverSlop(PointerDeviceKind kind) { final spanDelta = (_currentSpan! - _initialSpan!).abs(); diff --git a/plugins/aves_magnifier/lib/src/magnifier.dart b/plugins/aves_magnifier/lib/src/magnifier.dart deleted file mode 100644 index 38f5e1d02..000000000 --- a/plugins/aves_magnifier/lib/src/magnifier.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'package:aves_magnifier/src/controller/controller.dart'; -import 'package:aves_magnifier/src/controller/state.dart'; -import 'package:aves_magnifier/src/core/core.dart'; -import 'package:aves_magnifier/src/scale/scale_boundaries.dart'; -import 'package:aves_magnifier/src/scale/scale_level.dart'; -import 'package:aves_magnifier/src/scale/state.dart'; -import 'package:flutter/material.dart'; - -/* - adapted from package `photo_view` v0.9.2: - - removed image related aspects to focus on a general purpose pan/scale viewer (à la `InteractiveViewer`) - - removed rotation and many customization parameters - - removed ignorable/ignoring partial notifiers - - formatted, renamed and reorganized - - fixed gesture recognizers when used inside a scrollable widget like `PageView` - - fixed corner hit detection when in containers scrollable in both axes - - fixed corner hit detection issues due to imprecise double comparisons - - added single & double tap position feedback - - fixed focus when scaling by double-tap/pinch - */ -class AvesMagnifier extends StatelessWidget { - const AvesMagnifier({ - super.key, - required this.controller, - required this.childSize, - this.allowOriginalScaleBeyondRange = true, - this.minScale = const ScaleLevel(factor: .0), - this.maxScale = const ScaleLevel(factor: double.infinity), - this.initialScale = const ScaleLevel(ref: ScaleReference.contained), - this.scaleStateCycle = defaultScaleStateCycle, - this.applyScale = true, - this.onScaleStart, - this.onScaleUpdate, - this.onScaleEnd, - this.onFling, - this.onTap, - this.onDoubleTap, - required this.child, - }); - - final AvesMagnifierController controller; - - // The size of the custom [child]. This value is used to compute the relation between the child and the container's size to calculate the scale value. - final Size childSize; - - final bool allowOriginalScaleBeyondRange; - - // Defines the minimum size in which the image will be allowed to assume, it is proportional to the original image size. - final ScaleLevel minScale; - - // Defines the maximum size in which the image will be allowed to assume, it is proportional to the original image size. - final ScaleLevel maxScale; - - // Defines the size the image will assume when the component is initialized, it is proportional to the original image size. - final ScaleLevel initialScale; - - final ScaleStateCycle scaleStateCycle; - final bool applyScale; - final MagnifierGestureScaleStartCallback? onScaleStart; - final MagnifierGestureScaleUpdateCallback? onScaleUpdate; - final MagnifierGestureScaleEndCallback? onScaleEnd; - final MagnifierGestureFlingCallback? onFling; - final MagnifierTapCallback? onTap; - final MagnifierDoubleTapCallback? onDoubleTap; - final Widget child; - - @override - Widget build(BuildContext context) { - return LayoutBuilder( - builder: (context, constraints) { - controller.setScaleBoundaries(ScaleBoundaries( - allowOriginalScaleBeyondRange: allowOriginalScaleBeyondRange, - minScale: minScale, - maxScale: maxScale, - initialScale: initialScale, - viewportSize: constraints.biggest, - childSize: childSize.isEmpty == false ? childSize : constraints.biggest, - )); - - return MagnifierCore( - controller: controller, - scaleStateCycle: scaleStateCycle, - applyScale: applyScale, - onScaleStart: onScaleStart, - onScaleUpdate: onScaleUpdate, - onScaleEnd: onScaleEnd, - onFling: onFling, - onTap: onTap, - onDoubleTap: onDoubleTap, - child: child, - ); - }, - ); - } -} - -typedef MagnifierTapCallback = Function( - BuildContext context, - MagnifierState state, - Alignment alignment, - Offset childTapPosition, -); -typedef MagnifierDoubleTapCallback = bool Function(Alignment alignment); -typedef MagnifierGestureScaleStartCallback = void Function(ScaleStartDetails details, bool doubleTap, ScaleBoundaries boundaries); -typedef MagnifierGestureScaleUpdateCallback = bool Function(ScaleUpdateDetails details); -typedef MagnifierGestureScaleEndCallback = void Function(ScaleEndDetails details); -typedef MagnifierGestureFlingCallback = void Function(AxisDirection direction); diff --git a/plugins/aves_magnifier/lib/src/pan/edge_hit_detector.dart b/plugins/aves_magnifier/lib/src/pan/edge_hit_detector.dart index 551c7c0a9..418e7d790 100644 --- a/plugins/aves_magnifier/lib/src/pan/edge_hit_detector.dart +++ b/plugins/aves_magnifier/lib/src/pan/edge_hit_detector.dart @@ -1,38 +1,41 @@ import 'package:aves_magnifier/src/controller/controller_delegate.dart'; +import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; mixin EdgeHitDetector on AvesMagnifierControllerDelegate { - // the child width/height is not accurate for some image size & scale combos + // the content width/height is not accurate for some image size & scale combos // e.g. 3580.0 * 0.1005586592178771 yields 360.0 // but 4764.0 * 0.07556675062972293 yields 360.00000000000006 // so be sure to compare with `precisionErrorTolerance` EdgeHit getXEdgeHit() { - final boundaries = scaleBoundaries; - if (boundaries == null) return const EdgeHit(false, false); + final _boundaries = scaleBoundaries; + final _scale = scale; + if (_boundaries == null || _scale == null) return const EdgeHit(false, false); - final childWidth = boundaries.childSize.width * scale!; - final viewportWidth = boundaries.viewportSize.width; - if (viewportWidth + precisionErrorTolerance >= childWidth) { + final contentWidth = _boundaries.contentSize.width * _scale; + final viewportWidth = _boundaries.viewportSize.width; + if (viewportWidth + precisionErrorTolerance >= contentWidth) { return const EdgeHit(true, true); } final x = -position.dx; - final range = getXEdges(); + final range = _boundaries.getXEdges(scale: _scale); return EdgeHit(x <= range.min, x >= range.max); } EdgeHit getYEdgeHit() { - final boundaries = scaleBoundaries; - if (boundaries == null) return const EdgeHit(false, false); + final _boundaries = scaleBoundaries; + final _scale = scale; + if (_boundaries == null || _scale == null) return const EdgeHit(false, false); - final childHeight = boundaries.childSize.height * scale!; - final viewportHeight = boundaries.viewportSize.height; - if (viewportHeight + precisionErrorTolerance >= childHeight) { + final contentHeight = _boundaries.contentSize.height * _scale; + final viewportHeight = _boundaries.viewportSize.height; + if (viewportHeight + precisionErrorTolerance >= contentHeight) { return const EdgeHit(true, true); } final y = -position.dy; - final range = getYEdges(); + final range = _boundaries.getYEdges(scale: _scale); return EdgeHit(y <= range.min, y >= range.max); } @@ -56,12 +59,16 @@ mixin EdgeHitDetector on AvesMagnifierControllerDelegate { } } -class EdgeHit { - const EdgeHit(this.hasHitMin, this.hasHitMax); - +@immutable +class EdgeHit extends Equatable { final bool hasHitMin; final bool hasHitMax; + @override + List get props => [hasHitMin, hasHitMax]; + + const EdgeHit(this.hasHitMin, this.hasHitMax); + bool get hasHitAny => hasHitMin || hasHitMax; bool get hasHitBoth => hasHitMin && hasHitMax; diff --git a/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart b/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart index 256612d9f..f3c12f8f9 100644 --- a/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart +++ b/plugins/aves_magnifier/lib/src/scale/scale_boundaries.dart @@ -1,12 +1,13 @@ import 'dart:math'; import 'package:aves_magnifier/src/controller/controller.dart'; +import 'package:aves_magnifier/src/controller/range.dart'; import 'package:aves_magnifier/src/scale/scale_level.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/widgets.dart'; /// Internal class to wrap custom scale boundaries (min, max and initial) -/// Also, stores values regarding the two sizes: the container and the child. +/// Also, stores values regarding the two sizes: the container and the content. @immutable class ScaleBoundaries extends Equatable { final bool _allowOriginalScaleBeyondRange; @@ -14,10 +15,13 @@ class ScaleBoundaries extends Equatable { final ScaleLevel _maxScale; final ScaleLevel _initialScale; final Size viewportSize; - final Size childSize; + final Size contentSize; + final Matrix4? externalTransform; + + static const Alignment basePosition = Alignment.center; @override - List get props => [_allowOriginalScaleBeyondRange, _minScale, _maxScale, _initialScale, viewportSize, childSize]; + List get props => [_allowOriginalScaleBeyondRange, _minScale, _maxScale, _initialScale, viewportSize, contentSize, externalTransform]; const ScaleBoundaries({ required bool allowOriginalScaleBeyondRange, @@ -25,32 +29,54 @@ class ScaleBoundaries extends Equatable { required ScaleLevel maxScale, required ScaleLevel initialScale, required this.viewportSize, - required this.childSize, + required this.contentSize, + this.externalTransform, }) : _allowOriginalScaleBeyondRange = allowOriginalScaleBeyondRange, _minScale = minScale, _maxScale = maxScale, _initialScale = initialScale; + static const ScaleBoundaries zero = ScaleBoundaries( + allowOriginalScaleBeyondRange: true, + minScale: ScaleLevel(factor: .0), + maxScale: ScaleLevel(factor: double.infinity), + initialScale: ScaleLevel(ref: ScaleReference.contained), + viewportSize: Size.zero, + contentSize: Size.zero, + ); + ScaleBoundaries copyWith({ - Size? childSize, + bool? allowOriginalScaleBeyondRange, + ScaleLevel? minScale, + ScaleLevel? maxScale, + ScaleLevel? initialScale, + Size? viewportSize, + Size? contentSize, + Matrix4? externalTransform, }) { return ScaleBoundaries( - allowOriginalScaleBeyondRange: _allowOriginalScaleBeyondRange, - minScale: _minScale, - maxScale: _maxScale, - initialScale: _initialScale, - viewportSize: viewportSize, - childSize: childSize ?? this.childSize, + allowOriginalScaleBeyondRange: allowOriginalScaleBeyondRange ?? _allowOriginalScaleBeyondRange, + minScale: minScale ?? _minScale, + maxScale: maxScale ?? _maxScale, + initialScale: initialScale ?? _initialScale, + viewportSize: viewportSize ?? this.viewportSize, + contentSize: contentSize ?? this.contentSize, + externalTransform: externalTransform ?? this.externalTransform, ); } + Size get _transformedViewportSize { + final matrix = externalTransform; + return matrix != null ? MatrixUtils.transformRect(Matrix4.inverted(matrix), Offset.zero & viewportSize).size : viewportSize; + } + double scaleForLevel(ScaleLevel level) { final factor = level.factor; switch (level.ref) { case ScaleReference.contained: - return factor * ScaleLevel.scaleForContained(viewportSize, childSize); + return factor * ScaleLevel.scaleForContained(viewportSize, contentSize); case ScaleReference.covered: - return factor * ScaleLevel.scaleForCovering(viewportSize, childSize); + return factor * ScaleLevel.scaleForCovering(viewportSize, contentSize); case ScaleReference.absolute: default: return factor; @@ -62,33 +88,83 @@ class ScaleBoundaries extends Equatable { return 1.0 / (view?.devicePixelRatio ?? 1.0); } - double get minScale => { - scaleForLevel(_minScale), - _allowOriginalScaleBeyondRange ? originalScale : double.infinity, - initialScale, - }.fold(double.infinity, min); - - double get maxScale => { - scaleForLevel(_maxScale), - _allowOriginalScaleBeyondRange ? originalScale : double.negativeInfinity, - initialScale, - }.fold(0, max); - double get initialScale => scaleForLevel(_initialScale); Offset get _viewportCenter => viewportSize.center(Offset.zero); - Offset get _childCenter => childSize.center(Offset.zero); + Offset get _contentCenter => contentSize.center(Offset.zero); Offset viewportToStatePosition(AvesMagnifierController controller, Offset viewportPosition) { return viewportPosition - _viewportCenter - controller.position; } - Offset viewportToChildPosition(AvesMagnifierController controller, Offset viewportPosition) { - return viewportToStatePosition(controller, viewportPosition) / controller.scale! + _childCenter; + Offset viewportToContentPosition(AvesMagnifierController controller, Offset viewportPosition) { + return viewportToStatePosition(controller, viewportPosition) / controller.scale! + _contentCenter; } - Offset childToStatePosition(double scale, Offset childPosition) { - return (_childCenter - childPosition) * scale; + Offset contentToStatePosition(double scale, Offset contentPosition) { + return (_contentCenter - contentPosition) * scale; + } + + EdgeRange getXEdges({required double scale}) { + final computedWidth = contentSize.width * scale; + final viewportWidth = _transformedViewportSize.width; + + final positionX = basePosition.x; + final widthDiff = computedWidth - viewportWidth; + + final minX = ((positionX - 1).abs() / 2) * widthDiff * -1; + final maxX = ((positionX + 1).abs() / 2) * widthDiff; + return EdgeRange(minX, maxX); + } + + EdgeRange getYEdges({required double scale}) { + final computedHeight = contentSize.height * scale; + final viewportHeight = _transformedViewportSize.height; + + final positionY = basePosition.y; + final heightDiff = computedHeight - viewportHeight; + + final minY = ((positionY - 1).abs() / 2) * heightDiff * -1; + final maxY = ((positionY + 1).abs() / 2) * heightDiff; + return EdgeRange(minY, maxY); + } + + double clampScale(double scale) { + final minScale = { + scaleForLevel(_minScale), + _allowOriginalScaleBeyondRange ? originalScale : double.infinity, + initialScale, + }.fold(double.infinity, min); + + final maxScale = { + scaleForLevel(_maxScale), + _allowOriginalScaleBeyondRange ? originalScale : double.negativeInfinity, + initialScale, + }.fold(.0, max); + + return scale.clamp(minScale, maxScale); + } + + Offset clampPosition({required Offset position, required double scale}) { + final computedWidth = contentSize.width * scale; + final computedHeight = contentSize.height * scale; + + final viewportWidth = _transformedViewportSize.width; + final viewportHeight = _transformedViewportSize.height; + + var finalX = 0.0; + if (viewportWidth < computedWidth) { + final range = getXEdges(scale: scale); + finalX = position.dx.clamp(range.min, range.max); + } + + var finalY = 0.0; + if (viewportHeight < computedHeight) { + final range = getYEdges(scale: scale); + finalY = position.dy.clamp(range.min, range.max); + } + + return Offset(finalX, finalY); } } diff --git a/plugins/aves_magnifier/lib/src/scale/scale_level.dart b/plugins/aves_magnifier/lib/src/scale/scale_level.dart index a076181ae..b186684e0 100644 --- a/plugins/aves_magnifier/lib/src/scale/scale_level.dart +++ b/plugins/aves_magnifier/lib/src/scale/scale_level.dart @@ -17,9 +17,9 @@ class ScaleLevel extends Equatable { this.factor = 1.0, }); - static double scaleForContained(Size containerSize, Size childSize) => min(containerSize.width / childSize.width, containerSize.height / childSize.height); + static double scaleForContained(Size viewportSize, Size contentSize) => min(viewportSize.width / contentSize.width, viewportSize.height / contentSize.height); - static double scaleForCovering(Size containerSize, Size childSize) => max(containerSize.width / childSize.width, containerSize.height / childSize.height); + static double scaleForCovering(Size viewportSize, Size contentSize) => max(viewportSize.width / contentSize.width, viewportSize.height / contentSize.height); } enum ScaleReference { absolute, contained, covered } diff --git a/plugins/aves_magnifier/lib/src/scale/state.dart b/plugins/aves_magnifier/lib/src/scale/state.dart index 44f5dd533..6cf44a351 100644 --- a/plugins/aves_magnifier/lib/src/scale/state.dart +++ b/plugins/aves_magnifier/lib/src/scale/state.dart @@ -33,12 +33,9 @@ ScaleState defaultScaleStateCycle(ScaleState actual) { case ScaleState.covering: return ScaleState.originalSize; case ScaleState.originalSize: - return ScaleState.initial; case ScaleState.zoomedIn: case ScaleState.zoomedOut: return ScaleState.initial; - default: - return ScaleState.initial; } } diff --git a/plugins/aves_magnifier/pubspec.lock b/plugins/aves_magnifier/pubspec.lock index 318c61e2c..7ae3ad656 100644 --- a/plugins/aves_magnifier/pubspec.lock +++ b/plugins/aves_magnifier/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + aves_utils: + dependency: "direct main" + description: + path: "../aves_utils" + relative: true + source: path + version: "0.0.1" characters: dependency: transitive description: diff --git a/plugins/aves_magnifier/pubspec.yaml b/plugins/aves_magnifier/pubspec.yaml index b60a8df8c..cb6f1a9c7 100644 --- a/plugins/aves_magnifier/pubspec.yaml +++ b/plugins/aves_magnifier/pubspec.yaml @@ -8,6 +8,8 @@ environment: dependencies: flutter: sdk: flutter + aves_utils: + path: ../aves_utils equatable: provider: tuple: diff --git a/plugins/aves_model/lib/aves_model.dart b/plugins/aves_model/lib/aves_model.dart index f03a09657..30d67e558 100644 --- a/plugins/aves_model/lib/aves_model.dart +++ b/plugins/aves_model/lib/aves_model.dart @@ -10,6 +10,7 @@ export 'src/actions/move_type.dart'; export 'src/actions/settings.dart'; export 'src/actions/share.dart'; export 'src/actions/slideshow.dart'; +export 'src/editor/enums.dart'; export 'src/entry/base.dart'; export 'src/metadata/enums.dart'; export 'src/metadata/fields.dart'; diff --git a/plugins/aves_model/lib/src/editor/enums.dart b/plugins/aves_model/lib/src/editor/enums.dart new file mode 100644 index 000000000..7d03820ac --- /dev/null +++ b/plugins/aves_model/lib/src/editor/enums.dart @@ -0,0 +1,66 @@ +enum EditorAction { transform } + +enum CropAspectRatio { free, original, square, ar_16_9, ar_4_3 } + +enum TransformActivity { none, pan, resize, straighten } + +enum TransformOrientation { normal, rotate90, rotate180, rotate270, transverse, flipVertical, transpose, flipHorizontal } + +extension ExtraTransformOrientation on TransformOrientation { + TransformOrientation flipHorizontally() { + switch (this) { + case TransformOrientation.normal: + return TransformOrientation.flipHorizontal; + case TransformOrientation.rotate90: + return TransformOrientation.transverse; + case TransformOrientation.rotate180: + return TransformOrientation.flipVertical; + case TransformOrientation.rotate270: + return TransformOrientation.transpose; + case TransformOrientation.transverse: + return TransformOrientation.rotate90; + case TransformOrientation.flipVertical: + return TransformOrientation.rotate180; + case TransformOrientation.transpose: + return TransformOrientation.rotate270; + case TransformOrientation.flipHorizontal: + return TransformOrientation.normal; + } + } + + bool get isFlipped { + switch (this) { + case TransformOrientation.normal: + case TransformOrientation.rotate90: + case TransformOrientation.rotate180: + case TransformOrientation.rotate270: + return false; + case TransformOrientation.transverse: + case TransformOrientation.flipVertical: + case TransformOrientation.transpose: + case TransformOrientation.flipHorizontal: + return true; + } + } + + TransformOrientation rotateClockwise() { + switch (this) { + case TransformOrientation.normal: + return TransformOrientation.rotate90; + case TransformOrientation.rotate90: + return TransformOrientation.rotate180; + case TransformOrientation.rotate180: + return TransformOrientation.rotate270; + case TransformOrientation.rotate270: + return TransformOrientation.normal; + case TransformOrientation.transverse: + return TransformOrientation.flipHorizontal; + case TransformOrientation.flipVertical: + return TransformOrientation.transverse; + case TransformOrientation.transpose: + return TransformOrientation.flipVertical; + case TransformOrientation.flipHorizontal: + return TransformOrientation.transpose; + } + } +} diff --git a/plugins/aves_utils/lib/aves_utils.dart b/plugins/aves_utils/lib/aves_utils.dart index 1921022e4..d41bcfd2b 100644 --- a/plugins/aves_utils/lib/aves_utils.dart +++ b/plugins/aves_utils/lib/aves_utils.dart @@ -2,3 +2,4 @@ library aves_utils; export 'src/change_notifier.dart'; export 'src/optional_event_channel.dart'; +export 'src/vector_utils.dart'; diff --git a/plugins/aves_utils/lib/src/change_notifier.dart b/plugins/aves_utils/lib/src/change_notifier.dart index 60ad5d939..1e0b0b9f5 100644 --- a/plugins/aves_utils/lib/src/change_notifier.dart +++ b/plugins/aves_utils/lib/src/change_notifier.dart @@ -1,6 +1,6 @@ import 'package:flutter/foundation.dart'; -// `ChangeNotifier` wrapper so that it can be used anywhere, not just as a mixin +// `ChangeNotifier` wrapper to call `notify` without constraint class AChangeNotifier extends ChangeNotifier { void notify() { // why is this protected? diff --git a/plugins/aves_utils/lib/src/vector_utils.dart b/plugins/aves_utils/lib/src/vector_utils.dart new file mode 100644 index 000000000..14f320784 --- /dev/null +++ b/plugins/aves_utils/lib/src/vector_utils.dart @@ -0,0 +1,15 @@ +import 'dart:ui'; + +import 'package:vector_math/vector_math_64.dart'; + +extension ExtraOffset on Offset { + Vector3 get toVector3 => Vector3(dx, dy, 0); +} + +extension ExtraVector3 on Vector3 { + Offset get toOffset => Offset(x, y); +} + +extension ExtraMatrix4 on Matrix4 { + Offset transformOffset(Offset v) => transform3(v.toVector3).toOffset; +} diff --git a/plugins/aves_utils/pubspec.lock b/plugins/aves_utils/pubspec.lock index 65a37f405..f496c7561 100644 --- a/plugins/aves_utils/pubspec.lock +++ b/plugins/aves_utils/pubspec.lock @@ -68,7 +68,7 @@ packages: source: sdk version: "0.0.99" vector_math: - dependency: transitive + dependency: "direct main" description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" diff --git a/plugins/aves_utils/pubspec.yaml b/plugins/aves_utils/pubspec.yaml index dd19f728c..52f2d1f3d 100644 --- a/plugins/aves_utils/pubspec.yaml +++ b/plugins/aves_utils/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: flutter: sdk: flutter + vector_math: dev_dependencies: flutter_lints: diff --git a/pubspec.lock b/pubspec.lock index b2210d693..dcb48c388 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1462,7 +1462,7 @@ packages: source: hosted version: "3.0.6" vector_math: - dependency: transitive + dependency: "direct main" description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" diff --git a/pubspec.yaml b/pubspec.yaml index 639a13adc..23676818c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -113,6 +113,7 @@ dependencies: transparent_image: tuple: url_launcher: + vector_math: volume_controller: xml: diff --git a/test/model/view_state_test.dart b/test/model/view_state_test.dart new file mode 100644 index 000000000..7da0dcb84 --- /dev/null +++ b/test/model/view_state_test.dart @@ -0,0 +1,90 @@ +import 'dart:ui'; + +import 'package:aves/model/view_state.dart'; +import 'package:aves_utils/aves_utils.dart'; +import 'package:test/test.dart'; +import 'package:vector_math/vector_math_64.dart'; + +void main() { + test('scene -> viewport, original scaleFit', () { + const viewport = Rect.fromLTWH(0, 0, 100, 200); + const content = Rect.fromLTWH(0, 0, 200, 400); + final state = ViewState(position: Offset.zero, scale: 1, viewportSize: viewport.size, contentSize: content.size); + + expect(_toViewportPoint(state, content.topLeft), const Offset(-50, -100)); + expect(_toViewportPoint(state, content.bottomRight), const Offset(150, 300)); + }); + + test('scene -> viewport, scaled to fit .5', () { + const viewport = Rect.fromLTWH(0, 0, 100, 200); + const content = Rect.fromLTWH(0, 0, 200, 400); + final state = ViewState(position: Offset.zero, scale: .5, viewportSize: viewport.size, contentSize: content.size); + + expect(_toViewportPoint(state, content.topLeft), viewport.topLeft); + expect(_toViewportPoint(state, content.center), viewport.center); + expect(_toViewportPoint(state, content.bottomRight), viewport.bottomRight); + }); + + test('scene -> viewport, scaled to fit .25', () { + const viewport = Rect.fromLTWH(0, 0, 50, 100); + const content = Rect.fromLTWH(0, 0, 200, 400); + final state = ViewState(position: Offset.zero, scale: .25, viewportSize: viewport.size, contentSize: content.size); + + expect(_toViewportPoint(state, content.topLeft), viewport.topLeft); + expect(_toViewportPoint(state, content.center), viewport.center); + expect(_toViewportPoint(state, content.bottomRight), viewport.bottomRight); + }); + + test('viewport -> scene, original scaleFit', () { + const viewport = Rect.fromLTWH(0, 0, 100, 200); + const content = Rect.fromLTWH(0, 0, 200, 400); + final state = ViewState(position: Offset.zero, scale: 1, viewportSize: viewport.size, contentSize: content.size); + + expect(_toContentPoint(state, viewport.topLeft), const Offset(50, 100)); + expect(_toContentPoint(state, viewport.bottomRight), const Offset(150, 300)); + }); + + test('viewport -> scene, scaled to fit', () { + const viewport = Rect.fromLTWH(0, 0, 100, 200); + const content = Rect.fromLTWH(0, 0, 200, 400); + final state = ViewState(position: Offset.zero, scale: .5, viewportSize: viewport.size, contentSize: content.size); + + expect(_toContentPoint(state, viewport.topLeft), content.topLeft); + expect(_toContentPoint(state, viewport.center), content.center); + expect(_toContentPoint(state, viewport.bottomRight), content.bottomRight); + }); + + test('viewport -> scene, translated', () { + const viewport = Rect.fromLTWH(0, 0, 100, 200); + const content = Rect.fromLTWH(0, 0, 200, 400); + final state = ViewState(position: const Offset(50, 50), scale: 1, viewportSize: viewport.size, contentSize: content.size); + + _toContentPoint(state, viewport.topLeft); + expect(_toContentPoint(state, viewport.topLeft), const Offset(0, 50)); + expect(_toContentPoint(state, viewport.bottomRight), const Offset(100, 250)); + }); + + test('scene -> viewport, scaled to fit, different ratios', () { + const viewport = Rect.fromLTWH(0, 0, 360, 521); + const content = Rect.fromLTWH(0, 0, 2268, 4032); + final scaleFit = viewport.height / content.height; + final state = ViewState(position: Offset.zero, scale: scaleFit, viewportSize: viewport.size, contentSize: content.size); + + final scaledContentLeft = (viewport.width - content.width * scaleFit) / 2; + final scaledContentRight = viewport.width - scaledContentLeft; + + expect(_toViewportPoint(state, content.topLeft), Offset(scaledContentLeft, 0)); + expect(_toViewportPoint(state, content.center), viewport.center); + expect(_toViewportPoint(state, content.bottomRight), Offset(scaledContentRight, viewport.bottom)); + }); +} + +// convenience methods + +Offset _toViewportPoint(ViewState state, Offset contentPoint) { + return state.matrix.transformOffset(contentPoint); +} + +Offset _toContentPoint(ViewState state, viewportPoint) { + return Matrix4.inverted(state.matrix).transformOffset(viewportPoint); +} diff --git a/test/utils/math_utils_test.dart b/test/utils/math_utils_test.dart index bb8f5cae2..8032d07c9 100644 --- a/test/utils/math_utils_test.dart +++ b/test/utils/math_utils_test.dart @@ -1,5 +1,8 @@ +import 'dart:ui'; + import 'package:aves/utils/math_utils.dart'; import 'package:test/test.dart'; +import 'package:tuple/tuple.dart'; void main() { test('highest power of 2 that is smaller than or equal to the number', () { @@ -24,4 +27,10 @@ void main() { expect(roundToPrecision(1.2345678, decimals: 3), 1.235); expect(roundToPrecision(0, decimals: 3), 0); }); + + test('segment intersection', () { + const s1 = Tuple2(Offset(1, 1), Offset(3, 2)); + const s2 = Tuple2(Offset(1, 4), Offset(2, -1)); + expect(segmentIntersection(s1, s2), const Offset(17 / 11, 14 / 11)); + }); } diff --git a/untranslated.json b/untranslated.json index d07633804..7e2beb5f6 100644 --- a/untranslated.json +++ b/untranslated.json @@ -6,6 +6,8 @@ "timeMinutes", "timeDays", "focalLength", + "saveCopyButtonLabel", + "applyTooltip", "pickTooltip", "sourceStateLoading", "sourceStateCataloguing", @@ -75,6 +77,12 @@ "entryInfoActionRemoveMetadata", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterBinLabel", @@ -625,6 +633,8 @@ ], "ckb": [ + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionShowCountryStates", "entryActionRotateCCW", @@ -654,6 +664,12 @@ "entryInfoActionRemoveMetadata", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterBinLabel", @@ -1217,6 +1233,14 @@ ], "cs": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "maxBrightnessNever", "maxBrightnessAlways", "videoResumptionModeNever", @@ -1231,6 +1255,14 @@ ], "de": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "maxBrightnessNever", "maxBrightnessAlways", "videoResumptionModeNever", @@ -1244,7 +1276,42 @@ "tagEditorDiscardDialogMessage" ], + "el": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + + "es": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + + "eu": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + "fa": [ + "saveCopyButtonLabel", + "applyTooltip", "clearTooltip", "chipActionGoToPlacePage", "chipActionLock", @@ -1257,6 +1324,12 @@ "viewerActionLock", "viewerActionUnlock", "slideshowActionResume", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterLocatedLabel", @@ -1739,8 +1812,21 @@ "filePickerUseThisFolder" ], + "fr": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + "gl": [ "columnCount", + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -1752,6 +1838,12 @@ "viewerActionUnlock", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterNoAddressLabel", @@ -2279,6 +2371,8 @@ "showButtonLabel", "hideButtonLabel", "continueButtonLabel", + "saveCopyButtonLabel", + "applyTooltip", "cancelTooltip", "changeTooltip", "clearTooltip", @@ -2360,6 +2454,12 @@ "entryInfoActionRemoveMetadata", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterBinLabel", @@ -2923,6 +3023,8 @@ ], "hi": [ + "saveCopyButtonLabel", + "applyTooltip", "resetTooltip", "saveTooltip", "pickTooltip", @@ -2996,6 +3098,12 @@ "entryInfoActionRemoveMetadata", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterBinLabel", @@ -3558,13 +3666,54 @@ "filePickerUseThisFolder" ], + "hu": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + + "id": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + + "it": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + "ja": [ "columnCount", + "saveCopyButtonLabel", + "applyTooltip", "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "filterTaggedLabel", "albumTierVaults", @@ -3600,8 +3749,21 @@ "tagEditorDiscardDialogMessage" ], + "ko": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + "lt": [ "columnCount", + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -3609,6 +3771,12 @@ "chipActionConfigureVault", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "filterTaggedLabel", "albumTierVaults", @@ -3684,6 +3852,8 @@ "showButtonLabel", "hideButtonLabel", "continueButtonLabel", + "saveCopyButtonLabel", + "applyTooltip", "cancelTooltip", "changeTooltip", "clearTooltip", @@ -3765,6 +3935,12 @@ "entryInfoActionRemoveMetadata", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterBinLabel", @@ -4328,9 +4504,17 @@ ], "nb": [ + "saveCopyButtonLabel", + "applyTooltip", "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "maxBrightnessNever", "maxBrightnessAlways", "vaultLockTypePattern", @@ -4359,6 +4543,8 @@ "nl": [ "columnCount", + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -4366,6 +4552,12 @@ "entryActionShareVideoOnly", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "albumTierVaults", "maxBrightnessNever", @@ -4425,6 +4617,8 @@ "nn": [ "columnCount", + "saveCopyButtonLabel", + "applyTooltip", "sourceStateCataloguing", "chipActionGoToPlacePage", "chipActionLock", @@ -4434,6 +4628,12 @@ "viewerActionLock", "viewerActionUnlock", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "filterNoLocationLabel", "filterTaggedLabel", @@ -4778,6 +4978,8 @@ "deleteButtonLabel", "nextButtonLabel", "continueButtonLabel", + "saveCopyButtonLabel", + "applyTooltip", "cancelTooltip", "changeTooltip", "clearTooltip", @@ -4853,6 +5055,12 @@ "entryInfoActionRemoveMetadata", "entryInfoActionExportMetadata", "entryInfoActionRemoveLocation", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterAspectRatioLandscapeLabel", "filterAspectRatioPortraitLabel", "filterBinLabel", @@ -5354,7 +5562,37 @@ "filePickerUseThisFolder" ], + "pl": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + + "pt": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + "ro": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "maxBrightnessNever", "maxBrightnessAlways", "videoResumptionModeNever", @@ -5369,6 +5607,14 @@ ], "ru": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "maxBrightnessNever", "maxBrightnessAlways", "videoResumptionModeNever", @@ -5393,6 +5639,8 @@ "itemCount", "columnCount", "timeSeconds", + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -5400,6 +5648,12 @@ "chipActionConfigureVault", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "filterNoLocationLabel", "albumTierVaults", @@ -5841,6 +6095,8 @@ "timeDays", "focalLength", "applyButtonLabel", + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -5848,6 +6104,12 @@ "chipActionConfigureVault", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "albumTierVaults", "lengthUnitPixel", "lengthUnitPercent", @@ -6213,6 +6475,8 @@ ], "tr": [ + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -6220,6 +6484,12 @@ "chipActionConfigureVault", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "albumTierVaults", "lengthUnitPixel", "lengthUnitPercent", @@ -6269,10 +6539,29 @@ "tagPlaceholderState" ], + "uk": [ + "saveCopyButtonLabel", + "applyTooltip", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare" + ], + "zh": [ + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "filterTaggedLabel", "albumTierVaults", @@ -6332,6 +6621,8 @@ "zh_Hant": [ "columnCount", + "saveCopyButtonLabel", + "applyTooltip", "chipActionGoToPlacePage", "chipActionLock", "chipActionShowCountryStates", @@ -6339,6 +6630,12 @@ "chipActionConfigureVault", "viewerActionLock", "viewerActionUnlock", + "editorActionTransform", + "editorTransformCrop", + "editorTransformRotate", + "cropAspectRatioFree", + "cropAspectRatioOriginal", + "cropAspectRatioSquare", "filterLocatedLabel", "filterTaggedLabel", "albumTierVaults", From a4e5748ced2a344e1a49f80137d6011f16f47650 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 15:41:13 +0200 Subject: [PATCH 16/35] revert agp 8 --- android/app/build.gradle | 2 ++ android/build.gradle | 4 +++- android/gradle.properties | 6 +++--- android/gradle/wrapper/gradle-wrapper.properties | 2 +- pubspec.lock | 6 +++--- pubspec.yaml | 8 +++----- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index bf19c8257..5213fabf6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -232,6 +232,8 @@ dependencies { // huawei flavor only huaweiImplementation "com.huawei.agconnect:agconnect-core:$huawei_agconnect_version" + testImplementation "org.junit.jupiter:junit-jupiter-engine:5.9.2" + kapt 'androidx.annotation:annotation:1.6.0' kapt "com.github.bumptech.glide:compiler:$glide_version" diff --git a/android/build.gradle b/android/build.gradle index b8c6923a4..736af05b3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,8 +1,10 @@ buildscript { ext { kotlin_version = '1.8.21' - agp_version = '8.0.1' + agp_version = '7.4.2' glide_version = '4.15.1' + // AppGallery Connect plugin versions: https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-sdk-changenotes-0000001058732550 + // TODO TLAD AppGallery Connect plugin v1.8.1.300 does not support Gradle 8+ huawei_agconnect_version = '1.8.0.300' abiCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3, 'x86_64': 4] useCrashlytics = gradle.startParameter.taskNames.any { task -> task.containsIgnoreCase("play") } diff --git a/android/gradle.properties b/android/gradle.properties index d87c7019b..55ec37afc 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -15,6 +15,6 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -android.defaults.buildfeatures.buildconfig=true -android.nonTransitiveRClass=false -android.nonFinalResIds=false +#android.defaults.buildfeatures.buildconfig=true +#android.nonTransitiveRClass=false +#android.nonFinalResIds=false diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 8bc9958ab..3c472b99c 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/pubspec.lock b/pubspec.lock index dcb48c388..2d2595325 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -407,9 +407,9 @@ packages: dependency: "direct main" description: path: "." - ref: kotlin-jvm-target - resolved-ref: "4781520e090c3a104e2478cfe8e8cb97235341ec" - url: "https://github.com/deckerst/floating.git" + ref: main + resolved-ref: b073419d48f099b5855816a7c6e04d397b1f1c37 + url: "https://github.com/wrbl606/floating.git" source: git version: "2.0.0" fluster: diff --git a/pubspec.yaml b/pubspec.yaml index 23676818c..218d08138 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -70,11 +70,9 @@ dependencies: flex_color_picker: floating: git: - # url: https://github.com/wrbl606/floating.git - # # v2.0.0 is incompatible with AGP8 - # ref: main - url: https://github.com/deckerst/floating.git - ref: kotlin-jvm-target + url: https://github.com/wrbl606/floating.git + # v2.0.0 is incompatible with AGP8 + ref: main fluster: flutter_displaymode: flutter_highlight: From 94647a928bfd7ac15fddbb5b0405f658d1d69f8f Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 16:07:59 +0200 Subject: [PATCH 17/35] #637 fixed writing incorrect OffsetTime tag when timezone is negative --- .../aves/model/provider/ImageProvider.kt | 16 +++++++++++----- .../aves/model/provider/ImageProviderTest.kt | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 android/app/src/test/kotlin/deckers/thibault/aves/model/provider/ImageProviderTest.kt diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt index c6b825258..ac1624c5b 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt @@ -52,6 +52,7 @@ import pixy.meta.meta.MetadataType import java.io.* import java.nio.channels.Channels import java.util.* +import kotlin.math.absoluteValue abstract class ImageProvider { open fun fetchSingle(context: Context, uri: Uri, sourceMimeType: String?, callback: ImageOpCallback) { @@ -538,11 +539,7 @@ abstract class ImageProvider { exif.setAttribute(ExifInterface.TAG_DATETIME, dateString) exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, dateString) - val offsetInMinutes = TimeZone.getDefault().getOffset(dateTimeMillis) / 60000 - val offsetSign = if (offsetInMinutes < 0) "-" else "+" - val offsetHours = "${offsetInMinutes / 60}".padStart(2, '0') - val offsetMinutes = "${offsetInMinutes % 60}".padStart(2, '0') - val timeZoneString = "$offsetSign$offsetHours:$offsetMinutes" + val timeZoneString = getTimeZoneString(TimeZone.getDefault(), dateTimeMillis) exif.setAttribute(ExifInterface.TAG_OFFSET_TIME, timeZoneString) exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL, timeZoneString) @@ -1387,6 +1384,15 @@ abstract class ImageProvider { false } } + + fun getTimeZoneString(timeZone: TimeZone, dateTimeMillis: Long): String { + val offset = timeZone.getOffset(dateTimeMillis) + val offsetInMinutes = offset.absoluteValue / 60000 + val offsetSign = if (offset < 0) "-" else "+" + val offsetHours = "${offsetInMinutes / 60}".padStart(2, '0') + val offsetMinutes = "${offsetInMinutes % 60}".padStart(2, '0') + return "$offsetSign$offsetHours:$offsetMinutes" + } } } diff --git a/android/app/src/test/kotlin/deckers/thibault/aves/model/provider/ImageProviderTest.kt b/android/app/src/test/kotlin/deckers/thibault/aves/model/provider/ImageProviderTest.kt new file mode 100644 index 000000000..705503c62 --- /dev/null +++ b/android/app/src/test/kotlin/deckers/thibault/aves/model/provider/ImageProviderTest.kt @@ -0,0 +1,18 @@ +package deckers.thibault.aves.model.provider + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.time.LocalDate +import java.time.Month +import java.util.TimeZone + +class ImageProviderTest { + @Test + fun imageProvider_CorrectEmailSimple_ReturnsTrue() { + val date = LocalDate.of(1990, Month.FEBRUARY, 11).toEpochDay() + assertEquals(ImageProvider.getTimeZoneString(TimeZone.getTimeZone("Europe/Paris"), date), "+01:00") + assertEquals(ImageProvider.getTimeZoneString(TimeZone.getTimeZone("UTC"), date), "+00:00") + assertEquals(ImageProvider.getTimeZoneString(TimeZone.getTimeZone("Asia/Kolkata"), date), "+05:30") + assertEquals(ImageProvider.getTimeZoneString(TimeZone.getTimeZone("America/Chicago"), date), "-06:00") + } +} From c56ab99315002f05354812cb385779648b4abb2e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 16:58:08 +0200 Subject: [PATCH 18/35] #639 keep showing empty albums if are pinned --- CHANGELOG.md | 1 + lib/model/source/album.dart | 6 +++++- lib/model/source/collection_source.dart | 4 +++- lib/model/source/media_store_source.dart | 2 ++ .../filter_grids/common/action_delegates/album_set.dart | 1 + 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c35f01c6..fe67ce4d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. ### Changed +- keep showing empty albums if are pinned - remember whether to show the title filter when picking albums - upgraded Flutter to stable v3.10.0 diff --git a/lib/model/source/album.dart b/lib/model/source/album.dart index 809086b97..1a2c09bd4 100644 --- a/lib/model/source/album.dart +++ b/lib/model/source/album.dart @@ -90,7 +90,11 @@ mixin AlbumMixin on SourceBase { } bool _isRemovable(String album) { - return !(visibleEntries.any((entry) => entry.directory == album) || _newAlbums.contains(album) || vaults.isVault(album)); + if (visibleEntries.any((entry) => entry.directory == album)) return false; + if (_newAlbums.contains(album)) return false; + if (vaults.isVault(album)) return false; + if (settings.pinnedFilters.whereType().map((v) => v.album).contains(album)) return false; + return true; } // filter summary diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index 5464e6774..e12ee7da3 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -292,7 +292,9 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place settings.drawerAlbumBookmarks = settings.drawerAlbumBookmarks?..insert(bookmark, destinationAlbum); } if (pinned) { - settings.pinnedFilters = settings.pinnedFilters..add(newFilter); + settings.pinnedFilters = settings.pinnedFilters + ..remove(oldFilter) + ..add(newFilter); } } diff --git a/lib/model/source/media_store_source.dart b/lib/model/source/media_store_source.dart index 5ca9a2466..2c8cd142a 100644 --- a/lib/model/source/media_store_source.dart +++ b/lib/model/source/media_store_source.dart @@ -5,6 +5,7 @@ import 'package:aves/model/covers.dart'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/origins.dart'; import 'package:aves/model/favourites.dart'; +import 'package:aves/model/filters/album.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/analysis_controller.dart'; import 'package:aves/model/source/collection_source.dart'; @@ -34,6 +35,7 @@ class MediaStoreSource extends CollectionSource { if (_initState != SourceInitializationState.full) { _initState = directory != null ? SourceInitializationState.directory : SourceInitializationState.full; } + addDirectories(albums: settings.pinnedFilters.whereType().map((v) => v.album).toSet()); unawaited(_loadEntries( analysisController: analysisController, directory: directory, diff --git a/lib/widgets/filter_grids/common/action_delegates/album_set.dart b/lib/widgets/filter_grids/common/action_delegates/album_set.dart index 28894923c..9a46e474d 100644 --- a/lib/widgets/filter_grids/common/action_delegates/album_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/album_set.dart @@ -320,6 +320,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with ); if (confirmed == null || !confirmed) return; + settings.pinnedFilters = settings.pinnedFilters..removeAll(filters); source.forgetNewAlbums(todoAlbums); source.cleanEmptyAlbums(emptyAlbums); From 56b67c47db7e8c75dd773b9aadf550275388b614 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 17:08:56 +0200 Subject: [PATCH 19/35] #631 info: day filter with item date --- CHANGELOG.md | 1 + lib/widgets/viewer/info/basic_section.dart | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe67ce4d4..30ca19c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - option to set the Tags page as home - support for animated PNG +- Info: added day filter with item date ### Changed diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index ec7de8dde..73445653d 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -7,6 +7,7 @@ import 'package:aves/model/entry/extensions/multipage.dart'; import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/favourites.dart'; import 'package:aves/model/filters/album.dart'; +import 'package:aves/model/filters/date.dart'; import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/mime.dart'; import 'package:aves/model/filters/rating.dart'; @@ -115,6 +116,7 @@ class _BasicSectionState extends State { Widget _buildChips(BuildContext context) { final entry = widget.entry; final tags = entry.tags.toList()..sort(compareAsciiUpperCaseNatural); + final date = entry.bestDate; final album = entry.directory; final filters = { MimeFilter(entry.mimeType), @@ -125,6 +127,7 @@ class _BasicSectionState extends State { if (entry.isImage && entry.is360) TypeFilter.panorama, if (entry.isVideo && entry.is360) TypeFilter.sphericalVideo, if (entry.isVideo && !entry.is360) MimeFilter.video, + if (date != null) DateFilter(DateLevel.ymd, date), if (album != null) AlbumFilter(album, collection?.source.getAlbumDisplayName(context, album)), if (entry.rating != 0) RatingFilter(entry.rating), ...tags.map(TagFilter.new), From 00346ebb3147e49e8dbc81e7e30c70efc08a4b64 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 18:40:33 +0200 Subject: [PATCH 20/35] #638 widget: option to update on tap --- CHANGELOG.md | 1 + .../thibault/aves/HomeWidgetProvider.kt | 83 +++++++++++++------ lib/l10n/app_en.arb | 1 + lib/view/src/settings/enums.dart | 2 + lib/widget_common.dart | 8 +- lib/widgets/home_page.dart | 1 + .../aves_model/lib/src/settings/enums.dart | 2 +- untranslated.json | 55 +++++++++--- 8 files changed, 112 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30ca19c7a..5c27ee26a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - option to set the Tags page as home - support for animated PNG - Info: added day filter with item date +- Widget: option to update image on tap ### Changed diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt index 20961ea40..c65609042 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/HomeWidgetProvider.kt @@ -18,6 +18,7 @@ import deckers.thibault.aves.channel.AvesByteSendingMethodCodec import deckers.thibault.aves.channel.calls.* import deckers.thibault.aves.channel.streams.ImageByteStreamHandler import deckers.thibault.aves.channel.streams.MediaStoreStreamHandler +import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.utils.FlutterUtils import deckers.thibault.aves.utils.LogUtils import io.flutter.FlutterInjector @@ -40,11 +41,11 @@ class HomeWidgetProvider : AppWidgetProvider() { val widgetInfo = appWidgetManager.getAppWidgetOptions(widgetId) defaultScope.launch { - val backgroundBytes = getBytes(context, widgetId, widgetInfo, drawEntryImage = false) - updateWidgetImage(context, appWidgetManager, widgetId, widgetInfo, backgroundBytes) + val backgroundProps = getProps(context, widgetId, widgetInfo, drawEntryImage = false) + updateWidgetImage(context, appWidgetManager, widgetId, widgetInfo, backgroundProps) - val imageBytes = getBytes(context, widgetId, widgetInfo, drawEntryImage = true, reuseEntry = false) - updateWidgetImage(context, appWidgetManager, widgetId, widgetInfo, imageBytes) + val imageProps = getProps(context, widgetId, widgetInfo, drawEntryImage = true, reuseEntry = false) + updateWidgetImage(context, appWidgetManager, widgetId, widgetInfo, imageProps) } } } @@ -59,8 +60,8 @@ class HomeWidgetProvider : AppWidgetProvider() { } imageByteFetchJob = defaultScope.launch { delay(500) - val imageBytes = getBytes(context, widgetId, widgetInfo, drawEntryImage = true, reuseEntry = true) - updateWidgetImage(context, appWidgetManager, widgetId, widgetInfo, imageBytes) + val imageProps = getProps(context, widgetId, widgetInfo, drawEntryImage = true, reuseEntry = true) + updateWidgetImage(context, appWidgetManager, widgetId, widgetInfo, imageProps) } } @@ -76,13 +77,13 @@ class HomeWidgetProvider : AppWidgetProvider() { return Pair(widthPx, heightPx) } - private suspend fun getBytes( + private suspend fun getProps( context: Context, widgetId: Int, widgetInfo: Bundle, drawEntryImage: Boolean, reuseEntry: Boolean = false, - ): ByteArray? { + ): FieldMap? { val (widthPx, heightPx) = getWidgetSizePx(context, widgetInfo) if (widthPx == 0 || heightPx == 0) return null @@ -90,7 +91,7 @@ class HomeWidgetProvider : AppWidgetProvider() { val messenger = flutterEngine!!.dartExecutor val channel = MethodChannel(messenger, WIDGET_DRAW_CHANNEL) try { - val bytes = suspendCoroutine { cont -> + val props = suspendCoroutine { cont -> defaultScope.launch { FlutterUtils.runOnUiThread { channel.invokeMethod("drawWidget", hashMapOf( @@ -116,7 +117,8 @@ class HomeWidgetProvider : AppWidgetProvider() { } } } - if (bytes is ByteArray) return bytes + @Suppress("unchecked_cast") + return props as FieldMap? } catch (e: Exception) { Log.e(LOG_TAG, "failed to draw widget for widgetId=$widgetId widthPx=$widthPx heightPx=$heightPx", e) } @@ -128,9 +130,16 @@ class HomeWidgetProvider : AppWidgetProvider() { appWidgetManager: AppWidgetManager, widgetId: Int, widgetInfo: Bundle, - bytes: ByteArray?, + props: FieldMap?, ) { - bytes ?: return + props ?: return + + val bytes = props["bytes"] as ByteArray? + val updateOnTap = props["updateOnTap"] as Boolean? + if (bytes == null || updateOnTap == null) { + Log.e(LOG_TAG, "missing arguments") + return + } val (widthPx, heightPx) = getWidgetSizePx(context, widgetInfo) if (widthPx == 0 || heightPx == 0) return @@ -139,24 +148,11 @@ class HomeWidgetProvider : AppWidgetProvider() { val bitmap = Bitmap.createBitmap(widthPx, heightPx, Bitmap.Config.ARGB_8888) bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(bytes)) - // set a unique URI to prevent the intent (and its extras) from being shared by different widgets - val intent = Intent(MainActivity.INTENT_ACTION_WIDGET_OPEN, Uri.parse("widget://$widgetId"), context, MainActivity::class.java) - .putExtra(MainActivity.EXTRA_KEY_WIDGET_ID, widgetId) - - val activity = PendingIntent.getActivity( - context, - 0, - intent, - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE - } else { - PendingIntent.FLAG_UPDATE_CURRENT - } - ) + val pendingIntent = if (updateOnTap) buildUpdateIntent(context, widgetId) else buildOpenAppIntent(context, widgetId) val views = RemoteViews(context.packageName, R.layout.app_widget).apply { setImageViewBitmap(R.id.widget_img, bitmap) - setOnClickPendingIntent(R.id.widget_img, activity) + setOnClickPendingIntent(R.id.widget_img, pendingIntent) } appWidgetManager.updateAppWidget(widgetId, views) @@ -166,6 +162,39 @@ class HomeWidgetProvider : AppWidgetProvider() { } } + private fun buildUpdateIntent(context: Context, widgetId: Int): PendingIntent { + val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, Uri.parse("widget://$widgetId"), context, HomeWidgetProvider::class.java) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(widgetId)) + + return PendingIntent.getBroadcast( + context, + 0, + intent, + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + } else { + PendingIntent.FLAG_UPDATE_CURRENT + } + ) + } + + private fun buildOpenAppIntent(context: Context, widgetId: Int): PendingIntent { + // set a unique URI to prevent the intent (and its extras) from being shared by different widgets + val intent = Intent(MainActivity.INTENT_ACTION_WIDGET_OPEN, Uri.parse("widget://$widgetId"), context, MainActivity::class.java) + .putExtra(MainActivity.EXTRA_KEY_WIDGET_ID, widgetId) + + return PendingIntent.getActivity( + context, + 0, + intent, + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + } else { + PendingIntent.FLAG_UPDATE_CURRENT + } + ) + } + companion object { private val LOG_TAG = LogUtils.createTag() private const val WIDGET_DART_ENTRYPOINT = "widgetMain" diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a83d54d89..bcd049bbd 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -281,6 +281,7 @@ "widgetOpenPageHome": "Open home", "widgetOpenPageCollection": "Open collection", "widgetOpenPageViewer": "Open viewer", + "widgetTapUpdateWidget": "Update widget", "storageVolumeDescriptionFallbackPrimary": "Internal storage", "storageVolumeDescriptionFallbackNonPrimary": "SD card", diff --git a/lib/view/src/settings/enums.dart b/lib/view/src/settings/enums.dart index 3ac2afdf4..dedfc4018 100644 --- a/lib/view/src/settings/enums.dart +++ b/lib/view/src/settings/enums.dart @@ -275,6 +275,8 @@ extension ExtraWidgetOpenPageView on WidgetOpenPage { return context.l10n.widgetOpenPageCollection; case WidgetOpenPage.viewer: return context.l10n.widgetOpenPageViewer; + case WidgetOpenPage.updateWidget: + return context.l10n.widgetTapUpdateWidget; } } } diff --git a/lib/widget_common.dart b/lib/widget_common.dart index 4ea33f334..4197f0311 100644 --- a/lib/widget_common.dart +++ b/lib/widget_common.dart @@ -34,7 +34,7 @@ void widgetMainCommon(AppFlavor flavor) async { }); } -Future _drawWidget(dynamic args) async { +Future> _drawWidget(dynamic args) async { final widgetId = args['widgetId'] as int; final widthPx = args['widthPx'] as int; final heightPx = args['heightPx'] as int; @@ -47,12 +47,16 @@ Future _drawWidget(dynamic args) async { entry: entry, devicePixelRatio: devicePixelRatio, ); - return painter.drawWidget( + final bytes = await painter.drawWidget( widthPx: widthPx, heightPx: heightPx, outline: settings.getWidgetOutline(widgetId), shape: settings.getWidgetShape(widgetId), ); + return { + 'bytes': bytes, + 'updateOnTap': settings.getWidgetOpenPage(widgetId) == WidgetOpenPage.updateWidget, + }; } Future _getWidgetEntry(int widgetId, bool reuseEntry) async { diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index c130f009b..5f55824e1 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -113,6 +113,7 @@ class _HomePageState extends State { final page = settings.getWidgetOpenPage(widgetId); switch (page) { case WidgetOpenPage.home: + case WidgetOpenPage.updateWidget: break; case WidgetOpenPage.collection: _initialFilters = settings.getWidgetCollectionFilters(widgetId); diff --git a/plugins/aves_model/lib/src/settings/enums.dart b/plugins/aves_model/lib/src/settings/enums.dart index 1c868f99d..2508a8f3b 100644 --- a/plugins/aves_model/lib/src/settings/enums.dart +++ b/plugins/aves_model/lib/src/settings/enums.dart @@ -44,6 +44,6 @@ enum ViewerTransition { slide, parallax, fade, zoomIn, none } enum WidgetDisplayedItem { random, mostRecent } -enum WidgetOpenPage { home, collection, viewer } +enum WidgetOpenPage { home, collection, viewer, updateWidget } enum WidgetShape { rrect, circle, heart } diff --git a/untranslated.json b/untranslated.json index 7e2beb5f6..78c4c844a 100644 --- a/untranslated.json +++ b/untranslated.json @@ -178,6 +178,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -765,6 +766,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -1245,6 +1247,7 @@ "maxBrightnessAlways", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "exportEntryDialogQuality", "settingsAskEverytime", "settingsVideoPlaybackTile", @@ -1267,6 +1270,7 @@ "maxBrightnessAlways", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "exportEntryDialogQuality", "settingsAskEverytime", "settingsVideoPlaybackTile", @@ -1284,7 +1288,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "es": [ @@ -1295,7 +1300,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "eu": [ @@ -1306,7 +1312,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "fa": [ @@ -1382,6 +1389,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "rootDirectoryDescription", "otherDirectoryDescription", "restrictedAccessDialogMessage", @@ -1820,7 +1828,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "gl": [ @@ -1891,6 +1900,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -2555,6 +2565,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -3199,6 +3210,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -3674,7 +3686,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "id": [ @@ -3685,7 +3698,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "it": [ @@ -3696,7 +3710,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "ja": [ @@ -3722,6 +3737,7 @@ "subtitlePositionBottom", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "vaultBinUsageDialogMessage", "exportEntryDialogQuality", "exportEntryDialogWriteMetadata", @@ -3757,7 +3773,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "lt": [ @@ -3791,6 +3808,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "newVaultWarningDialogMessage", "newVaultDialogTitle", "configureVaultDialogTitle", @@ -4036,6 +4054,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -4521,6 +4540,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "patternDialogEnter", "patternDialogConfirm", "exportEntryDialogQuality", @@ -4567,6 +4587,7 @@ "vaultLockTypePattern", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "newVaultWarningDialogMessage", "newVaultDialogTitle", "configureVaultDialogTitle", @@ -4653,6 +4674,7 @@ "videoResumptionModeAlways", "wallpaperTargetHome", "wallpaperTargetHomeLock", + "widgetTapUpdateWidget", "setCoverDialogCustom", "newVaultWarningDialogMessage", "newVaultDialogTitle", @@ -5145,6 +5167,7 @@ "widgetOpenPageHome", "widgetOpenPageCollection", "widgetOpenPageViewer", + "widgetTapUpdateWidget", "storageVolumeDescriptionFallbackPrimary", "storageVolumeDescriptionFallbackNonPrimary", "rootDirectoryDescription", @@ -5570,7 +5593,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "pt": [ @@ -5581,7 +5605,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "ro": [ @@ -5597,6 +5622,7 @@ "maxBrightnessAlways", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "exportEntryDialogQuality", "settingsAskEverytime", "settingsVideoPlaybackTile", @@ -5619,6 +5645,7 @@ "maxBrightnessAlways", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "exportEntryDialogQuality", "statePageTitle", "stateEmpty", @@ -5668,6 +5695,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "otherDirectoryDescription", "storageAccessDialogMessage", "restrictedAccessDialogMessage", @@ -6121,6 +6149,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "newVaultWarningDialogMessage", "newVaultDialogTitle", "configureVaultDialogTitle", @@ -6501,6 +6530,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "newVaultWarningDialogMessage", "newVaultDialogTitle", "configureVaultDialogTitle", @@ -6547,7 +6577,8 @@ "editorTransformRotate", "cropAspectRatioFree", "cropAspectRatioOriginal", - "cropAspectRatioSquare" + "cropAspectRatioSquare", + "widgetTapUpdateWidget" ], "zh": [ @@ -6575,6 +6606,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "newVaultWarningDialogMessage", "newVaultDialogTitle", "configureVaultDialogTitle", @@ -6649,6 +6681,7 @@ "settingsVideoEnablePip", "videoResumptionModeNever", "videoResumptionModeAlways", + "widgetTapUpdateWidget", "newVaultWarningDialogMessage", "newVaultDialogTitle", "configureVaultDialogTitle", From 123e7c67cb28f7937c8a4eb414c853daceabce68 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 21:52:57 +0200 Subject: [PATCH 21/35] analysis: chunked work requests --- .../deckers/thibault/aves/AnalysisWorker.kt | 4 ++ .../aves/channel/calls/AnalysisHandler.kt | 37 ++++++++++++++----- lib/model/source/analysis_controller.dart | 3 ++ lib/model/source/tag.dart | 7 +++- lib/services/analysis_service.dart | 7 +++- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt b/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt index ec8ffb8ef..16e47dd16 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisWorker.kt @@ -63,6 +63,8 @@ class AnalysisWorker(context: Context, parameters: WorkerParameters) : Coroutine "start", hashMapOf( "entryIds" to inputData.getIntArray(KEY_ENTRY_IDS)?.toList(), "force" to inputData.getBoolean(KEY_FORCE, false), + "progressTotal" to inputData.getInt(KEY_PROGRESS_TOTAL, 0), + "progressOffset" to inputData.getInt(KEY_PROGRESS_OFFSET, 0), ) ) } @@ -169,5 +171,7 @@ class AnalysisWorker(context: Context, parameters: WorkerParameters) : Coroutine const val KEY_ENTRY_IDS = "entry_ids" const val KEY_FORCE = "force" + const val KEY_PROGRESS_TOTAL = "progress_total" + const val KEY_PROGRESS_OFFSET = "progress_offset" } } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt index ade45f3c5..c640d31c7 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt @@ -3,6 +3,7 @@ package deckers.thibault.aves.channel.calls import android.content.Context import androidx.core.app.ComponentActivity import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkInfo import androidx.work.WorkManager @@ -51,20 +52,35 @@ class AnalysisHandler(private val activity: ComponentActivity, private val onAna } // can be null or empty - val entryIds = call.argument>("entryIds") + val allEntryIds = call.argument>("entryIds") + val progressTotal = allEntryIds?.size ?: 0 + var progressOffset = 0 - WorkManager.getInstance(activity).enqueueUniqueWork( + // work `Data` cannot occupy more than 10240 bytes when serialized + // so we split it when we have a long list of entry IDs + val chunked = allEntryIds?.chunked(WORK_DATA_CHUNK_SIZE) ?: listOf(null) + + fun buildRequest(entryIds: List?, progressOffset: Int): OneTimeWorkRequest { + val workData = workDataOf( + AnalysisWorker.KEY_ENTRY_IDS to entryIds?.toIntArray(), + AnalysisWorker.KEY_FORCE to force, + AnalysisWorker.KEY_PROGRESS_TOTAL to progressTotal, + AnalysisWorker.KEY_PROGRESS_OFFSET to progressOffset, + ) + return OneTimeWorkRequestBuilder().apply { setInputData(workData) }.build() + } + + var work = WorkManager.getInstance(activity).beginUniqueWork( ANALYSIS_WORK_NAME, ExistingWorkPolicy.KEEP, - OneTimeWorkRequestBuilder().apply { - setInputData( - workDataOf( - AnalysisWorker.KEY_ENTRY_IDS to entryIds?.toIntArray(), - AnalysisWorker.KEY_FORCE to force, - ) - ) - }.build() + buildRequest(chunked.first(), progressOffset), ) + chunked.drop(1).forEach { entryIds -> + progressOffset += WORK_DATA_CHUNK_SIZE + work = work.then(buildRequest(entryIds, progressOffset)) + } + work.enqueue() + attachToActivity() result.success(null) } @@ -89,5 +105,6 @@ class AnalysisHandler(private val activity: ComponentActivity, private val onAna companion object { const val CHANNEL = "deckers.thibault/aves/analysis" private const val ANALYSIS_WORK_NAME = "analysis_work" + private const val WORK_DATA_CHUNK_SIZE = 1000 } } diff --git a/lib/model/source/analysis_controller.dart b/lib/model/source/analysis_controller.dart index c4e1e9e41..f6996674c 100644 --- a/lib/model/source/analysis_controller.dart +++ b/lib/model/source/analysis_controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart'; class AnalysisController { final bool canStartService, force; + final int progressTotal, progressOffset; final List? entryIds; final ValueNotifier stopSignal; @@ -9,6 +10,8 @@ class AnalysisController { this.canStartService = true, this.entryIds, this.force = false, + this.progressTotal = 0, + this.progressOffset = 0, ValueNotifier? stopSignal, }) : stopSignal = stopSignal ?? ValueNotifier(false); diff --git a/lib/model/source/tag.dart b/lib/model/source/tag.dart index bd8248b07..537ee0c53 100644 --- a/lib/model/source/tag.dart +++ b/lib/model/source/tag.dart @@ -34,8 +34,11 @@ mixin TagMixin on SourceBase { if (todo.isEmpty) return; state = SourceState.cataloguing; - var progressDone = 0; - final progressTotal = todo.length; + var progressDone = controller.progressOffset; + var progressTotal = controller.progressTotal; + if (progressTotal == 0) { + progressTotal = todo.length; + } setProgress(done: progressDone, total: progressTotal); var stopCheckCount = 0; diff --git a/lib/services/analysis_service.dart b/lib/services/analysis_service.dart index 9c656db62..071561f35 100644 --- a/lib/services/analysis_service.dart +++ b/lib/services/analysis_service.dart @@ -108,15 +108,20 @@ class Analyzer { Future start(dynamic args) async { List? entryIds; var force = false; + var progressTotal = 0, progressOffset = 0; if (args is Map) { entryIds = (args['entryIds'] as List?)?.cast(); force = args['force'] ?? false; + progressTotal = args['progressTotal']; + progressOffset = args['progressOffset']; } - debugPrint('$runtimeType start for ${entryIds?.length ?? 'all'} entries'); + debugPrint('$runtimeType start for ${entryIds?.length ?? 'all'} entries, at $progressOffset/$progressTotal'); _controller = AnalysisController( canStartService: false, entryIds: entryIds, force: force, + progressTotal: progressTotal, + progressOffset: progressOffset, stopSignal: ValueNotifier(false), ); From 1a89a28866dedbd4a6a6b52b19f17db26b84b4b4 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 22:59:03 +0200 Subject: [PATCH 22/35] fixed crash when cataloguing PSD with large XMP --- CHANGELOG.md | 6 +- .../aves/metadata/metadataextractor/Helper.kt | 9 +- .../metadataextractor/SafePhotoshopReader.kt | 116 ++++++++++++++++++ .../SafePngMetadataReader.kt | 2 +- .../SafePsdMetadataReader.kt | 13 ++ .../metadataextractor/SafePsdReader.kt | 93 ++++++++++++++ .../metadataextractor/SafeXmpReader.kt | 9 +- 7 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePhotoshopReader.kt create mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdMetadataReader.kt create mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdReader.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c27ee26a..38ae27c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ All notable changes to this project will be documented in this file. - remember whether to show the title filter when picking albums - upgraded Flutter to stable v3.10.0 +### Fixed + +- crash when cataloguing PSD with large XMP + ## [v1.8.6] - 2023-04-30 ### Added @@ -859,7 +863,7 @@ All notable changes to this project will be documented in this file. ### Fixed -- fixed crash when cataloguing large MP4/PSD +- crash when cataloguing large MP4/PSD - prevent videos playing in the background when quickly switching entries ## [v1.4.0] - 2021-04-16 diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt index ed247f4cf..2c71d16ed 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt @@ -67,14 +67,16 @@ object Helper { val metadata = when (fileType) { FileType.Jpeg -> safeReadJpeg(inputStream) + FileType.Mp4 -> safeReadMp4(inputStream) FileType.Png -> safeReadPng(inputStream) + FileType.Psd -> safeReadPsd(inputStream) FileType.Tiff, FileType.Arw, FileType.Cr2, FileType.Nef, FileType.Orf, FileType.Rw2 -> safeReadTiff(inputStream) - FileType.Mp4 -> safeReadMp4(inputStream) + else -> ImageMetadataReader.readMetadata(inputStream, safeReadStreamLength, fileType) } @@ -100,6 +102,10 @@ object Helper { return SafePngMetadataReader.readMetadata(input) } + private fun safeReadPsd(input: InputStream): com.drew.metadata.Metadata { + return SafePsdMetadataReader.readMetadata(input) + } + @Throws(IOException::class, TiffProcessingException::class) fun safeReadTiff(input: InputStream): com.drew.metadata.Metadata { val reader = RandomAccessStreamReader(input, RandomAccessStreamReader.DEFAULT_CHUNK_LENGTH, safeReadStreamLength) @@ -262,6 +268,7 @@ object Helper { ExifReader().extract(ByteArrayReader(dataBytes), metadata, ExifReader.JPEG_SEGMENT_PREAMBLE.length) } } + PNG_RAW_PROFILE_IPTC -> { val start = dataBytes.indexOf(Metadata.IPTC_MARKER_BYTE) if (start != -1) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePhotoshopReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePhotoshopReader.kt new file mode 100644 index 000000000..d312569bd --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePhotoshopReader.kt @@ -0,0 +1,116 @@ +package deckers.thibault.aves.metadata.metadataextractor + +import com.drew.imaging.ImageProcessingException +import com.drew.lang.ByteArrayReader +import com.drew.lang.SequentialByteArrayReader +import com.drew.lang.SequentialReader +import com.drew.metadata.Directory +import com.drew.metadata.Metadata +import com.drew.metadata.exif.ExifReader +import com.drew.metadata.icc.IccReader +import com.drew.metadata.iptc.IptcReader +import com.drew.metadata.photoshop.PhotoshopDirectory +import com.drew.metadata.photoshop.PhotoshopReader +import java.util.Arrays + +// adapted from `PhotoshopReader` to prevent OOM from reading large XMP +// as of `metadata-extractor` v2.18.0, there is no way to customize the Photoshop reader +// without copying the whole `extract` function +class SafePhotoshopReader : PhotoshopReader() { + override fun extract(reader: SequentialReader, length: Int, metadata: Metadata, parentDirectory: Directory?) { + val directory = PhotoshopDirectory() + metadata.addDirectory(directory) + + if (parentDirectory != null) { + directory.parent = parentDirectory + } + + // Data contains a sequence of Image Resource Blocks (IRBs): + // + // 4 bytes - Signature; mostly "8BIM" but "PHUT", "AgHg" and "DCSR" are also found + // 2 bytes - Resource identifier + // String - Pascal string, padded to make length even + // 4 bytes - Size of resource data which follows + // Data - The resource data, padded to make size even + // + // http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037504 + + var pos = 0 + var clippingPathCount = 0 + while (pos < length) { + try { + // 4 bytes for the signature ("8BIM", "PHUT", etc.) + val signature = reader.getString(4) + pos += 4 + + // 2 bytes for the resource identifier (tag type). + val tagType = reader.uInt16 // segment type + pos += 2 + + // A variable number of bytes holding a pascal string (two leading bytes for length). + var descriptionLength = reader.uInt8.toInt() + pos += 1 + // Some basic bounds checking + if (descriptionLength < 0 || descriptionLength + pos > length) { + throw ImageProcessingException("Invalid string length") + } + + // Get name (important for paths) + val description = StringBuilder() + descriptionLength += pos + // Loop through each byte and append to string + while (pos < descriptionLength) { + description.append(Char(reader.uInt8.toUShort())) + pos++ + } + + // The number of bytes is padded with a trailing zero, if needed, to make the size even. + if (pos % 2 != 0) { + reader.skip(1) + pos++ + } + + // 4 bytes for the size of the resource data that follows. + val byteCount = reader.int32 + pos += 4 + // The resource data. + var tagBytes = reader.getBytes(byteCount) + pos += byteCount + // The number of bytes is padded with a trailing zero, if needed, to make the size even. + if (pos % 2 != 0) { + reader.skip(1) + pos++ + } + + if (signature == "8BIM") { + when (tagType) { + PhotoshopDirectory.TAG_IPTC -> IptcReader().extract(SequentialByteArrayReader(tagBytes), metadata, tagBytes.size.toLong(), directory) + PhotoshopDirectory.TAG_ICC_PROFILE_BYTES -> IccReader().extract(ByteArrayReader(tagBytes), metadata, directory) + PhotoshopDirectory.TAG_EXIF_DATA_1, + PhotoshopDirectory.TAG_EXIF_DATA_3 -> ExifReader().extract(ByteArrayReader(tagBytes), metadata, 0, directory) + + PhotoshopDirectory.TAG_XMP_DATA -> SafeXmpReader().extract(tagBytes, metadata, directory) + in 0x07D0..0x0BB6 -> { + clippingPathCount++ + tagBytes = Arrays.copyOf(tagBytes, tagBytes.size + description.length + 1) + // Append description(name) to end of byte array with 1 byte before the description representing the length + for (i in tagBytes.size - description.length - 1 until tagBytes.size) { + if (i % (tagBytes.size - description.length - 1 + description.length) == 0) tagBytes[i] = description.length.toByte() else tagBytes[i] = description[i - (tagBytes.size - description.length - 1)].code.toByte() + } +// PhotoshopDirectory._tagNameMap[0x07CF + clippingPathCount] = "Path Info $clippingPathCount" + directory.setByteArray(0x07CF + clippingPathCount, tagBytes) + } + + else -> directory.setByteArray(tagType, tagBytes) + } +// if (tagType in 0x0fa0..0x1387) { +// PhotoshopDirectory._tagNameMap[tagType] = String.format("Plug-in %d Data", tagType - 0x0fa0 + 1) +// } + } + } catch (ex: Exception) { + directory.addError(ex.message) + return + } + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt index 1012a6477..d8b5452a4 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt @@ -34,7 +34,7 @@ import java.io.InputStream import java.util.zip.InflaterInputStream import java.util.zip.ZipException -// adapted from `PngMetadataReader` to prevent reading OOM from large chunks +// adapted from `PngMetadataReader` to prevent OOM from reading large chunks // as of `metadata-extractor` v2.18.0, there is no way to customize the reader // without copying `desiredChunkTypes` and the whole `processChunk` function object SafePngMetadataReader { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdMetadataReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdMetadataReader.kt new file mode 100644 index 000000000..6f93a23f8 --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdMetadataReader.kt @@ -0,0 +1,13 @@ +package deckers.thibault.aves.metadata.metadataextractor + +import com.drew.lang.StreamReader +import com.drew.metadata.Metadata +import java.io.InputStream + +object SafePsdMetadataReader { + fun readMetadata(inputStream: InputStream): Metadata { + val metadata = Metadata() + SafePsdReader().extract(StreamReader(inputStream), metadata) + return metadata + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdReader.kt new file mode 100644 index 000000000..91dcf8444 --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePsdReader.kt @@ -0,0 +1,93 @@ +package deckers.thibault.aves.metadata.metadataextractor + +import com.drew.lang.SequentialReader +import com.drew.metadata.Metadata +import com.drew.metadata.photoshop.PsdHeaderDirectory +import java.io.IOException + +// adapted from `PsdReader` to prevent OOM from reading large XMP +// as of `metadata-extractor` v2.18.0, there is no way to customize the Photoshop reader +// without copying the whole `extract` function +class SafePsdReader { + fun extract(reader: SequentialReader, metadata: Metadata) { + val directory = PsdHeaderDirectory() + metadata.addDirectory(directory) + + // FILE HEADER SECTION + + try { + val signature = reader.int32 + if (signature != 0x38425053) // "8BPS" + { + directory.addError("Invalid PSD file signature") + return + } + + val version = reader.uInt16 + if (version != 1 && version != 2) { + directory.addError("Invalid PSD file version (must be 1 or 2)") + return + } + + // 6 reserved bytes are skipped here. They should be zero. + reader.skip(6) + + val channelCount = reader.uInt16 + directory.setInt(PsdHeaderDirectory.TAG_CHANNEL_COUNT, channelCount) + + // even though this is probably an unsigned int, the max height in practice is 300,000 + val imageHeight = reader.int32 + directory.setInt(PsdHeaderDirectory.TAG_IMAGE_HEIGHT, imageHeight) + + // even though this is probably an unsigned int, the max width in practice is 300,000 + val imageWidth = reader.int32 + directory.setInt(PsdHeaderDirectory.TAG_IMAGE_WIDTH, imageWidth) + + val bitsPerChannel = reader.uInt16 + directory.setInt(PsdHeaderDirectory.TAG_BITS_PER_CHANNEL, bitsPerChannel) + + val colorMode = reader.uInt16 + directory.setInt(PsdHeaderDirectory.TAG_COLOR_MODE, colorMode) + } catch (e: IOException) { + directory.addError("Unable to read PSD header") + return + } + + // COLOR MODE DATA SECTION + + try { + val sectionLength = reader.uInt32 + + /* + * Only indexed color and duotone (see the mode field in the File header section) have color mode data. + * For all other modes, this section is just the 4-byte length field, which is set to zero. + * + * Indexed color images: length is 768; color data contains the color table for the image, + * in non-interleaved order. + * Duotone images: color data contains the duotone specification (the format of which is not documented). + * Other applications that read Photoshop files can treat a duotone image as a gray image, + * and just preserve the contents of the duotone information when reading and writing the + * file. + */ + reader.skip(sectionLength) + } catch (e: IOException) { + return + } + + // IMAGE RESOURCES SECTION + + try { + val sectionLength = reader.uInt32 + + assert(sectionLength <= Int.MAX_VALUE) + + SafePhotoshopReader().extract(reader, sectionLength.toInt(), metadata) + } catch (e: IOException) { + // ignore + } + + // LAYER AND MASK INFORMATION SECTION (skipped) + + // IMAGE DATA SECTION (skipped) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt index 8eb67202e..e36402907 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt @@ -61,12 +61,19 @@ class SafeXmpReader : XmpReader() { } // adapted from `XmpReader` to provide different parsing options + // and to detect large XMP when extracted directly (e.g. from Photoshop reader) override fun extract(xmpBytes: ByteArray, offset: Int, length: Int, metadata: Metadata, parentDirectory: Directory?) { + val totalSize = xmpBytes.size + if (totalSize > SEGMENT_TYPE_SIZE_DANGER_THRESHOLD) { + logError(metadata, totalSize) + return + } + val directory = XmpDirectory() if (parentDirectory != null) directory.parent = parentDirectory try { - val xmpMeta: XMPMeta = if (offset == 0 && length == xmpBytes.size) { + val xmpMeta: XMPMeta = if (offset == 0 && length == totalSize) { XMPMetaFactory.parseFromBuffer(xmpBytes, PARSE_OPTIONS) } else { val buffer = ByteBuffer(xmpBytes, offset, length) From 6968e673c7a4acff967f8ccdd049fa5df31758d9 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 14 May 2023 23:08:30 +0200 Subject: [PATCH 23/35] fixed crash when cataloguing large HEIF --- CHANGELOG.md | 13 +++++++------ .../deckers/thibault/aves/metadata/Metadata.kt | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38ae27c17..a1392714b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. ### Fixed - crash when cataloguing PSD with large XMP +- crash when cataloguing large HEIF ## [v1.8.6] - 2023-04-30 @@ -347,8 +348,8 @@ All notable changes to this project will be documented in this file. - Albums / Countries / Tags: live title filter - option to hide confirmation message after moving items to the bin - Collection / Info: edit description via Exif / IPTC / XMP -- Info: read XMP from HEIC on Android >=11 -- Collection: support HEIC motion photos on Android >=11 +- Info: read XMP from HEIF on Android >=11 +- Collection: support HEIF motion photos on Android >=11 - Search: `recently added` filter - Dutch translation (thanks Martijn Fabrie, Koen Koppens) @@ -759,7 +760,7 @@ All notable changes to this project will be documented in this file. ### Fixed - auto album identification and naming -- opening HEIC images from downloads content URI on Android >=11 +- opening HEIF images from downloads content URI on Android >=11 ## [v1.4.7] - 2021-08-06 [YANKED] @@ -854,7 +855,7 @@ All notable changes to this project will be documented in this file. ### Added - Motion photo support -- Viewer: play videos in multi-track HEIC +- Viewer: play videos in multi-track HEIF - Handle share intent ### Changed @@ -981,7 +982,7 @@ All notable changes to this project will be documented in this file. ### Added -Collection: identify multipage TIFF & multitrack HEIC/HEIF Viewer: support for multipage TIFF +Collection: identify multipage TIFF & multitrack HEIF Viewer: support for multipage TIFF Viewer: support for cropped panoramas Albums: grouping options ### Changed @@ -1092,7 +1093,7 @@ upgraded libtiff to 4.2.0 for TIFF decoding - Viewer: leave when the loaded item is deleted and it is the last one - Viewer: refresh the viewer overlay and info page when the loaded image is modified -- Info: prevent reporting a "Media" section for images other than HEIC/HEIF +- Info: prevent reporting a "Media" section for images other than HEIF - Fixed opening items shared via a "file" media content URI ### Removed diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt index 699dc4009..c8522a6cf 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt @@ -134,6 +134,8 @@ object Metadata { private fun getSafeUri(context: Context, uri: Uri, mimeType: String, sizeBytes: Long?): Uri { return when (mimeType) { // formats known to yield OOM for large files + MimeTypes.HEIC, + MimeTypes.HEIF, MimeTypes.MP4, MimeTypes.PSD_VND, MimeTypes.PSD_X, From 6172a601c63c8dd53ee063a8f1ce64decf35a7e0 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 15 May 2023 20:07:32 +0200 Subject: [PATCH 24/35] viewer: option for random transition --- CHANGELOG.md | 1 + .../settings/enums/viewer_transition.dart | 43 +++++++++++++++++++ lib/view/src/settings/enums.dart | 2 + .../aves_model/lib/src/settings/enums.dart | 2 +- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1392714b..d6763f3ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - support for animated PNG - Info: added day filter with item date - Widget: option to update image on tap +- Slideshow / Screen saver: option for random transition ### Changed diff --git a/lib/model/settings/enums/viewer_transition.dart b/lib/model/settings/enums/viewer_transition.dart index b97b5b77c..81aefe62a 100644 --- a/lib/model/settings/enums/viewer_transition.dart +++ b/lib/model/settings/enums/viewer_transition.dart @@ -1,5 +1,8 @@ +import 'dart:math'; + import 'package:aves/widgets/viewer/controls/controller.dart'; import 'package:aves_model/aves_model.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart'; extension ExtraViewerTransition on ViewerTransition { @@ -15,6 +18,46 @@ extension ExtraViewerTransition on ViewerTransition { return PageTransitionEffects.fade(pageController, index, zoomIn: true); case ViewerTransition.none: return PageTransitionEffects.none(pageController, index); + case ViewerTransition.random: + return _ViewerTransitionRandomizer.getBuilder(pageController, index); } } } + +class _ViewerTransitionRandomizer { + static const options = [ + ViewerTransition.slide, + ViewerTransition.parallax, + ViewerTransition.fade, + ViewerTransition.zoomIn, + ]; + + static final List<(int, ViewerTransition)> _indexedTransitions = []; + + static TransitionBuilder getBuilder( + PageController pageController, + int index, + ) => + (context, child) { + final negative = pageController.hasClients && pageController.position.haveDimensions && (pageController.page! - index).isNegative; + final transition = _getTransition(negative ? index - 1 : index); + final builder = transition.builder(pageController, index); + return builder(context, child); + }; + + static ViewerTransition _getTransition(int transitionIndex) { + var indexedTransition = _indexedTransitions.firstWhereOrNull((v) => v.$1 == transitionIndex); + if (indexedTransition != null) { + _indexedTransitions.remove(indexedTransition); + } else { + indexedTransition = (transitionIndex, options[Random().nextInt(options.length)]); + } + _indexedTransitions.insert(0, indexedTransition); + while (_indexedTransitions.length > 3) { + _indexedTransitions.removeLast(); + } + + final (_, transition) = indexedTransition; + return transition; + } +} diff --git a/lib/view/src/settings/enums.dart b/lib/view/src/settings/enums.dart index dedfc4018..8b7abc0c5 100644 --- a/lib/view/src/settings/enums.dart +++ b/lib/view/src/settings/enums.dart @@ -251,6 +251,8 @@ extension ExtraViewerTransitionView on ViewerTransition { return context.l10n.viewerTransitionZoomIn; case ViewerTransition.none: return context.l10n.viewerTransitionNone; + case ViewerTransition.random: + return context.l10n.widgetDisplayedItemRandom; } } } diff --git a/plugins/aves_model/lib/src/settings/enums.dart b/plugins/aves_model/lib/src/settings/enums.dart index 2508a8f3b..3f327feca 100644 --- a/plugins/aves_model/lib/src/settings/enums.dart +++ b/plugins/aves_model/lib/src/settings/enums.dart @@ -40,7 +40,7 @@ enum VideoLoopMode { never, shortOnly, always } enum VideoResumptionMode { never, ask, always } -enum ViewerTransition { slide, parallax, fade, zoomIn, none } +enum ViewerTransition { slide, parallax, fade, zoomIn, none, random } enum WidgetDisplayedItem { random, mostRecent } From 01e1058f1a43e3b974fe5048436acd35c20926fe Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Thu, 18 May 2023 13:24:59 +0200 Subject: [PATCH 25/35] upgraded Flutter to stable v3.10.1 --- .flutter | 2 +- CHANGELOG.md | 2 +- plugins/aves_report_crashlytics/pubspec.lock | 16 +++---- pubspec.lock | 47 ++++++++++---------- pubspec.yaml | 8 +--- shaders.sksl.json | 2 +- 6 files changed, 35 insertions(+), 42 deletions(-) diff --git a/.flutter b/.flutter index 84a1e904f..d3d8effc6 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit 84a1e904f44f9b0e9c4510138010edcc653163f8 +Subproject commit d3d8effc686d73e0114d71abdcccef63fa1f25d2 diff --git a/CHANGELOG.md b/CHANGELOG.md index d6763f3ea..ab2f65147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ All notable changes to this project will be documented in this file. - keep showing empty albums if are pinned - remember whether to show the title filter when picking albums -- upgraded Flutter to stable v3.10.0 +- upgraded Flutter to stable v3.10.1 ### Fixed diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index 716168085..c16f93235 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: d687576bb973e8d2539d0b4615d985336269a0dbe1b3984e937fd22d31406fb8 + sha256: "8eb354cb8ebed8a9fdf63699d15deff533bc133128898afaf754926b57d611b6" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.1" async: dependency: transitive description: @@ -68,10 +68,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "4491238f4fddc885bc994e304a035eb8aba2c935816b2c0b31d87f3ec6e96682" + sha256: "250678b816279b3240c3a33e1f76bf712c00718f1fbeffc85873a5da8c077379" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.0" firebase_core_platform_interface: dependency: transitive description: @@ -92,18 +92,18 @@ packages: dependency: "direct main" description: name: firebase_crashlytics - sha256: cc6cab05d4de3257408c167ec1e2e410f21c0764aea22f78481314496a1cc4ca + sha256: "0d74cca3085f144f99aa4bd82cc4d33280d4cb72bac0b733cbf97c2d7d126df8" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: b3b6017045866b981b566896a0de6114181bf9e91465221f2e89996f47a160b4 + sha256: "13880033d5f2055f53bcda28024e16607b8400445a425f86732c1935da9260db" url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.6.1" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.lock b/pubspec.lock index 2d2595325..977c2c130 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: d687576bb973e8d2539d0b4615d985336269a0dbe1b3984e937fd22d31406fb8 + sha256: "8eb354cb8ebed8a9fdf63699d15deff533bc133128898afaf754926b57d611b6" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.1" analyzer: dependency: transitive description: @@ -269,7 +269,7 @@ packages: description: path: "packages/device_info_plus/device_info_plus" ref: main - resolved-ref: e8d3b445ce52012456126a3844ddb49b92c5c850 + resolved-ref: "57d9c8845edfc81fdbabcef9eb1d1ca450e62e7d" url: "https://github.com/fluttercommunity/plus_plugins.git" source: git version: "9.0.0" @@ -285,10 +285,10 @@ packages: dependency: "direct main" description: name: dynamic_color - sha256: "1ffc93e3794696af22ff11d75adcd6f5fb67b45bd54f9d8735a5d1cf8c013841" + sha256: "74dff1435a695887ca64899b8990004f8d1232b0e84bfc4faa1fdda7c6f57cc1" url: "https://pub.dev" source: hosted - version: "1.6.4" + version: "1.6.5" equatable: dependency: "direct main" description: @@ -351,10 +351,10 @@ packages: dependency: transitive description: name: firebase_core - sha256: "4491238f4fddc885bc994e304a035eb8aba2c935816b2c0b31d87f3ec6e96682" + sha256: "250678b816279b3240c3a33e1f76bf712c00718f1fbeffc85873a5da8c077379" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.0" firebase_core_platform_interface: dependency: transitive description: @@ -375,18 +375,18 @@ packages: dependency: transitive description: name: firebase_crashlytics - sha256: cc6cab05d4de3257408c167ec1e2e410f21c0764aea22f78481314496a1cc4ca + sha256: "0d74cca3085f144f99aa4bd82cc4d33280d4cb72bac0b733cbf97c2d7d126df8" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: b3b6017045866b981b566896a0de6114181bf9e91465221f2e89996f47a160b4 + sha256: "13880033d5f2055f53bcda28024e16607b8400445a425f86732c1935da9260db" url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.6.1" flex_color_picker: dependency: "direct main" description: @@ -841,7 +841,7 @@ packages: description: path: "packages/package_info_plus/package_info_plus" ref: main - resolved-ref: e8d3b445ce52012456126a3844ddb49b92c5c850 + resolved-ref: "57d9c8845edfc81fdbabcef9eb1d1ca450e62e7d" url: "https://github.com/fluttercommunity/plus_plugins.git" source: git version: "4.0.0" @@ -951,14 +951,13 @@ packages: source: hosted version: "10.2.0" permission_handler_android: - dependency: "direct overridden" + dependency: transitive description: - path: permission_handler_android - ref: agp8-compat - resolved-ref: ad409917f0db1b1ad6a2c74d3c6b3b35f331a81e - url: "https://github.com/deckerst/flutter-permission-handler.git" - source: git - version: "10.2.0" + name: permission_handler_android + sha256: d8cc6a62ded6d0f49c6eac337e080b066ee3bce4d405bd9439a61e1f1927bfe8 + url: "https://pub.dev" + source: hosted + version: "10.2.1" permission_handler_apple: dependency: transitive description: @@ -1264,10 +1263,10 @@ packages: dependency: "direct main" description: name: sqflite - sha256: "3a82c9a216b46b88617e3714dd74227eaca20c501c4abcc213e56db26b9caa00" + sha256: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9 url: "https://pub.dev" source: hosted - version: "2.2.8+2" + version: "2.2.8+4" sqflite_common: dependency: transitive description: @@ -1409,10 +1408,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "7aac14be5f4731b923cc697ae2d42043945076cd0dbb8806baecc92c1dc88891" + sha256: "1a5848f598acc5b7d8f7c18b8cb834ab667e59a13edc3c93e9d09cf38cc6bc87" url: "https://pub.dev" source: hosted - version: "6.0.33" + version: "6.0.34" url_launcher_ios: dependency: transitive description: @@ -1568,4 +1567,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.0.0 <4.0.0" - flutter: ">=3.10.0" + flutter: ">=3.10.1" diff --git a/pubspec.yaml b/pubspec.yaml index 218d08138..b0918bbff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,7 +13,7 @@ publish_to: none environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper - flutter: 3.10.0 + flutter: 3.10.1 sdk: ">=3.0.0 <4.0.0" # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor @@ -147,12 +147,6 @@ dependency_overrides: url: https://github.com/deckerst/flutter-google-api-availability.git ref: agp8-compat path: google_api_availability_android - # cf https://github.com/Baseflow/flutter-permission-handler/pull/1039 - permission_handler_android: - git: - url: https://github.com/deckerst/flutter-permission-handler.git - ref: agp8-compat - path: permission_handler_android # cf https://github.com/kurenai7968/volume_controller/pull/19 volume_controller: git: diff --git a/shaders.sksl.json b/shaders.sksl.json index 5e5087ff8..a27e6de73 100644 --- a/shaders.sksl.json +++ b/shaders.sksl.json @@ -1 +1 @@ -{"platform":"android","name":"SM G970N","engineRevision":"d44b5a94c976fbb65815374f61ab5392a220b084","data":{"DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAHSADQAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAQAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQHEB4XIQAQAADQAAAABAAAAAAABAEMVDOMCJKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABRBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSA/IDEgOiAwKSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MxX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IHhfcGx1c18xPXZhcmNjb29yZF9TMC54LCB5PXZhcmNjb29yZF9TMC55OwoJaGFsZiBjb3ZlcmFnZTsKCWlmICgwID09IHhfcGx1c18xKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoeSk7Cgl9CgllbHNlIAoJewoJCWZsb2F0IGZuID0geF9wbHVzXzEgKiAoeF9wbHVzXzEgLSAyKTsKCQlmbiA9IGZtYSh5LHksIGZuKTsKCQlmbG9hdCBmbndpZHRoID0gZndpZHRoKGZuKTsKCQljb3ZlcmFnZSA9IC41IC0gaGFsZihmbi9mbndpZHRoKTsKCQljb3ZlcmFnZSA9IGNsYW1wKGNvdmVyYWdlLCAwLCAxKTsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAFBQATAAAAAAFAAMAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAABABAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgRWxsaXB0aWNhbFJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJZmxvYXQyIFogPSBkeHkgKiB1aW52UmFkaWlYWV9TMS54eTsKCWhhbGYgaW1wbGljaXQgPSBoYWxmKGRvdChaLCBkeHkpIC0gMS4wKTsKCWhhbGYgZ3JhZF9kb3QgPSBoYWxmKDQuMCAqIGRvdChaLCBaKSk7CglncmFkX2RvdCA9IG1heChncmFkX2RvdCwgMS4wZS00KTsKCWhhbGYgYXBwcm94X2Rpc3QgPSBpbXBsaWNpdCAqIGhhbGYoaW52ZXJzZXNxcnQoZ3JhZF9kb3QpKTsKCWhhbGYgYWxwaGEgPSBjbGFtcCgwLjUgKyBhcHByb3hfZGlzdCwgMC4wLCAxLjApOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRWxsaXB0aWNhbFJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAA7AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAAYQADAAAEAFEURUKQKAAAYAAAAAAAAIAAAABSCICWKY2FAEAAAMAAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB+BQAAY29uc3QgaW50IGtGaWxsQldfUzFfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzFfYzA7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgUmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMV9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzFfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MxX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACfAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEaXN0YW5jZUZpZWxkUGF0aAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQyIHV2ID0gdlRleHR1cmVDb29yZHNfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLnJycnI7Cgl9CgloYWxmIGRpc3RhbmNlID0gNy45Njg3NSoodGV4Q29sb3IuciAtIDAuNTAxOTYwNzg0MzEpOwoJaGFsZiBhZndpZHRoOwoJYWZ3aWR0aCA9IGFicygwLjY1KmhhbGYoZEZkeCh2SW50VGV4dHVyZUNvb3Jkc19TMC54KSkpOwoJaGFsZiB2YWwgPSBzbW9vdGhzdGVwKC1hZndpZHRoLCBhZndpZHRoLCBkaXN0YW5jZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KHZhbCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"CgAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADdAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIG91dHB1dENvbG9yX1MwKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEADZABYAAAIAAAAAACQAGAAAAAQAAAAAAAQQG":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAADUAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAAAAAAQFV5W6JEAAAAAYAAAABQEZ2AKAWAQAABAL6SYKDYAAAACAAAAAAQEGIAAAAACAWTWL3EYAAAADAAAAACADHIJJCYCAAAEAP2LRIPAAAAAIAAAAAAABTALI3F5SOAIAABQAAAAAABTUEUZMBAAAAAH5FYUXQAAAAAAAEAAAAAZMRGOQCQFQEAAAAAAAAAGARL2LXJHAAEAAAAAEAAAABSCQX5FQUHQAAAAAAAAAACAA4AAAABAACAAAACCAYAAAAA":"CgAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc182X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAMMHAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwpoYWxmNCBTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IF9jb29yZHM7CglyZXR1cm4gaGFsZjQobWl4KHVzdGFydF9TMV9jMF9jMF9jMCwgdWVuZF9TMV9jMF9jMF9jMCwgaGFsZihfdG1wXzFfY29vcmRzLngpKSk7Cn0KaGFsZjQgTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfM19jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKCXJldHVybiBoYWxmNChoYWxmNChoYWxmKF90bXBfM19jb29yZHMueCkgKyAxZS0wNSwgMS4wLCAwLjAsIDAuMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgdCA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShfdG1wXzRfaW5Db2xvcik7CgloYWxmNCBvdXRDb2xvcjsKCWlmICghYm9vbChpbnQoMSkpICYmIHQueSA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSBoYWxmNCgwLjApOwoJfQoJZWxzZSBpZiAodC54IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IHVsZWZ0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIGlmICh0LnggPiAxLjApIAoJewoJCW91dENvbG9yID0gdXJpZ2h0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIAoJewoJCW91dENvbG9yID0gU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgY29sb3JfeGZvcm1fUzFfYzAoZmxvYXQ0IGNvbG9yKSAKewoJY29sb3IucmdiICo9IGNvbG9yLmE7CglyZXR1cm4gaGFsZjQoY29sb3IpOwp9CmhhbGY0IENvbG9yU3BhY2VYZm9ybV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gY29sb3JfeGZvcm1fUzFfYzAoQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCkpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ29sb3JTcGFjZVhmb3JtX1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gKGhhbGY0KDEuMCkgLSBvdXRwdXRfUzEpICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAD2AAAAAAQAVSWGRIBAAADAAAAACAAAAAAQCGEIQOZLBIQAAAABQAAAAAAAAAAAAFAAMAAAABAAAAAAABBAMAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAARQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAACU53QJEKAAAAAAMAAAAAIAAAAAAGIRDFB2XASAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAC4BAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjbGVfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41ID8gMSA6IDApKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShfc3JjLCBDaXJjbGVfUzFfYzAoX3NyYykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQDAAAAAAAAAEAAAABJGQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAO4EAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFs0XTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgU21vb3RoX1MxX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIGNvb3JkLCBoYWxmMiBvZmZzZXRBbmRLZXJuZWwpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCwgKGNvb3JkICsgb2Zmc2V0QW5kS2VybmVsLnggKiB1SW5jcmVtZW50X1MxX2MwKSkgKiBvZmZzZXRBbmRLZXJuZWwueTsKfQpoYWxmNCBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IGNvbG9yID0gaGFsZjQoMCk7CglmbG9hdDIgY29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZvciAoaW50IGk9MDsgaTw0OyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAIBAIAAAABLCIIBAAAAABAEGABBAMAACAIAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAADJAwAAdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoTWF0cml4RWZmZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvbG9yX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAANAAAAALHCKLMRAAAAAAAAABAAAAAGJBCFLQVBWAQAAAAAAQAAAAAMACQCAACAAAAA2AIBAEIAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAeAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1Y2lyY2xlRGF0YV9TMV9jMDsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBDaXJjbGVCbHVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjIgdmVjID0gaGFsZjIoKHNrX0ZyYWdDb29yZC54eSAtIGZsb2F0Mih1Y2lyY2xlRGF0YV9TMV9jMC54eSkpICogZmxvYXQodWNpcmNsZURhdGFfUzFfYzAudykpOwoJaGFsZiBkaXN0ID0gbGVuZ3RoKHZlYykgKyAoMC41IC0gdWNpcmNsZURhdGFfUzFfYzAueikgKiB1Y2lyY2xlRGF0YV9TMV9jMC53OwoJcmV0dXJuIGhhbGY0KE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgZmxvYXQyKGhhbGYyKGRpc3QsIDAuNSkpKS53d3d3KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKENpcmNsZUJsdXJfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAIAAEAAAABJYQAAAAAQAAIAAAAAWCBACAABAAAAANAECAZAAEAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IGNsYW1wKHN1YnNldENvb3JkLngsIHVjbGFtcF9TMV9jMF9jMF9jMC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueik7CgljbGFtcGVkQ29vcmQueSA9IHN1YnNldENvb3JkLnk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAAAAEAAAABJYQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAPAEAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxM107CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IFNtb290aF9TMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBjb29yZCwgaGFsZjIgb2Zmc2V0QW5kS2VybmVsKSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfaW5wdXQsIChjb29yZCArIG9mZnNldEFuZEtlcm5lbC54ICogdUluY3JlbWVudF9TMV9jMCkpICogb2Zmc2V0QW5kS2VybmVsLnk7Cn0KaGFsZjQgR2F1c3NpYW5Db252b2x1dGlvbl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBjb2xvciA9IGhhbGY0KDApOwoJZmxvYXQyIGNvb3JkID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7Cglmb3IgKGludCBpPTA7IGk8MTM7ICsraSkgCgl7CgkJY29sb3IgKz0gU21vb3RoX1MxX2MwKF9pbnB1dCwgY29vcmQsIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldKTsKCX0KCXJldHVybiBjb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAHMCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwKS5ycnJyOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAAAAIAAAABLAIABAAAAABAEGABBAMAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAC2AgAAdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKE1hdHJpeEVmZmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb2xvcl9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAsQEAAHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAE0DAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMC54eSwgdWNsYW1wX1MxX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzAueCwgdWNsYW1wX1MxX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"CgAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAALAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBSUmVjdFNoYWRvdwoJaGFsZjMgc2hhZG93UGFyYW1zOwoJc2hhZG93UGFyYW1zID0gdmluU2hhZG93UGFyYW1zX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZiBkID0gbGVuZ3RoKHNoYWRvd1BhcmFtcy54eSk7CglmbG9hdDIgdXYgPSBmbG9hdDIoc2hhZG93UGFyYW1zLnogKiAoMS4wIC0gZCksIDAuNSk7CgloYWxmIGZhY3RvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLjAwMHIuYTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZmFjdG9yKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAOAAAAaW5TaGFkb3dQYXJhbXMAAAAAAAA=","DASAAAAAQAAWAABAYAAQBYH7777Z6QQBAEAAAAAAEAAAAAAAEBSAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADgAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCk7Cgl9CglvdXRwdXRDb2xvcl9TMCA9IG91dHB1dENvbG9yX1MwICogdGV4Q29sb3I7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBQU7BTXIAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"CgAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAArAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAABAEAAAABJYQAAAAAACAIAAAAAWCBAAAIBAAAAANAECAZAAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IHN1YnNldENvb3JkLng7CgljbGFtcGVkQ29vcmQueSA9IGNsYW1wKHN1YnNldENvb3JkLnksIHVjbGFtcF9TMV9jMF9jMF9jMC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAudyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACsAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"CgAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQAAEAQAAAAGQCBAMQAAAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzAueSwgdWNsYW1wX1MxX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAKPABAAAAAAB2AAAAAAACAAAAAEBSAAAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACbBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBFbGxpcHRpY2FsUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CglmbG9hdDIgWiA9IGR4eSAqIHVpbnZSYWRpaVhZX1MxLnh5OwoJaGFsZiBpbXBsaWNpdCA9IGhhbGYoZG90KFosIGR4eSkgLSAxLjApOwoJaGFsZiBncmFkX2RvdCA9IGhhbGYoNC4wICogZG90KFosIFopKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjBlLTQpOwoJaGFsZiBhcHByb3hfZGlzdCA9IGltcGxpY2l0ICogaGFsZihpbnZlcnNlc3FydChncmFkX2RvdCkpOwoJaGFsZiBhbHBoYSA9IGNsYW1wKDAuNSArIGFwcHJveF9kaXN0LCAwLjAsIDEuMCk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEVsbGlwdGljYWxSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADgAAAHJhZGlpX3NlbGVjdG9yAAAZAAAAY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cwAAABUAAABhYV9ibG9hdF9hbmRfY292ZXJhZ2UAAAAHAAAAcmFkaWlfeAAHAAAAcmFkaWlfeQAEAAAAc2tldxkAAAB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlAAAABQAAAGNvbG9yAAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAWXW3ZEQAAAADAAAAAGATHIBICYCAAAEBP2LBIPAAAAAIAAAAAEARRALJ3F5SMAAAABQAAAABABTUEURMBAAACAH5FYUHQAAAAAAAEAAAAAZ4RGGRCQFAEAAAAAAAAAGARP2LVJPAAAAAAAAEAAAABSKRXZFAUHQAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"CgAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABYQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB5AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA"}} \ No newline at end of file +{"platform":"android","name":"SM G970N","engineRevision":"b4fb11214dd2dda6ce012dd98ea498e9e8b91262","data":{"HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAA7AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACsAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"CgAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"CgAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAHMCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwKS5ycnJyOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAHSADQAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAQAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAWXW3ZEQAAAADAAAAAGATHIBICYCAAAEBP2LBIPAAAAAIAAAAAEARRALJ3F5SMAAAABQAAAABABTUEURMBAAACAH5FYUHQAAAAAAAEAAAAAZ4RGGRCQFAEAAAAAAAAAGARP2LVJPAAAAAAAAEAAAABSKRXZFAUHQAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"CgAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"CgAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAALAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBSUmVjdFNoYWRvdwoJaGFsZjMgc2hhZG93UGFyYW1zOwoJc2hhZG93UGFyYW1zID0gdmluU2hhZG93UGFyYW1zX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZiBkID0gbGVuZ3RoKHNoYWRvd1BhcmFtcy54eSk7CglmbG9hdDIgdXYgPSBmbG9hdDIoc2hhZG93UGFyYW1zLnogKiAoMS4wIC0gZCksIDAuNSk7CgloYWxmIGZhY3RvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLjAwMHIuYTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZmFjdG9yKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAOAAAAaW5TaGFkb3dQYXJhbXMAAAAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAACU53QJEKAAAAAAMAAAAAIAAAAAAGIRDFB2XASAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAC4BAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjbGVfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41ID8gMSA6IDApKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShfc3JjLCBDaXJjbGVfUzFfYzAoX3NyYykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQHEB4XIQAQAADQAAAABAAAAAAABAEMVDOMCJKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABRBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSA/IDEgOiAwKSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MxX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IHhfcGx1c18xPXZhcmNjb29yZF9TMC54LCB5PXZhcmNjb29yZF9TMC55OwoJaGFsZiBjb3ZlcmFnZTsKCWlmICgwID09IHhfcGx1c18xKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoeSk7Cgl9CgllbHNlIAoJewoJCWZsb2F0IGZuID0geF9wbHVzXzEgKiAoeF9wbHVzXzEgLSAyKTsKCQlmbiA9IGZtYSh5LHksIGZuKTsKCQlmbG9hdCBmbndpZHRoID0gZndpZHRoKGZuKTsKCQljb3ZlcmFnZSA9IC41IC0gaGFsZihmbi9mbndpZHRoKTsKCQljb3ZlcmFnZSA9IGNsYW1wKGNvdmVyYWdlLCAwLCAxKTsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAIAAEAAAABJYQAAAAAQAAIAAAAAWCBACAABAAAAANAECAZAAEAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IGNsYW1wKHN1YnNldENvb3JkLngsIHVjbGFtcF9TMV9jMF9jMF9jMC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueik7CgljbGFtcGVkQ29vcmQueSA9IHN1YnNldENvb3JkLnk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEADZABYAAAIAAAAAACQAGAAAAAQAAAAAAAQQG":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAADUAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBQU7BTXIAAAAAACAAAAAAQFV5W6JEAAAAAYAAAABQEZ2AKAWAQAABAL6SYKDYAAAACAAAAAAQEGIAAAAACAWTWL3EYAAAADAAAAACADHIJJCYCAAAEAP2LRIPAAAAAIAAAAAAABTALI3F5SOAIAABQAAAAAABTUEUZMBAAAAAH5FYUXQAAAAAAAEAAAAAZMRGOQCQFQEAAAAAAAAAGARL2LXJHAAEAAAAAEAAAABSCQX5FQUHQAAAAAAAAAACAA4AAAABAACAAAACCAYAAAAA":"CgAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc182X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAMMHAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwpoYWxmNCBTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IF9jb29yZHM7CglyZXR1cm4gaGFsZjQobWl4KHVzdGFydF9TMV9jMF9jMF9jMCwgdWVuZF9TMV9jMF9jMF9jMCwgaGFsZihfdG1wXzFfY29vcmRzLngpKSk7Cn0KaGFsZjQgTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfM19jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKCXJldHVybiBoYWxmNChoYWxmNChoYWxmKF90bXBfM19jb29yZHMueCkgKyAxZS0wNSwgMS4wLCAwLjAsIDAuMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTGluZWFyTGF5b3V0X1MxX2MwX2MwX2MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgdCA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMF9jMShfdG1wXzRfaW5Db2xvcik7CgloYWxmNCBvdXRDb2xvcjsKCWlmICghYm9vbChpbnQoMSkpICYmIHQueSA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSBoYWxmNCgwLjApOwoJfQoJZWxzZSBpZiAodC54IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IHVsZWZ0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIGlmICh0LnggPiAxLjApIAoJewoJCW91dENvbG9yID0gdXJpZ2h0Qm9yZGVyQ29sb3JfUzFfYzBfYzA7Cgl9CgllbHNlIAoJewoJCW91dENvbG9yID0gU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgY29sb3JfeGZvcm1fUzFfYzAoZmxvYXQ0IGNvbG9yKSAKewoJY29sb3IucmdiICo9IGNvbG9yLmE7CglyZXR1cm4gaGFsZjQoY29sb3IpOwp9CmhhbGY0IENvbG9yU3BhY2VYZm9ybV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gY29sb3JfeGZvcm1fUzFfYzAoQ2xhbXBlZEdyYWRpZW50X1MxX2MwX2MwKF9pbnB1dCkpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ29sb3JTcGFjZVhmb3JtX1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gKGhhbGY0KDEuMCkgLSBvdXRwdXRfUzEpICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzAueCwgdWNsYW1wX1MxX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"CgAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACfAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEaXN0YW5jZUZpZWxkUGF0aAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQyIHV2ID0gdlRleHR1cmVDb29yZHNfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLnJycnI7Cgl9CgloYWxmIGRpc3RhbmNlID0gNy45Njg3NSoodGV4Q29sb3IuciAtIDAuNTAxOTYwNzg0MzEpOwoJaGFsZiBhZndpZHRoOwoJYWZ3aWR0aCA9IGFicygwLjY1KmhhbGYoZEZkeCh2SW50VGV4dHVyZUNvb3Jkc19TMC54KSkpOwoJaGFsZiB2YWwgPSBzbW9vdGhzdGVwKC1hZndpZHRoLCBhZndpZHRoLCBkaXN0YW5jZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KHZhbCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"CgAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAABEAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAoAIAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAAAAIAAAABLAIABAAAAABAEGABBAMAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAC2AgAAdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKE1hdHJpeEVmZmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb2xvcl9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAIBAIAAAABLCIIBAAAAABAEGABBAMAACAIAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAADJAwAAdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoTWF0cml4RWZmZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvbG9yX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","DASAAAAAQAAWAABAYAAQBYH7777Z6QQBAEAAAAAAEAAAAAAAEBSAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADgAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCk7Cgl9CglvdXRwdXRDb2xvcl9TMCA9IG91dHB1dENvbG9yX1MwICogdGV4Q29sb3I7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAAYQADAAAEAFEURUKQKAAAYAAAAAAAAIAAAABSCICWKY2FAEAAAMAAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB+BQAAY29uc3QgaW50IGtGaWxsQldfUzFfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzFfYzA7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgUmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMV9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzFfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MxX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAD2AAAAAAQAVSWGRIBAAADAAAAACAAAAAAQCGEIQOZLBIQAAAABQAAAAAAAAAAAAFAAMAAAABAAAAAAABBAMAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAARQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAAAAEAAAABJYQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAPAEAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxM107CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IFNtb290aF9TMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBjb29yZCwgaGFsZjIgb2Zmc2V0QW5kS2VybmVsKSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfaW5wdXQsIChjb29yZCArIG9mZnNldEFuZEtlcm5lbC54ICogdUluY3JlbWVudF9TMV9jMCkpICogb2Zmc2V0QW5kS2VybmVsLnk7Cn0KaGFsZjQgR2F1c3NpYW5Db252b2x1dGlvbl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBjb2xvciA9IGhhbGY0KDApOwoJZmxvYXQyIGNvb3JkID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7Cglmb3IgKGludCBpPTA7IGk8MTM7ICsraSkgCgl7CgkJY29sb3IgKz0gU21vb3RoX1MxX2MwKF9pbnB1dCwgY29vcmQsIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldKTsKCX0KCXJldHVybiBjb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"CgAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQAAEAQAAAAGQCBAMQAAAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzAueSwgdWNsYW1wX1MxX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAANAAAAALHCKLMRAAAAAAAAABAAAAAGJBCFLQVBWAQAAAAAAQAAAAAMACQCAACAAAAA2AIBAEIAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAAAA":"CgAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAeAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1Y2lyY2xlRGF0YV9TMV9jMDsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBDaXJjbGVCbHVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjIgdmVjID0gaGFsZjIoKHNrX0ZyYWdDb29yZC54eSAtIGZsb2F0Mih1Y2lyY2xlRGF0YV9TMV9jMC54eSkpICogZmxvYXQodWNpcmNsZURhdGFfUzFfYzAudykpOwoJaGFsZiBkaXN0ID0gbGVuZ3RoKHZlYykgKyAoMC41IC0gdWNpcmNsZURhdGFfUzFfYzAueikgKiB1Y2lyY2xlRGF0YV9TMV9jMC53OwoJcmV0dXJuIGhhbGY0KE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgZmxvYXQyKGhhbGYyKGRpc3QsIDAuNSkpKS53d3d3KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKENpcmNsZUJsdXJfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"CgAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"CgAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBQU7BTXIAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"CgAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAArAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAKPABAAAAAAB2AAAAAAACAAAAAEBSAAAAAAA":"CgAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACbBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBFbGxpcHRpY2FsUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CglmbG9hdDIgWiA9IGR4eSAqIHVpbnZSYWRpaVhZX1MxLnh5OwoJaGFsZiBpbXBsaWNpdCA9IGhhbGYoZG90KFosIGR4eSkgLSAxLjApOwoJaGFsZiBncmFkX2RvdCA9IGhhbGYoNC4wICogZG90KFosIFopKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjBlLTQpOwoJaGFsZiBhcHByb3hfZGlzdCA9IGltcGxpY2l0ICogaGFsZihpbnZlcnNlc3FydChncmFkX2RvdCkpOwoJaGFsZiBhbHBoYSA9IGNsYW1wKDAuNSArIGFwcHJveF9kaXN0LCAwLjAsIDEuMCk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEVsbGlwdGljYWxSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADgAAAHJhZGlpX3NlbGVjdG9yAAAZAAAAY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cwAAABUAAABhYV9ibG9hdF9hbmRfY292ZXJhZ2UAAAAHAAAAcmFkaWlfeAAHAAAAcmFkaWlfeQAEAAAAc2tldxkAAAB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlAAAABQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAABAEAAAABJYQAAAAAACAIAAAAAWCBAAAIBAAAAANAECAZAAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IHN1YnNldENvb3JkLng7CgljbGFtcGVkQ29vcmQueSA9IGNsYW1wKHN1YnNldENvb3JkLnksIHVjbGFtcF9TMV9jMF9jMF9jMC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAudyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAE0DAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMC54eSwgdWNsYW1wX1MxX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"CgAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAsQEAAHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABYQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB5AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"CgAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"CgAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADdAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIG91dHB1dENvbG9yX1MwKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"CgAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA="}} \ No newline at end of file From 33841788f7551b331b7b81d49e3b21b1a6ae15e8 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 21 May 2023 16:47:38 +0200 Subject: [PATCH 26/35] APNG identification --- CHANGELOG.md | 2 +- android/app/src/main/AndroidManifest.xml | 2 +- .../channel/calls/MetadataFetchHandler.kt | 6 +++++ .../metadataextractor/PngActlDirectory.kt | 22 ++++++++++++++++++ .../SafePngMetadataReader.kt | 23 ++++++++++++++++--- 5 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/PngActlDirectory.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index ab2f65147..3408d0272 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - option to set the Tags page as home -- support for animated PNG +- support for animated PNG (requires rescan) - Info: added day filter with item date - Widget: option to update image on tap - Slideshow / Screen saver: option for random transition diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 014a84516..28d61c137 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -301,7 +301,7 @@ This change eventually prevents building the app with Flutter v3.7.11. - + diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt index 8145c71cc..e04dc7241 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt @@ -75,6 +75,7 @@ import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeInt import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeRational import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeString import deckers.thibault.aves.metadata.metadataextractor.Helper.isPngTextDir +import deckers.thibault.aves.metadata.metadataextractor.PngActlDirectory import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue import deckers.thibault.aves.utils.LogUtils @@ -657,6 +658,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { } } } + + // identification of animated PNG + if (metadata.containsDirectoryOfType(PngActlDirectory::class.java)) { + flags = flags or MASK_IS_ANIMATED + } } MimeTypes.GIF -> { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/PngActlDirectory.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/PngActlDirectory.kt new file mode 100644 index 000000000..93138826a --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/PngActlDirectory.kt @@ -0,0 +1,22 @@ +package deckers.thibault.aves.metadata.metadataextractor +import com.drew.imaging.png.PngChunkType +import com.drew.metadata.png.PngDirectory + +class PngActlDirectory : PngDirectory(chunkType) { + override fun getTagNameMap(): HashMap { + return tagNames + } + + companion object { + val chunkType = PngChunkType("acTL") + + // tags should be distinct from those already defined in `PngDirectory` + const val TAG_NUM_FRAMES = 101 + const val TAG_NUM_PLAYS = 102 + + private val tagNames = hashMapOf( + TAG_NUM_FRAMES to "Number Of Frames", + TAG_NUM_PLAYS to "Number Of Plays", + ) + } +} diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt index d8b5452a4..c438068b5 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafePngMetadataReader.kt @@ -34,9 +34,10 @@ import java.io.InputStream import java.util.zip.InflaterInputStream import java.util.zip.ZipException -// adapted from `PngMetadataReader` to prevent OOM from reading large chunks -// as of `metadata-extractor` v2.18.0, there is no way to customize the reader -// without copying `desiredChunkTypes` and the whole `processChunk` function +// adapted from `PngMetadataReader` to: +// - prevent OOM from reading large chunks. As of `metadata-extractor` v2.18.0, there is no way to customize the reader +// without copying `desiredChunkTypes` and the whole `processChunk` function. +// - parse `acTL` chunk to identify animated PNGs. object SafePngMetadataReader { private val LOG_TAG = LogUtils.createTag() @@ -60,6 +61,7 @@ object SafePngMetadataReader { PngChunkType.pHYs, PngChunkType.sBIT, PngChunkType.eXIf, + PngActlDirectory.chunkType, ) @Throws(IOException::class, PngProcessingException::class) @@ -99,6 +101,21 @@ object SafePngMetadataReader { directory.setInt(PngDirectory.TAG_FILTER_METHOD, header.filterMethod.toInt()) directory.setInt(PngDirectory.TAG_INTERLACE_METHOD, header.interlaceMethod.toInt()) metadata.addDirectory(directory) + // TLAD insert start + } else if (chunkType == PngActlDirectory.chunkType) { + if (bytes.size != 8) { + throw PngProcessingException("Invalid number of bytes") + } + val reader = SequentialByteArrayReader(bytes) + try { + metadata.addDirectory(PngActlDirectory().apply { + setInt(PngActlDirectory.TAG_NUM_FRAMES, reader.int32) + setInt(PngActlDirectory.TAG_NUM_PLAYS, reader.int32) + }) + } catch (ex: IOException) { + throw PngProcessingException(ex) + } + // TLAD insert end } else if (chunkType == PngChunkType.PLTE) { val directory = PngDirectory(PngChunkType.PLTE) directory.setInt(PngDirectory.TAG_PALETTE_SIZE, bytes.size / 3) From 1487d8cc1a89a6c9b98efd079601e8f24d217421 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 21 May 2023 17:53:59 +0200 Subject: [PATCH 27/35] l10n by weblate (#635) Translate-URL: https://hosted.weblate.org/projects/aves/app-android/ar/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ar/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/cs/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/de/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/es/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/eu/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/fr/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/hu/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/id/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/ko/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/nn/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/pl/ Translate-URL: https://hosted.weblate.org/projects/aves/app-main/uk/ Translate-URL: https://hosted.weblate.org/projects/aves/store-full-description/eu/ Translation: Aves/App - Android Translation: Aves/App - Main Translation: Aves/Store - Full description Co-authored-by: Aitor Salaberria Co-authored-by: Ettore Atalan Co-authored-by: Linerly Co-authored-by: Skrripy Co-authored-by: Thibault Deckers Co-authored-by: gallegonovato Co-authored-by: nasreddineloukriz Co-authored-by: rehork Co-authored-by: tryvseu Co-authored-by: vesp Co-authored-by: wickdj --- .../app/src/main/res/values-ar/strings.xml | 2 + .../metadata/android/eu/full_description.txt | 4 +- lib/l10n/app_ar.arb | 8 +- lib/l10n/app_cs.arb | 36 +- lib/l10n/app_de.arb | 44 +- lib/l10n/app_es.arb | 20 +- lib/l10n/app_eu.arb | 20 +- lib/l10n/app_fr.arb | 22 +- lib/l10n/app_hu.arb | 20 +- lib/l10n/app_id.arb | 20 +- lib/l10n/app_ko.arb | 22 +- lib/l10n/app_nn.arb | 724 +++++++++++++++++- lib/l10n/app_pl.arb | 20 +- lib/l10n/app_uk.arb | 20 +- 14 files changed, 923 insertions(+), 59 deletions(-) diff --git a/android/app/src/main/res/values-ar/strings.xml b/android/app/src/main/res/values-ar/strings.xml index a5e1a1c3b..0d6515695 100644 --- a/android/app/src/main/res/values-ar/strings.xml +++ b/android/app/src/main/res/values-ar/strings.xml @@ -7,4 +7,6 @@ فحص الوسائط يتم فحص الوسائط إيقاف + الوضع الآمن + أيفيس \ No newline at end of file diff --git a/fastlane/metadata/android/eu/full_description.txt b/fastlane/metadata/android/eu/full_description.txt index b0d5229c3..e615df16a 100644 --- a/fastlane/metadata/android/eu/full_description.txt +++ b/fastlane/metadata/android/eu/full_description.txt @@ -1,5 +1,5 @@ -Aves aplikazioak mota guztitako irudi eta bideoak, nahiz ohiko zure JPEG eta MP4 fitxategiak eta exotikoagoak diren orri ugaritako TIFF, SVG, AVI zaharrak eta are gehiago maneiatzen ditu! Zure media-bilduma eskaneatzen du mugimendu-argazkiak,panoramikak (argazki esferikoak bezala ere ezagunak), 360°-ko bideoak, baita GeoTIFF fitxategiak ere. +Aves aplikazioak mota guztitako irudi eta bideoak, nahiz ohiko zure JPEG eta MP4 fitxategiak eta exotikoagoak diren orri ugaritako TIFF, SVG, AVI zaharrak eta are gehiago maneiatzen ditu! Zure media-bilduma eskaneatzen du mugimendu-argazkiak, panoramikak (argazki esferikoak bezala ere ezagunak), 360°-ko bideoak, baita GeoTIFF fitxategiak ere. Nabigazioa eta bilaketa Aves aplikazioaren zati garrantzitsu bat da. Helburua, erabiltzaileek albumetatik argazkietara, etiketetara, mapetara, etab. modu errazean mugi ahal izatea da. -Aves Androidera (KitKatetik Android 13ra, Android TV barne) egiten da ezaugarri ugarirekin: widgetak, aplikazioko lasterbideak, pantaila-babeslea eta bilaketa globala. Baita ere, media-bisore edo -hautagailu bezala ere erabil daiteke. \ No newline at end of file +Aves Androidera (KitKatetik Android 13ra, Android TV barne) egiten da ezaugarri ugarirekin: widgetak, aplikazioko lasterbideak, pantaila-babeslea eta bilaketa globala. Baita ere, media-bisore edo -hautagailu bezala erabil daiteke. \ No newline at end of file diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 557e12b6a..73b65e109 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -39,7 +39,7 @@ "@changeTooltip": {}, "actionRemove": "إزالة", "@actionRemove": {}, - "appName": "Aves", + "appName": "أيفيس", "@appName": {}, "welcomeOptional": "اختياري", "@welcomeOptional": {}, @@ -51,7 +51,7 @@ "@cancelTooltip": {}, "previousTooltip": "السابق", "@previousTooltip": {}, - "welcomeMessage": "مرحبا بكم في Aves", + "welcomeMessage": "مرحبا بكم في أيفيس", "@welcomeMessage": {}, "applyButtonLabel": "تطبيق", "@applyButtonLabel": {}, @@ -68,5 +68,7 @@ "hideTooltip": "إخفاء", "@hideTooltip": {}, "tagEditorPageAddTagTooltip": "إضافة علامة", - "@tagEditorPageAddTagTooltip": {} + "@tagEditorPageAddTagTooltip": {}, + "albumScreenRecordings": "تسجيل الشاشة", + "@albumScreenRecordings": {} } diff --git a/lib/l10n/app_cs.arb b/lib/l10n/app_cs.arb index c388db77d..1f52e0060 100644 --- a/lib/l10n/app_cs.arb +++ b/lib/l10n/app_cs.arb @@ -1452,5 +1452,39 @@ "tagPlaceholderState": "Stát", "@tagPlaceholderState": {}, "settingsVideoBackgroundModeDialogTitle": "Režim na pozadí", - "@settingsVideoBackgroundModeDialogTitle": {} + "@settingsVideoBackgroundModeDialogTitle": {}, + "saveCopyButtonLabel": "ULOŽIT KOPII", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Použít", + "@applyTooltip": {}, + "editorTransformCrop": "Oříznout", + "@editorTransformCrop": {}, + "editorTransformRotate": "Otočit", + "@editorTransformRotate": {}, + "cropAspectRatioOriginal": "Originál", + "@cropAspectRatioOriginal": {}, + "widgetTapUpdateWidget": "Aktualizovat widget", + "@widgetTapUpdateWidget": {}, + "settingsVideoResumptionModeDialogTitle": "Obnovit přehrávání", + "@settingsVideoResumptionModeDialogTitle": {}, + "settingsAskEverytime": "Vždy se zeptat", + "@settingsAskEverytime": {}, + "tagEditorDiscardDialogMessage": "Chcete zrušit změny?", + "@tagEditorDiscardDialogMessage": {}, + "maxBrightnessNever": "Nikdy", + "@maxBrightnessNever": {}, + "maxBrightnessAlways": "Vždy", + "@maxBrightnessAlways": {}, + "videoResumptionModeNever": "Nikdy", + "@videoResumptionModeNever": {}, + "videoResumptionModeAlways": "Vždy", + "@videoResumptionModeAlways": {}, + "exportEntryDialogQuality": "Kvalita", + "@exportEntryDialogQuality": {}, + "settingsVideoPlaybackTile": "Přehrávání", + "@settingsVideoPlaybackTile": {}, + "settingsVideoPlaybackPageTitle": "Přehrávání", + "@settingsVideoPlaybackPageTitle": {}, + "settingsVideoResumptionModeTile": "Obnovit přehrávání", + "@settingsVideoResumptionModeTile": {} } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 9e83cf533..7512c6b81 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -303,7 +303,7 @@ "@wallpaperTargetHomeLock": {}, "widgetOpenPageHome": "Startseite öffnen", "@widgetOpenPageHome": {}, - "widgetOpenPageViewer": "Viewer öffnen", + "widgetOpenPageViewer": "Betrachter öffnen", "@widgetOpenPageViewer": {}, "albumTierNew": "Neu", "@albumTierNew": {}, @@ -1294,5 +1294,45 @@ "vaultBinUsageDialogMessage": "Einige Tresore verwenden den Papierkorb.", "@vaultBinUsageDialogMessage": {}, "pinDialogEnter": "PIN eingeben", - "@pinDialogEnter": {} + "@pinDialogEnter": {}, + "maxBrightnessNever": "Nie", + "@maxBrightnessNever": {}, + "maxBrightnessAlways": "Immer", + "@maxBrightnessAlways": {}, + "videoResumptionModeNever": "Nie", + "@videoResumptionModeNever": {}, + "videoResumptionModeAlways": "Immer", + "@videoResumptionModeAlways": {}, + "exportEntryDialogQuality": "Qualität", + "@exportEntryDialogQuality": {}, + "settingsAskEverytime": "Jedes Mal nachfragen", + "@settingsAskEverytime": {}, + "settingsVideoPlaybackTile": "Wiedergabe", + "@settingsVideoPlaybackTile": {}, + "settingsVideoPlaybackPageTitle": "Wiedergabe", + "@settingsVideoPlaybackPageTitle": {}, + "settingsVideoResumptionModeTile": "Wiedergabe fortsetzen", + "@settingsVideoResumptionModeTile": {}, + "settingsVideoResumptionModeDialogTitle": "Wiedergabe fortsetzen", + "@settingsVideoResumptionModeDialogTitle": {}, + "tagEditorDiscardDialogMessage": "Möchten Sie die Änderungen verwerfen?", + "@tagEditorDiscardDialogMessage": {}, + "saveCopyButtonLabel": "KOPIE SPEICHERN", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Anwenden", + "@applyTooltip": {}, + "editorActionTransform": "Umwandeln", + "@editorActionTransform": {}, + "editorTransformCrop": "Zuschneiden", + "@editorTransformCrop": {}, + "editorTransformRotate": "Drehen", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Frei", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Original", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "Quadrat", + "@cropAspectRatioSquare": {}, + "widgetTapUpdateWidget": "Widget öffnen", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 5040c967f..98fca8db9 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1316,5 +1316,23 @@ "videoResumptionModeNever": "Nunca", "@videoResumptionModeNever": {}, "exportEntryDialogQuality": "Calidad", - "@exportEntryDialogQuality": {} + "@exportEntryDialogQuality": {}, + "saveCopyButtonLabel": "GUARDAR UNA COPIA", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Aplicar", + "@applyTooltip": {}, + "editorTransformCrop": "Recortar", + "@editorTransformCrop": {}, + "editorTransformRotate": "Girar", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Libre", + "@cropAspectRatioFree": {}, + "cropAspectRatioSquare": "Cuadrado", + "@cropAspectRatioSquare": {}, + "editorActionTransform": "Transformar", + "@editorActionTransform": {}, + "cropAspectRatioOriginal": "Original", + "@cropAspectRatioOriginal": {}, + "widgetTapUpdateWidget": "Actualizar el widget", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_eu.arb b/lib/l10n/app_eu.arb index 2b28a73af..04972bb2e 100644 --- a/lib/l10n/app_eu.arb +++ b/lib/l10n/app_eu.arb @@ -1474,5 +1474,23 @@ "videoResumptionModeNever": "Inoiz", "@videoResumptionModeNever": {}, "settingsVideoResumptionModeDialogTitle": "Jarraitu erreprodukzioa", - "@settingsVideoResumptionModeDialogTitle": {} + "@settingsVideoResumptionModeDialogTitle": {}, + "saveCopyButtonLabel": "GORDE KOPIA", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Aplikatu", + "@applyTooltip": {}, + "editorActionTransform": "Eraldatu", + "@editorActionTransform": {}, + "editorTransformCrop": "Moztu", + "@editorTransformCrop": {}, + "editorTransformRotate": "Biratu", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Librea", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Jatorrizkoa", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "Karratua", + "@cropAspectRatioSquare": {}, + "widgetTapUpdateWidget": "Eguneratu widgeta", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index a53802a31..a204ea360 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -17,7 +17,7 @@ "@timeDays": {}, "focalLength": "{length} mm", "@focalLength": {}, - "applyButtonLabel": "ENREGISTRER", + "applyButtonLabel": "APPLIQUER", "@applyButtonLabel": {}, "deleteButtonLabel": "SUPPRIMER", "@deleteButtonLabel": {}, @@ -1316,5 +1316,23 @@ "videoResumptionModeAlways": "Toujours", "@videoResumptionModeAlways": {}, "exportEntryDialogQuality": "Qualité", - "@exportEntryDialogQuality": {} + "@exportEntryDialogQuality": {}, + "saveCopyButtonLabel": "ENREGISTRER UNE COPIE", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Appliquer", + "@applyTooltip": {}, + "editorActionTransform": "Transformation", + "@editorActionTransform": {}, + "editorTransformCrop": "Recadrage", + "@editorTransformCrop": {}, + "editorTransformRotate": "Rotation", + "@editorTransformRotate": {}, + "cropAspectRatioSquare": "Carré", + "@cropAspectRatioSquare": {}, + "cropAspectRatioFree": "Personnalisé", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Photo d’origine", + "@cropAspectRatioOriginal": {}, + "widgetTapUpdateWidget": "Mettre à jour le widget", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_hu.arb b/lib/l10n/app_hu.arb index d634e332b..35f720b45 100644 --- a/lib/l10n/app_hu.arb +++ b/lib/l10n/app_hu.arb @@ -1474,5 +1474,23 @@ "settingsVideoPlaybackTile": "Visszajátszás", "@settingsVideoPlaybackTile": {}, "exportEntryDialogQuality": "Minőség", - "@exportEntryDialogQuality": {} + "@exportEntryDialogQuality": {}, + "editorActionTransform": "Alakítás", + "@editorActionTransform": {}, + "cropAspectRatioOriginal": "Eredeti", + "@cropAspectRatioOriginal": {}, + "applyTooltip": "Alkalmaz", + "@applyTooltip": {}, + "saveCopyButtonLabel": "MÁSOLAT MENTÉSE", + "@saveCopyButtonLabel": {}, + "editorTransformCrop": "Vágás", + "@editorTransformCrop": {}, + "editorTransformRotate": "Forgatás", + "@editorTransformRotate": {}, + "cropAspectRatioSquare": "Négyzet", + "@cropAspectRatioSquare": {}, + "cropAspectRatioFree": "Kötetlen", + "@cropAspectRatioFree": {}, + "widgetTapUpdateWidget": "Widget frissítése", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 97398a84c..16eddb018 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -1316,5 +1316,23 @@ "settingsVideoPlaybackTile": "Pemutaran", "@settingsVideoPlaybackTile": {}, "settingsVideoPlaybackPageTitle": "Pemutaran", - "@settingsVideoPlaybackPageTitle": {} + "@settingsVideoPlaybackPageTitle": {}, + "cropAspectRatioOriginal": "Asli", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "Kotak", + "@cropAspectRatioSquare": {}, + "saveCopyButtonLabel": "SIMPAN SALINAN", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Terapkan", + "@applyTooltip": {}, + "editorActionTransform": "Transformasi", + "@editorActionTransform": {}, + "editorTransformCrop": "Potong", + "@editorTransformCrop": {}, + "editorTransformRotate": "Putar", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Bebas", + "@cropAspectRatioFree": {}, + "widgetTapUpdateWidget": "Perbarui widget", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index f8ea87c9d..d3d75fe63 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -17,7 +17,7 @@ "@timeDays": {}, "focalLength": "{length} mm", "@focalLength": {}, - "applyButtonLabel": "확인", + "applyButtonLabel": "적용", "@applyButtonLabel": {}, "deleteButtonLabel": "삭제", "@deleteButtonLabel": {}, @@ -1316,5 +1316,23 @@ "maxBrightnessNever": "작동 안 함", "@maxBrightnessNever": {}, "exportEntryDialogQuality": "품질", - "@exportEntryDialogQuality": {} + "@exportEntryDialogQuality": {}, + "saveCopyButtonLabel": "사본 저장", + "@saveCopyButtonLabel": {}, + "applyTooltip": "적용", + "@applyTooltip": {}, + "editorTransformCrop": "자르기", + "@editorTransformCrop": {}, + "editorTransformRotate": "회전", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "사용자 맞춤 비율", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "원본", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "정사각형", + "@cropAspectRatioSquare": {}, + "editorActionTransform": "변형", + "@editorActionTransform": {}, + "widgetTapUpdateWidget": "위젯 갱신", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_nn.arb b/lib/l10n/app_nn.arb index 11c247896..4969889a1 100644 --- a/lib/l10n/app_nn.arb +++ b/lib/l10n/app_nn.arb @@ -64,13 +64,13 @@ "@actionRemove": {}, "resetTooltip": "Still attende", "@resetTooltip": {}, - "saveTooltip": "Gøym", + "saveTooltip": "Spar", "@saveTooltip": {}, "pickTooltip": "Vel", "@pickTooltip": {}, "chipActionUnpin": "losna ifrå toppen", "@chipActionUnpin": {}, - "chipActionRename": "Gjev nytt/nye namn", + "chipActionRename": "Byt namn", "@chipActionRename": {}, "chipActionSetCover": "Sett omslag", "@chipActionSetCover": {}, @@ -82,7 +82,7 @@ "@entryActionDelete": {}, "entryActionConvert": "Lag om", "@entryActionConvert": {}, - "entryActionRename": "Gjev nytt/nye namn", + "entryActionRename": "Byt namn", "@entryActionRename": {}, "entryActionRestore": "Gjenopprett", "@entryActionRestore": {}, @@ -114,11 +114,11 @@ "@entryActionRotateScreen": {}, "entryActionAddFavourite": "Lik", "@entryActionAddFavourite": {}, - "videoActionCaptureFrame": "Grip ramma", + "videoActionCaptureFrame": "Grip biletet", "@videoActionCaptureFrame": {}, "videoActionMute": "Døyv", "@videoActionMute": {}, - "videoActionUnmute": "Tak bort døyvinga", + "videoActionUnmute": "Ikkje døyv", "@videoActionUnmute": {}, "videoActionPause": "Stans", "@videoActionPause": {}, @@ -144,7 +144,7 @@ "@chipActionGoToAlbumPage": {}, "chipActionGoToCountryPage": "Vis i Land", "@chipActionGoToCountryPage": {}, - "chipActionGoToTagPage": "Vis i Merkelappar", + "chipActionGoToTagPage": "Vis i Merke", "@chipActionGoToTagPage": {}, "chipActionHide": "Skjul", "@chipActionHide": {}, @@ -176,15 +176,15 @@ "@slideshowActionResume": {}, "slideshowActionShowInCollection": "Vis i Samling", "@slideshowActionShowInCollection": {}, - "entryInfoActionEditDate": "Brigd dato og tid", + "entryInfoActionEditDate": "Brigd datoen og tida", "@entryInfoActionEditDate": {}, "entryInfoActionEditTitleDescription": "Brigd namnet og utgreiinga", "@entryInfoActionEditTitleDescription": {}, "entryInfoActionEditRating": "Brigd omdøminga", "@entryInfoActionEditRating": {}, - "entryInfoActionEditTags": "Brigd merkelappar", + "entryInfoActionEditTags": "Brigd merka", "@entryInfoActionEditTags": {}, - "entryInfoActionExportMetadata": "Utfør metadata", + "entryInfoActionExportMetadata": "Før ut metadata", "@entryInfoActionExportMetadata": {}, "filterAspectRatioLandscapeLabel": "Liggjande", "@filterAspectRatioLandscapeLabel": {}, @@ -198,7 +198,7 @@ "@filterNoAddressLabel": {}, "filterNoRatingLabel": "Ikkje dømde", "@filterNoRatingLabel": {}, - "filterNoTagLabel": "Utan merkelappar", + "filterNoTagLabel": "Utan merke", "@filterNoTagLabel": {}, "filterNoTitleLabel": "Utan namn", "@filterNoTitleLabel": {}, @@ -206,7 +206,7 @@ "@filterRecentlyAddedLabel": {}, "filterRatingRejectedLabel": "Avslegen", "@filterRatingRejectedLabel": {}, - "filterTypeRawLabel": "Rå(tt)", + "filterTypeRawLabel": "Rå", "@filterTypeRawLabel": {}, "filterTypeSphericalVideoLabel": "360°-video", "@filterTypeSphericalVideoLabel": {}, @@ -252,7 +252,7 @@ "@mapStyleHuaweiNormal": {}, "mapStyleHuaweiTerrain": "Petal Maps (mark)", "@mapStyleHuaweiTerrain": {}, - "nameConflictStrategyRename": "Omkall", + "nameConflictStrategyRename": "Byt namn", "@nameConflictStrategyRename": {}, "nameConflictStrategyReplace": "Byt ut", "@nameConflictStrategyReplace": {}, @@ -264,7 +264,7 @@ "@keepScreenOnViewerOnly": {}, "keepScreenOnAlways": "Heile tida", "@keepScreenOnAlways": {}, - "accessibilityAnimationsRemove": "Hindra skjermrørsle", + "accessibilityAnimationsRemove": "Hindr skjermrørsler", "@accessibilityAnimationsRemove": {}, "subtitlePositionTop": "På toppen", "@subtitlePositionTop": {}, @@ -278,7 +278,7 @@ "@videoPlaybackWithSound": {}, "viewerTransitionZoomIn": "Auk", "@viewerTransitionZoomIn": {}, - "wallpaperTargetLock": "Låsaskjerm", + "wallpaperTargetLock": "Låseskjerm", "@wallpaperTargetLock": {}, "widgetDisplayedItemMostRecent": "Nylegaste", "@widgetDisplayedItemMostRecent": {}, @@ -359,7 +359,7 @@ "@newAlbumDialogNameLabel": {}, "durationDialogMinutes": "Minutt", "@durationDialogMinutes": {}, - "settingsThemeColorHighlights": "Farga framhevjingar", + "settingsThemeColorHighlights": "Léta framhevjingar", "@settingsThemeColorHighlights": {}, "viewerInfoBackToViewerTooltip": "Attende til vising", "@viewerInfoBackToViewerTooltip": {}, @@ -406,7 +406,7 @@ "@renameEntrySetPagePreviewSectionTitle": {}, "renameEntryDialogLabel": "Nytt namn", "@renameEntryDialogLabel": {}, - "editEntryDialogCopyFromItem": "Kopier ifrå anna element", + "editEntryDialogCopyFromItem": "Kopier ifrå annan ting", "@editEntryDialogCopyFromItem": {}, "editEntryDateDialogSourceFileModifiedDate": "Filbrigdedato", "@editEntryDateDialogSourceFileModifiedDate": {}, @@ -414,17 +414,17 @@ "@durationDialogHours": {}, "editEntryLocationDialogChooseOnMap": "Vel på kartet", "@editEntryLocationDialogChooseOnMap": {}, - "settingsLanguageTile": "Mål", + "settingsLanguageTile": "Skriftmål", "@settingsLanguageTile": {}, "settingsUnitSystemTile": "Einingar", "@settingsUnitSystemTile": {}, "settingsCoordinateFormatDialogTitle": "Koordinatformat", "@settingsCoordinateFormatDialogTitle": {}, - "settingsWidgetDisplayedItem": "Vist element", + "settingsWidgetDisplayedItem": "Vist ting", "@settingsWidgetDisplayedItem": {}, "statsTopAlbumsSectionTitle": "Topp-album", "@statsTopAlbumsSectionTitle": {}, - "statsTopTagsSectionTitle": "Toppmerkelappar", + "statsTopTagsSectionTitle": "Toppmerke", "@statsTopTagsSectionTitle": {}, "viewerInfoUnknown": "ukjend", "@viewerInfoUnknown": {}, @@ -436,7 +436,7 @@ "@viewerInfoLabelOwner": {}, "viewerInfoLabelCoordinates": "Koordinatar", "@viewerInfoLabelCoordinates": {}, - "tagEditorPageAddTagTooltip": "Legg til merkelapp", + "tagEditorPageAddTagTooltip": "Legg til merke", "@tagEditorPageAddTagTooltip": {}, "filePickerDoNotShowHiddenFiles": "Ikkje vis skjulte filer", "@filePickerDoNotShowHiddenFiles": {}, @@ -446,19 +446,19 @@ "@panoramaDisableSensorControl": {}, "filePickerOpenFrom": "Opne ifrå", "@filePickerOpenFrom": {}, - "filePickerNoItems": "Ingen element", + "filePickerNoItems": "Ingen ting", "@filePickerNoItems": {}, "nameConflictDialogSingleSourceMessage": "Somme filer i målmappa har same namn.", "@nameConflictDialogSingleSourceMessage": {}, "nameConflictDialogMultipleSourceMessage": "Somme filer har same namn.", "@nameConflictDialogMultipleSourceMessage": {}, - "binEntriesConfirmationDialogMessage": "{count, plural, =1{Flytt dette elementet til papirkorga?} other{Flytt desse {count} elementa til papirkorga?}}", + "binEntriesConfirmationDialogMessage": "{count, plural, =1{Flytt denne tingen til papirkorga?} other{Flytt desse {count} tinga til papirkorga?}}", "@binEntriesConfirmationDialogMessage": { "placeholders": { "count": {} } }, - "deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Slett dette elementet?} other{Slett desse {count} elementa?}}", + "deleteEntriesConfirmationDialogMessage": "{count, plural, =1{Slett denne tingen?} other{Slett desse {count} tinga?}}", "@deleteEntriesConfirmationDialogMessage": { "placeholders": { "count": {} @@ -470,7 +470,7 @@ "@entryActionShareVideoOnly": {}, "entryActionShareImageOnly": "Del berre bilete", "@entryActionShareImageOnly": {}, - "unsupportedTypeDialogMessage": "{count, plural, other{Denne gjerda er ustødd for element av fylgjande slag: {types}.}}", + "unsupportedTypeDialogMessage": "{count, plural, other{Denne gjerda er ustødd for ting av fylgjande slag: {types}.}}", "@unsupportedTypeDialogMessage": { "placeholders": { "count": {}, @@ -481,17 +481,17 @@ } } }, - "addShortcutDialogLabel": "Snarvegsmerkelapp", + "addShortcutDialogLabel": "Snarvegsmerke", "@addShortcutDialogLabel": {}, "addShortcutButtonLabel": "LEGG TIL", "@addShortcutButtonLabel": {}, "noMatchingAppDialogMessage": "Ingen appar kan handsame dette.", "@noMatchingAppDialogMessage": {}, - "moveUndatedConfirmationDialogMessage": "Gøym elementdatoar før framhald?", + "moveUndatedConfirmationDialogMessage": "Spar datoane til tinga før du går vidare?", "@moveUndatedConfirmationDialogMessage": {}, - "moveUndatedConfirmationDialogSetDate": "Gøym datoar", + "moveUndatedConfirmationDialogSetDate": "Spar datoar", "@moveUndatedConfirmationDialogSetDate": {}, - "setCoverDialogLatest": "Nyaste element", + "setCoverDialogLatest": "Nyaste ting", "@setCoverDialogLatest": {}, "setCoverDialogAuto": "Auto", "@setCoverDialogAuto": {}, @@ -505,11 +505,11 @@ "@renameAlbumDialogLabel": {}, "renameAlbumDialogLabelAlreadyExistsHelper": "Mappa finst alt", "@renameAlbumDialogLabelAlreadyExistsHelper": {}, - "renameEntrySetPageTitle": "Døyp om", + "renameEntrySetPageTitle": "Byt namn", "@renameEntrySetPageTitle": {}, "exportEntryDialogWidth": "Breidd", "@exportEntryDialogWidth": {}, - "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{Slett desse albuma og deira element?} other{Slett desse albuma og deira {count} element?}}", + "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{Slett desse albuma og deira ting?} other{Slett desse albuma og deira {count} ting?}}", "@deleteMultiAlbumConfirmationDialogMessage": { "placeholders": { "count": {} @@ -521,7 +521,7 @@ "@editEntryDateDialogExtractFromTitle": {}, "editEntryDateDialogCopyField": "Kopier ifrå annan dato", "@editEntryDateDialogCopyField": {}, - "editEntryDateDialogShift": "Byt", + "editEntryDateDialogShift": "Skyv", "@editEntryDateDialogShift": {}, "durationDialogSeconds": "Sekund", "@durationDialogSeconds": {}, @@ -563,9 +563,9 @@ "@viewerInfoSearchEmpty": {}, "viewerInfoSearchSuggestionDate": "Dato og tid", "@viewerInfoSearchSuggestionDate": {}, - "tagEditorPageTitle": "Brigd merkelappar", + "tagEditorPageTitle": "Brigd merke", "@tagEditorPageTitle": {}, - "tagEditorPageNewTagFieldLabel": "Ny merkelapp", + "tagEditorPageNewTagFieldLabel": "Nytt merke", "@tagEditorPageNewTagFieldLabel": {}, "filePickerShowHiddenFiles": "Vis skjulte filer", "@filePickerShowHiddenFiles": {}, @@ -613,9 +613,9 @@ "@viewerTransitionFade": {}, "widgetDisplayedItemRandom": "Tilfeldig", "@widgetDisplayedItemRandom": {}, - "widgetOpenPageHome": "Opne heimside", + "widgetOpenPageHome": "Opne heimsida", "@widgetOpenPageHome": {}, - "restrictedAccessDialogMessage": "Denne appen har ikkje lov til å brigde filer i «{directory}»-mappa i «{volume}».\n\nBruk ein førehandsinnlagd filhandsamar eller galleriapp til å flytta elementa til ei anna mappe.", + "restrictedAccessDialogMessage": "Denne appen har ikkje lov til å brigde filer i «{directory}»-mappa i «{volume}».\n\nBruk ein førehandsinnlagd filhandsamar eller galleriapp til å flytta tinga til ei anna mappe.", "@restrictedAccessDialogMessage": { "placeholders": { "directory": { @@ -629,7 +629,7 @@ } } }, - "deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Slett dette albumet og elementet i det?} other{Slett dette albumet og dei {count} elementa i det?}}", + "deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Slett dette albumet og tingen i det?} other{Slett dette albumet og dei {count} tinga i det?}}", "@deleteSingleAlbumConfirmationDialogMessage": { "placeholders": { "count": {} @@ -669,9 +669,9 @@ "@settingsUnitSystemDialogTitle": {}, "settingsCoordinateFormatTile": "Koordinatformat", "@settingsCoordinateFormatTile": {}, - "settingsLanguagePageTitle": "Mål", + "settingsLanguagePageTitle": "Skriftmål", "@settingsLanguagePageTitle": {}, - "settingsLanguageSectionTitle": "Mål og format", + "settingsLanguageSectionTitle": "Skriftmål og format", "@settingsLanguageSectionTitle": {}, "settingsDisplaySectionTitle": "Vising", "@settingsDisplaySectionTitle": {}, @@ -707,7 +707,7 @@ "@videoStreamSelectionDialogOff": {}, "videoStreamSelectionDialogNoSelection": "Det er ingen andre spor.", "@videoStreamSelectionDialogNoSelection": {}, - "genericSuccessFeedback": "Fullgjort", + "genericSuccessFeedback": "Ferdig", "@genericSuccessFeedback": {}, "genericFailureFeedback": "Mislykka", "@genericFailureFeedback": {}, @@ -749,6 +749,648 @@ "@aboutBugSectionTitle": {}, "aboutTranslatorsSectionTitle": "Omsetjarar", "@aboutTranslatorsSectionTitle": {}, - "viewerInfoOpenEmbeddedFailureFeedback": "Kunne ikkje ta ut innbygde opplysingar", - "@viewerInfoOpenEmbeddedFailureFeedback": {} + "viewerInfoOpenEmbeddedFailureFeedback": "Greidde ikkje å pakke ut innbygde data", + "@viewerInfoOpenEmbeddedFailureFeedback": {}, + "dateThisMonth": "Denne månaden", + "@dateThisMonth": {}, + "settingsViewerSectionTitle": "Visinga", + "@settingsViewerSectionTitle": {}, + "cropAspectRatioFree": "Frihand", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Opphavleg", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "Kvadrat", + "@cropAspectRatioSquare": {}, + "videoResumptionModeNever": "Aldri", + "@videoResumptionModeNever": {}, + "wallpaperTargetHome": "Heimskjermen", + "@wallpaperTargetHome": {}, + "settingsViewerShowMinimap": "Vis småkart", + "@settingsViewerShowMinimap": {}, + "patternDialogConfirm": "Stadfest mønsteret", + "@patternDialogConfirm": {}, + "exportEntryDialogWriteMetadata": "Tak med metadata", + "@exportEntryDialogWriteMetadata": {}, + "removeEntryMetadataMotionPhotoXmpWarningDialogMessage": "XMP er turvt for å kunne spela av videoen inni rørslebilete.\n\nEr du viss på at du vil ta det bort?", + "@removeEntryMetadataMotionPhotoXmpWarningDialogMessage": {}, + "aboutBugSaveLogInstruction": "Spar apploggar til ei fil", + "@aboutBugSaveLogInstruction": {}, + "collectionActionMove": "Flytt til album", + "@collectionActionMove": {}, + "collectionGroupAlbum": "Etter album", + "@collectionGroupAlbum": {}, + "collectionGroupMonth": "Etter månad", + "@collectionGroupMonth": {}, + "sectionUnknown": "Ukjend", + "@sectionUnknown": {}, + "collectionEditFailureFeedback": "{count, plural, other{Kunne ikkje brigde {count} ting}}", + "@collectionEditFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "collectionMoveSuccessFeedback": "{count, plural, other{Flytte {count} ting}}", + "@collectionMoveSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "collectionEmptyFavourites": "Det du likar vert vist her", + "@collectionEmptyFavourites": {}, + "collectionEmptyVideos": "Ingen videoar", + "@collectionEmptyVideos": {}, + "drawerCollectionMotionPhotos": "Rørslebilete", + "@drawerCollectionMotionPhotos": {}, + "drawerTagPage": "Merke", + "@drawerTagPage": {}, + "sortByDate": "Etter dato", + "@sortByDate": {}, + "sortBySize": "Etter storleik", + "@sortBySize": {}, + "sortByRating": "Etter omdøme", + "@sortByRating": {}, + "sortOrderNewestFirst": "Nyaste først", + "@sortOrderNewestFirst": {}, + "sortOrderOldestFirst": "Eldste først", + "@sortOrderOldestFirst": {}, + "sortOrderLargestFirst": "Største først", + "@sortOrderLargestFirst": {}, + "albumScreenRecordings": "Skjermopptak", + "@albumScreenRecordings": {}, + "albumVideoCaptures": "Videoopptak", + "@albumVideoCaptures": {}, + "albumEmpty": "Ingen album", + "@albumEmpty": {}, + "searchAlbumsSectionTitle": "Album", + "@searchAlbumsSectionTitle": {}, + "searchCountriesSectionTitle": "Land", + "@searchCountriesSectionTitle": {}, + "settingsConfirmationVaultDataLoss": "Åtvar om datatap ved kvelvet", + "@settingsConfirmationVaultDataLoss": {}, + "settingsNavigationDrawerAddAlbum": "Legg til album", + "@settingsNavigationDrawerAddAlbum": {}, + "settingsConfirmationAfterMoveToBinItems": "Verta spurd om du vil angre etter å ha kasta ting i søppelkorga", + "@settingsConfirmationAfterMoveToBinItems": {}, + "settingsThumbnailShowTagIcon": "Vis merke-ikon", + "@settingsThumbnailShowTagIcon": {}, + "settingsCollectionBurstPatternsNone": "Ingen", + "@settingsCollectionBurstPatternsNone": {}, + "settingsViewerQuickActionEmpty": "Ingen knappar", + "@settingsViewerQuickActionEmpty": {}, + "settingsViewerShowOverlayOnOpening": "Vis ved opning", + "@settingsViewerShowOverlayOnOpening": {}, + "settingsViewerShowShootingDetails": "Vis biletetakingsopplysingar", + "@settingsViewerShowShootingDetails": {}, + "settingsSlideshowFillScreen": "Fyll skjermen", + "@settingsSlideshowFillScreen": {}, + "settingsViewerEnableOverlayBlurEffect": "Uskarp verknad", + "@settingsViewerEnableOverlayBlurEffect": {}, + "settingsSlideshowVideoPlaybackTile": "Videoavspeling", + "@settingsSlideshowVideoPlaybackTile": {}, + "settingsSlideshowVideoPlaybackDialogTitle": "Videoavspeling", + "@settingsSlideshowVideoPlaybackDialogTitle": {}, + "settingsVideoShowVideos": "Vis videoar", + "@settingsVideoShowVideos": {}, + "settingsVideoEnableHardwareAcceleration": "Auk ytinga med maskinvara", + "@settingsVideoEnableHardwareAcceleration": {}, + "settingsVideoBackgroundMode": "Spel av i bakgrunnen", + "@settingsVideoBackgroundMode": {}, + "settingsVideoBackgroundModeDialogTitle": "Spel av i bakgrunnen", + "@settingsVideoBackgroundModeDialogTitle": {}, + "settingsSlideshowIntervalTile": "Byt til neste etter", + "@settingsSlideshowIntervalTile": {}, + "settingsSubtitleThemeTextAlignmentTile": "Tekststilling", + "@settingsSubtitleThemeTextAlignmentTile": {}, + "settingsSubtitleThemeShowOutline": "Vis omriss og skuggar", + "@settingsSubtitleThemeShowOutline": {}, + "settingsSubtitleThemeTextAlignmentDialogTitle": "Tekststilling", + "@settingsSubtitleThemeTextAlignmentDialogTitle": {}, + "settingsAccessibilityShowPinchGestureAlternatives": "Vis andre utvegar for fleirtrykkhandvendingar", + "@settingsAccessibilityShowPinchGestureAlternatives": {}, + "settingsThemeEnableDynamicColor": "Skiftande let", + "@settingsThemeEnableDynamicColor": {}, + "settingsHiddenItemsTile": "Skjulte ting", + "@settingsHiddenItemsTile": {}, + "settingsStorageAccessBanner": "Nokre mapper krev at du gjev appen tilgjenge til dei for å brigde filer i dei. Du kan sjå på mappene som du har gjeve appen tilgjenge til her.", + "@settingsStorageAccessBanner": {}, + "settingsDisplayRefreshRateModeDialogTitle": "Rørslejamleik", + "@settingsDisplayRefreshRateModeDialogTitle": {}, + "viewerInfoPageTitle": "Opplysingar", + "@viewerInfoPageTitle": {}, + "mapPointNorthUpTooltip": "Rett opp", + "@mapPointNorthUpTooltip": {}, + "setCoverDialogCustom": "Eiget", + "@setCoverDialogCustom": {}, + "pinDialogEnter": "Skriv inn ein talkode", + "@pinDialogEnter": {}, + "settingsNavigationDrawerBanner": "Trykk og hald for å flytta og brigde rekkjefylgda til menytinga.", + "@settingsNavigationDrawerBanner": {}, + "settingsEnableBinSubtitle": "Sparar på sletta ting i 30 dagar", + "@settingsEnableBinSubtitle": {}, + "settingsHiddenItemsTabPaths": "Skjulte mapper", + "@settingsHiddenItemsTabPaths": {}, + "statsTopStatesSectionTitle": "Topplandsdelar", + "@statsTopStatesSectionTitle": {}, + "chipActionCreateVault": "Kvelv", + "@chipActionCreateVault": {}, + "chipActionConfigureVault": "Set opp kvelvet", + "@chipActionConfigureVault": {}, + "displayRefreshRatePreferLowest": "Mest ujamn", + "@displayRefreshRatePreferLowest": {}, + "filterTaggedLabel": "Merkte", + "@filterTaggedLabel": {}, + "displayRefreshRatePreferHighest": "Mest jamn", + "@displayRefreshRatePreferHighest": {}, + "settingsThumbnailShowLocationIcon": "Vis stad-ikon", + "@settingsThumbnailShowLocationIcon": {}, + "settingsThumbnailShowFavouriteIcon": "Vis likt-ikon", + "@settingsThumbnailShowFavouriteIcon": {}, + "settingsImageBackground": "Biletbakgrunn", + "@settingsImageBackground": {}, + "settingsViewerQuickActionsTile": "Kvikkgjerder", + "@settingsViewerQuickActionsTile": {}, + "settingsViewerShowRatingTags": "Vis omdøme og merke", + "@settingsViewerShowRatingTags": {}, + "settingsViewerQuickActionEditorAvailableButtonsSectionTitle": "Tilgjengelege knappar", + "@settingsViewerQuickActionEditorAvailableButtonsSectionTitle": {}, + "saveCopyButtonLabel": "SPAR KOPI", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Nytt", + "@applyTooltip": {}, + "editorActionTransform": "Form om", + "@editorActionTransform": {}, + "editorTransformCrop": "Klipp til", + "@editorTransformCrop": {}, + "editorTransformRotate": "Snu", + "@editorTransformRotate": {}, + "maxBrightnessNever": "Aldri", + "@maxBrightnessNever": {}, + "wallpaperTargetHomeLock": "Heim- og låseskjermane", + "@wallpaperTargetHomeLock": {}, + "sortOrderAtoZ": "A-Å", + "@sortOrderAtoZ": {}, + "createAlbumButtonLabel": "LAG", + "@createAlbumButtonLabel": {}, + "countryPageTitle": "Land", + "@countryPageTitle": {}, + "countryEmpty": "Ingen land", + "@countryEmpty": {}, + "tagEmpty": "Ingen merke", + "@tagEmpty": {}, + "newVaultWarningDialogMessage": "Ting i kvelva er berre tilgjengelege for denne appen.\n\nOm du slettar denne appen eller tømmer dataa til denne appen, vil du missa alt som er i kvelva.", + "@newVaultWarningDialogMessage": {}, + "newVaultDialogTitle": "Nytt kvelv", + "@newVaultDialogTitle": {}, + "configureVaultDialogTitle": "Set opp kvelvet", + "@configureVaultDialogTitle": {}, + "vaultDialogLockModeWhenScreenOff": "Lås når skjermen slår seg av", + "@vaultDialogLockModeWhenScreenOff": {}, + "sortOrderLowestFirst": "Lægste først", + "@sortOrderLowestFirst": {}, + "maxBrightnessAlways": "Heile tida", + "@maxBrightnessAlways": {}, + "videoResumptionModeAlways": "Kvar gong", + "@videoResumptionModeAlways": {}, + "vaultDialogLockTypeLabel": "Låseslag", + "@vaultDialogLockTypeLabel": {}, + "pinDialogConfirm": "Stadfest talkoden", + "@pinDialogConfirm": {}, + "passwordDialogEnter": "Skriv inn passordet", + "@passwordDialogEnter": {}, + "vaultBinUsageDialogMessage": "Nokre kvelv nyttar papirkorga.", + "@vaultBinUsageDialogMessage": {}, + "mapEmptyRegion": "Ingen bilete i dette området", + "@mapEmptyRegion": {}, + "exportEntryDialogQuality": "Kvalitet", + "@exportEntryDialogQuality": {}, + "tooManyItemsErrorDialogMessage": "Røyn att med færre ting.", + "@tooManyItemsErrorDialogMessage": {}, + "aboutLicensesShowAllButtonLabel": "Vis alle løyve", + "@aboutLicensesShowAllButtonLabel": {}, + "collectionActionEdit": "Brigd", + "@collectionActionEdit": {}, + "collectionSearchTitlesHintText": "Søk etter namn", + "@collectionSearchTitlesHintText": {}, + "collectionGroupDay": "Etter dag", + "@collectionGroupDay": {}, + "collectionMoveFailureFeedback": "{count, plural, other{Kunne ikkje flytta {count} ting}}", + "@collectionMoveFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "collectionRenameFailureFeedback": "{count, plural, other{Kunne ikkje byta namn på {count} ting}}", + "@collectionRenameFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsAskEverytime": "Spør kvar gong", + "@settingsAskEverytime": {}, + "settingsThumbnailShowRating": "Vis omdøme", + "@settingsThumbnailShowRating": {}, + "settingsThumbnailShowRawIcon": "Vis rå-ikon", + "@settingsThumbnailShowRawIcon": {}, + "settingsCollectionQuickActionEditorPageTitle": "Kvikkgjerder", + "@settingsCollectionQuickActionEditorPageTitle": {}, + "settingsCollectionSelectionQuickActionEditorBanner": "Trykk og hald for å flytta knappane og velja kva for slags gjerder som skal visast når du vel ting.", + "@settingsCollectionSelectionQuickActionEditorBanner": {}, + "settingsCollectionQuickActionTabBrowsing": "Gjennomsyn", + "@settingsCollectionQuickActionTabBrowsing": {}, + "settingsThumbnailShowMotionPhotoIcon": "Vis rørslebilete-ikon", + "@settingsThumbnailShowMotionPhotoIcon": {}, + "settingsViewerQuickActionEditorBanner": "Trykk og hald for å flytta knappane og velja kva for slags gjerder som skal visast i visinga.", + "@settingsViewerQuickActionEditorBanner": {}, + "settingsViewerSlideshowTile": "Ljosbiletevising", + "@settingsViewerSlideshowTile": {}, + "settingsViewerMaximumBrightness": "Full ljosstyrke", + "@settingsViewerMaximumBrightness": {}, + "settingsViewerUseCutout": "Nytt utklipt område", + "@settingsViewerUseCutout": {}, + "settingsVideoPlaybackTile": "Avspeling", + "@settingsVideoPlaybackTile": {}, + "settingsVideoPlaybackPageTitle": "Avspeling", + "@settingsVideoPlaybackPageTitle": {}, + "settingsVideoLoopModeDialogTitle": "Gjentak", + "@settingsVideoLoopModeDialogTitle": {}, + "settingsVideoResumptionModeTile": "Spel av der du slapp", + "@settingsVideoResumptionModeTile": {}, + "settingsVideoResumptionModeDialogTitle": "Spel av der du slapp", + "@settingsVideoResumptionModeDialogTitle": {}, + "settingsVideoControlsPageTitle": "Styring", + "@settingsVideoControlsPageTitle": {}, + "settingsVideoGestureDoubleTapTogglePlay": "Dobbeltrykk for å spela/stansa", + "@settingsVideoGestureDoubleTapTogglePlay": {}, + "settingsVideoGestureVerticalDragBrightnessVolume": "Dra opp eller ned for å brigde ljos-/ljodstyrken", + "@settingsVideoGestureVerticalDragBrightnessVolume": {}, + "settingsVideoButtonsTile": "Knappar", + "@settingsVideoButtonsTile": {}, + "settingsSubtitleThemeTextPositionDialogTitle": "Tekststad", + "@settingsSubtitleThemeTextPositionDialogTitle": {}, + "settingsSubtitleThemeTextSize": "Tekststorleik", + "@settingsSubtitleThemeTextSize": {}, + "settingsHiddenPathsBanner": "Bilete og videoar i desse mappene, og undermappene deiras, vert ikkje viste i samlinga di.", + "@settingsHiddenPathsBanner": {}, + "settingsAccessibilitySectionTitle": "Tilgjenge", + "@settingsAccessibilitySectionTitle": {}, + "settingsStorageAccessRevokeTooltip": "Fråta", + "@settingsStorageAccessRevokeTooltip": {}, + "settingsStorageAccessEmpty": "Ingen gjevne tilgjenge", + "@settingsStorageAccessEmpty": {}, + "settingsDisplayRefreshRateModeTile": "Rørslejamleiken til skjermen", + "@settingsDisplayRefreshRateModeTile": {}, + "tagEditorDiscardDialogMessage": "Vil du avvisa brigda?", + "@tagEditorDiscardDialogMessage": {}, + "sortByName": "Etter namn", + "@sortByName": {}, + "sortByItemCount": "Etter mengd ting", + "@sortByItemCount": {}, + "albumGroupVolume": "Etter gøymestad", + "@albumGroupVolume": {}, + "searchTagsSectionTitle": "Merke", + "@searchTagsSectionTitle": {}, + "settingsSearchFieldLabel": "Søkjeinnstillingar", + "@settingsSearchFieldLabel": {}, + "settingsKeepScreenOnDialogTitle": "Hald skjermen slegen på", + "@settingsKeepScreenOnDialogTitle": {}, + "settingsDoubleBackExit": "Trykk «Attende» to gongar for å gå ut av appen", + "@settingsDoubleBackExit": {}, + "settingsNavigationDrawerTabPages": "Sider", + "@settingsNavigationDrawerTabPages": {}, + "settingsCollectionQuickActionsTile": "Kvikkgjerder", + "@settingsCollectionQuickActionsTile": {}, + "settingsThumbnailShowVideoDuration": "Vis videolengd", + "@settingsThumbnailShowVideoDuration": {}, + "settingsViewerGestureSideTapNext": "Trykk på skjermkantane for å visa førre/neste ting", + "@settingsViewerGestureSideTapNext": {}, + "settingsViewerQuickActionEditorPageTitle": "Kvikkgjerder", + "@settingsViewerQuickActionEditorPageTitle": {}, + "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "Viste knappar", + "@settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": {}, + "settingsViewerOverlayTile": "Overlag", + "@settingsViewerOverlayTile": {}, + "settingsSlideshowTransitionTile": "Overgang", + "@settingsSlideshowTransitionTile": {}, + "settingsStorageAccessPageTitle": "Gøymetilgjenge", + "@settingsStorageAccessPageTitle": {}, + "settingsDisplayUseTvInterface": "Android TV-grensesnitt", + "@settingsDisplayUseTvInterface": {}, + "settingsActionExport": "Før ut", + "@settingsActionExport": {}, + "settingsNavigationDrawerTabAlbums": "Album", + "@settingsNavigationDrawerTabAlbums": {}, + "settingsThumbnailOverlayPageTitle": "Overlag", + "@settingsThumbnailOverlayPageTitle": {}, + "editEntryDateDialogSetCustom": "Vel dato å setja", + "@editEntryDateDialogSetCustom": {}, + "aboutBugReportButton": "Rapporter", + "@aboutBugReportButton": {}, + "aboutLicensesSectionTitle": "Løyve til opne kjeldekodar", + "@aboutLicensesSectionTitle": {}, + "aboutLicensesFlutterPluginsSectionTitle": "Flutter-tillegg", + "@aboutLicensesFlutterPluginsSectionTitle": {}, + "collectionActionEmptyBin": "Tøm papirkorga", + "@collectionActionEmptyBin": {}, + "collectionActionCopy": "Kopier til album", + "@collectionActionCopy": {}, + "collectionCopySuccessFeedback": "{count, plural, other{Kopierte {count} ting}}", + "@collectionCopySuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "drawerAboutButton": "Om", + "@drawerAboutButton": {}, + "collectionEmptyImages": "Ingen bilete", + "@collectionEmptyImages": {}, + "collectionEmptyGrantAccessButtonLabel": "Gje tilgjenge", + "@collectionEmptyGrantAccessButtonLabel": {}, + "drawerCollectionVideos": "Videoar", + "@drawerCollectionVideos": {}, + "drawerCountryPage": "Land", + "@drawerCountryPage": {}, + "sortOrderZtoA": "Å-A", + "@sortOrderZtoA": {}, + "sortOrderHighestFirst": "Høgste først", + "@sortOrderHighestFirst": {}, + "albumMimeTypeMixed": "Blanda", + "@albumMimeTypeMixed": {}, + "albumPickPageTitlePick": "Vel album", + "@albumPickPageTitlePick": {}, + "albumScreenshots": "Skjermbilete", + "@albumScreenshots": {}, + "settingsHomeTile": "Heim", + "@settingsHomeTile": {}, + "settingsViewerOverlayPageTitle": "Overlag", + "@settingsViewerOverlayPageTitle": {}, + "settingsViewerSlideshowPageTitle": "Ljosbiletevising", + "@settingsViewerSlideshowPageTitle": {}, + "settingsSlideshowRepeat": "Gjentak", + "@settingsSlideshowRepeat": {}, + "settingsVideoPageTitle": "Videoinnstillingar", + "@settingsVideoPageTitle": {}, + "settingsVideoSectionTitle": "Video", + "@settingsVideoSectionTitle": {}, + "settingsSubtitleThemeTile": "Undertekster", + "@settingsSubtitleThemeTile": {}, + "settingsSubtitleThemePageTitle": "Undertekster", + "@settingsSubtitleThemePageTitle": {}, + "settingsSubtitleThemeSample": "Dette er eit døme.", + "@settingsSubtitleThemeSample": {}, + "settingsSubtitleThemeTextPositionTile": "Tekststad", + "@settingsSubtitleThemeTextPositionTile": {}, + "settingsSubtitleThemeTextAlignmentLeft": "Venstre", + "@settingsSubtitleThemeTextAlignmentLeft": {}, + "settingsSubtitleThemeBackgroundOpacity": "Bakgrunnsgjennomsyn", + "@settingsSubtitleThemeBackgroundOpacity": {}, + "settingsAllowInstalledAppAccess": "Gje tilgjenge til lista over innlagde appar", + "@settingsAllowInstalledAppAccess": {}, + "settingsAllowInstalledAppAccessSubtitle": "Vert nytta til å betre albumsvisinga", + "@settingsAllowInstalledAppAccessSubtitle": {}, + "settingsSaveSearchHistory": "Spar søkjehistorikken", + "@settingsSaveSearchHistory": {}, + "settingsAllowErrorReporting": "Send inn anonyme feilrapportar", + "@settingsAllowErrorReporting": {}, + "collectionSelectSectionTooltip": "Vel utvalet", + "@collectionSelectSectionTooltip": {}, + "settingsCollectionBrowsingQuickActionEditorBanner": "Trykk og hald for å flytta knappane og velja kva for slags gjerder som skal visast når du ser igjennom ting.", + "@settingsCollectionBrowsingQuickActionEditorBanner": {}, + "settingsMotionPhotoAutoPlay": "Spel av rørslebilete sjølvverkande", + "@settingsMotionPhotoAutoPlay": {}, + "settingsViewerShowDescription": "Vis utgreiingar", + "@settingsViewerShowDescription": {}, + "settingsViewerShowInformationSubtitle": "Vis namn, dato, stad, osv …", + "@settingsViewerShowInformationSubtitle": {}, + "settingsThemeBrightnessDialogTitle": "Ham", + "@settingsThemeBrightnessDialogTitle": {}, + "settingsThemeBrightnessTile": "Ham", + "@settingsThemeBrightnessTile": {}, + "viewerInfoLabelDescription": "Utgreiing", + "@viewerInfoLabelDescription": {}, + "passwordDialogConfirm": "Stadfest passordet", + "@passwordDialogConfirm": {}, + "drawerCollectionImages": "Bilete", + "@drawerCollectionImages": {}, + "settingsConfirmationDialogTitle": "Stadfestingsvindaugo", + "@settingsConfirmationDialogTitle": {}, + "settingsConfirmationBeforeDeleteItems": "Verta spurd før du slettar noko for godt", + "@settingsConfirmationBeforeDeleteItems": {}, + "settingsStorageAccessTile": "Gøymetilgjenge", + "@settingsStorageAccessTile": {}, + "tagPlaceholderState": "Landsdel", + "@tagPlaceholderState": {}, + "chipActionShowCountryStates": "Vis landsdelar", + "@chipActionShowCountryStates": {}, + "viewerActionLock": "Lås visinga", + "@viewerActionLock": {}, + "viewerActionUnlock": "Lås opp visinga", + "@viewerActionUnlock": {}, + "albumTierVaults": "Kvelv", + "@albumTierVaults": {}, + "lengthUnitPercent": "%", + "@lengthUnitPercent": {}, + "collectionPickPageTitle": "Vel", + "@collectionPickPageTitle": {}, + "collectionSelectPageTitle": "Vel ting", + "@collectionSelectPageTitle": {}, + "collectionActionAddShortcut": "Legg til snarveg", + "@collectionActionAddShortcut": {}, + "collectionDeleteFailureFeedback": "{count, plural, other{Kunne ikkje slette {count} ting}}", + "@collectionDeleteFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "collectionCopyFailureFeedback": "{count, plural, other{Kunne ikkje kopiera {count} ting}}", + "@collectionCopyFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "collectionEditSuccessFeedback": "{count, plural, other{Brigda {count} ting}}", + "@collectionEditSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "drawerSettingsButton": "Innstillingar", + "@drawerSettingsButton": {}, + "collectionDeselectSectionTooltip": "Fråvel utvalet", + "@collectionDeselectSectionTooltip": {}, + "drawerCollectionAll": "Alle samlingar", + "@drawerCollectionAll": {}, + "sortOrderSmallestFirst": "Smæste først", + "@sortOrderSmallestFirst": {}, + "albumPickPageTitleCopy": "Kopier til album", + "@albumPickPageTitleCopy": {}, + "drawerCollectionFavourites": "Likte", + "@drawerCollectionFavourites": {}, + "albumGroupTier": "Etter nivå", + "@albumGroupTier": {}, + "albumPickPageTitleMove": "Flytt til album", + "@albumPickPageTitleMove": {}, + "albumGroupType": "Etter slag", + "@albumGroupType": {}, + "albumCamera": "Kamera", + "@albumCamera": {}, + "albumDownload": "Hent", + "@albumDownload": {}, + "statePageTitle": "Landsdelar", + "@statePageTitle": {}, + "stateEmpty": "Ingen landsdelar", + "@stateEmpty": {}, + "placePageTitle": "Stadar", + "@placePageTitle": {}, + "placeEmpty": "Ingen stadar", + "@placeEmpty": {}, + "tagPageTitle": "Merke", + "@tagPageTitle": {}, + "binPageTitle": "Papirkorga", + "@binPageTitle": {}, + "searchCollectionFieldHint": "Søk i samlinga", + "@searchCollectionFieldHint": {}, + "addPathTooltip": "Legg til mappe", + "@addPathTooltip": {}, + "settingsTimeToTakeActionTile": "Tid for å gjera", + "@settingsTimeToTakeActionTile": {}, + "searchStatesSectionTitle": "Landsdelar", + "@searchStatesSectionTitle": {}, + "searchPlacesSectionTitle": "Stadar", + "@searchPlacesSectionTitle": {}, + "searchRatingSectionTitle": "Omdøme", + "@searchRatingSectionTitle": {}, + "searchMetadataSectionTitle": "Metadata", + "@searchMetadataSectionTitle": {}, + "settingsPageTitle": "Innstillingar", + "@settingsPageTitle": {}, + "settingsSystemDefault": "Systemforval", + "@settingsSystemDefault": {}, + "settingsDefault": "Forval", + "@settingsDefault": {}, + "settingsDisabled": "Slegen av", + "@settingsDisabled": {}, + "settingsModificationWarningDialogMessage": "Andre innstillingar vil brigdast.", + "@settingsModificationWarningDialogMessage": {}, + "settingsSearchEmpty": "Ingen samsvarande innstilling", + "@settingsSearchEmpty": {}, + "settingsActionExportDialogTitle": "Før ut", + "@settingsActionExportDialogTitle": {}, + "settingsActionImport": "Før inn", + "@settingsActionImport": {}, + "settingsActionImportDialogTitle": "Før inn", + "@settingsActionImportDialogTitle": {}, + "appExportCovers": "Omslag", + "@appExportCovers": {}, + "appExportFavourites": "Likte ting", + "@appExportFavourites": {}, + "appExportSettings": "Innstillingar", + "@appExportSettings": {}, + "settingsHomeDialogTitle": "Heim", + "@settingsHomeDialogTitle": {}, + "settingsConfirmationTile": "Stadfestingsvindaugo", + "@settingsConfirmationTile": {}, + "settingsVideoGestureSideDoubleTapSeek": "Dobbeltrykk på skjermkantane for å hoppe framover/bakover", + "@settingsVideoGestureSideDoubleTapSeek": {}, + "settingsSubtitleThemeTextColor": "Tekstleten", + "@settingsSubtitleThemeTextColor": {}, + "settingsSubtitleThemeTextAlignmentRight": "Høgre", + "@settingsSubtitleThemeTextAlignmentRight": {}, + "settingsPrivacySectionTitle": "Personvern", + "@settingsPrivacySectionTitle": {}, + "settingsDisablingBinWarningDialogMessage": "Ting i papirkorga vil slettast for godt.", + "@settingsDisablingBinWarningDialogMessage": {}, + "settingsAllowMediaManagement": "La få handsame medium", + "@settingsAllowMediaManagement": {}, + "settingsHiddenItemsPageTitle": "Skjulte ting", + "@settingsHiddenItemsPageTitle": {}, + "lengthUnitPixel": "px", + "@lengthUnitPixel": {}, + "vaultLockTypePin": "Talkode", + "@vaultLockTypePin": {}, + "searchRecentSectionTitle": "Nylege", + "@searchRecentSectionTitle": {}, + "searchDateSectionTitle": "Dato", + "@searchDateSectionTitle": {}, + "settingsConfirmationBeforeMoveUndatedItems": "Verta spurd før du flyttar på ting utan dato", + "@settingsConfirmationBeforeMoveUndatedItems": {}, + "settingsEnableBin": "Nytt papirkorga", + "@settingsEnableBin": {}, + "chipActionLock": "Lås", + "@chipActionLock": {}, + "sortByAlbumFileName": "Etter album og filnamn", + "@sortByAlbumFileName": {}, + "aboutBugReportInstruction": "Rapporter på GitHub med loggføringene og systemopplysingane dine", + "@aboutBugReportInstruction": {}, + "aboutLinkPolicy": "Personvernutsegn", + "@aboutLinkPolicy": {}, + "collectionPageTitle": "Samling", + "@collectionPageTitle": {}, + "collectionRenameSuccessFeedback": "{count, plural, =1{Bytte namnet til 1 ting} other{Bytte namna til {count} ting}}", + "@collectionRenameSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "drawerCollectionPanoramas": "Panorama", + "@drawerCollectionPanoramas": {}, + "drawerCollectionRaws": "Rå bilete", + "@drawerCollectionRaws": {}, + "drawerCollectionSphericalVideos": "360°-videoar", + "@drawerCollectionSphericalVideos": {}, + "drawerAlbumPage": "Album", + "@drawerAlbumPage": {}, + "drawerPlacePage": "Stadar", + "@drawerPlacePage": {}, + "albumPickPageTitleExport": "Før ut til album", + "@albumPickPageTitleExport": {}, + "albumPageTitle": "Album", + "@albumPageTitle": {}, + "newFilterBanner": "ny", + "@newFilterBanner": {}, + "settingsKeepScreenOnTile": "Hald skjermen slegen på", + "@settingsKeepScreenOnTile": {}, + "settingsThumbnailSectionTitle": "Småbilete", + "@settingsThumbnailSectionTitle": {}, + "settingsConfirmationBeforeMoveToBinItems": "Verta spurd før du kastar ting i papirkorga", + "@settingsConfirmationBeforeMoveToBinItems": {}, + "settingsNavigationDrawerTabTypes": "Slag", + "@settingsNavigationDrawerTabTypes": {}, + "settingsThumbnailOverlayTile": "Overlag", + "@settingsThumbnailOverlayTile": {}, + "settingsSubtitleThemeTextOpacity": "Tekstgjennomsyn", + "@settingsSubtitleThemeTextOpacity": {}, + "settingsSubtitleThemeBackgroundColor": "Bakgrunnsleten", + "@settingsSubtitleThemeBackgroundColor": {}, + "settingsSubtitleThemeTextAlignmentCenter": "Midten", + "@settingsSubtitleThemeTextAlignmentCenter": {}, + "settingsVideoControlsTile": "Styring", + "@settingsVideoControlsTile": {}, + "settingsViewerShowInformation": "Vis opplysingar", + "@settingsViewerShowInformation": {}, + "settingsViewerShowOverlayThumbnails": "Vis småbilete", + "@settingsViewerShowOverlayThumbnails": {}, + "settingsSlideshowShuffle": "Bland", + "@settingsSlideshowShuffle": {}, + "settingsVideoLoopModeTile": "Gjentak", + "@settingsVideoLoopModeTile": {}, + "settingsVideoAutoPlay": "Spel av med ein gong", + "@settingsVideoAutoPlay": {}, + "vaultLockTypePattern": "Mønster", + "@vaultLockTypePattern": {}, + "vaultLockTypePassword": "Passord", + "@vaultLockTypePassword": {}, + "patternDialogEnter": "Stryk inn eit mønster", + "@patternDialogEnter": {}, + "editEntryDialogTargetFieldsHeader": "Område å brigde", + "@editEntryDialogTargetFieldsHeader": {}, + "settingsCollectionQuickActionTabSelecting": "Veljing", + "@settingsCollectionQuickActionTabSelecting": {}, + "policyPageTitle": "Personvernutsegn", + "@policyPageTitle": {}, + "collectionActionRescan": "Gjennomsøk att", + "@collectionActionRescan": {}, + "dateToday": "I dag", + "@dateToday": {}, + "dateYesterday": "I går", + "@dateYesterday": {} } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 946d6043b..5a8cc2ea0 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1474,5 +1474,23 @@ "videoResumptionModeAlways": "Zawsze", "@videoResumptionModeAlways": {}, "exportEntryDialogQuality": "Jakość", - "@exportEntryDialogQuality": {} + "@exportEntryDialogQuality": {}, + "saveCopyButtonLabel": "ZAPISZ KOPIĘ", + "@saveCopyButtonLabel": {}, + "applyTooltip": "Zastosuj", + "@applyTooltip": {}, + "editorTransformRotate": "Obróć", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Dowolnie", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Oryginał", + "@cropAspectRatioOriginal": {}, + "editorActionTransform": "Przekształć", + "@editorActionTransform": {}, + "editorTransformCrop": "Przytnij", + "@editorTransformCrop": {}, + "cropAspectRatioSquare": "Kwadrat", + "@cropAspectRatioSquare": {}, + "widgetTapUpdateWidget": "Zaktualizuj widżet", + "@widgetTapUpdateWidget": {} } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 0e19f56ad..8ff4ec6f2 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1474,5 +1474,23 @@ "tagEditorDiscardDialogMessage": "Ви хочете відмовитися від змін?", "@tagEditorDiscardDialogMessage": {}, "videoResumptionModeAlways": "Завжди", - "@videoResumptionModeAlways": {} + "@videoResumptionModeAlways": {}, + "applyTooltip": "Застосувати", + "@applyTooltip": {}, + "saveCopyButtonLabel": "ЗБЕРЕГТИ КОПІЮ", + "@saveCopyButtonLabel": {}, + "editorActionTransform": "Перетворити", + "@editorActionTransform": {}, + "editorTransformCrop": "Обрізати", + "@editorTransformCrop": {}, + "editorTransformRotate": "Повернути", + "@editorTransformRotate": {}, + "cropAspectRatioFree": "Без змін", + "@cropAspectRatioFree": {}, + "cropAspectRatioOriginal": "Оригінал", + "@cropAspectRatioOriginal": {}, + "cropAspectRatioSquare": "Площа", + "@cropAspectRatioSquare": {}, + "widgetTapUpdateWidget": "Оновити віджет", + "@widgetTapUpdateWidget": {} } From 2609dd90158b9808f6f8417b4c7b69aa65b9b1d6 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 21 May 2023 20:09:01 +0200 Subject: [PATCH 28/35] l10n: nn --- CHANGELOG.md | 1 + .../android/nn/images/featureGraphic.png | Bin 0 -> 16651 bytes .../android/nn/images/phoneScreenshots/1.png | Bin 0 -> 287503 bytes .../android/nn/images/phoneScreenshots/2.png | Bin 0 -> 510706 bytes .../android/nn/images/phoneScreenshots/3.png | Bin 0 -> 207407 bytes .../android/nn/images/phoneScreenshots/4.png | Bin 0 -> 110897 bytes .../android/nn/images/phoneScreenshots/5.png | Bin 0 -> 72982 bytes .../android/nn/images/phoneScreenshots/6.png | Bin 0 -> 348430 bytes .../android/nn/images/phoneScreenshots/7.png | Bin 0 -> 343520 bytes lib/model/app/contributors.dart | 3 +- lib/widgets/aves_app.dart | 7 +- lib/widgets/settings/language/locales.dart | 1 + plugins/aves_map/pubspec.lock | 4 +- plugins/aves_services/pubspec.lock | 4 +- plugins/aves_services_google/pubspec.lock | 20 +- plugins/aves_services_huawei/pubspec.lock | 4 +- plugins/aves_services_none/pubspec.lock | 4 +- pubspec.lock | 61 +-- pubspec.yaml | 15 +- untranslated.json | 444 +----------------- 20 files changed, 66 insertions(+), 502 deletions(-) create mode 100644 fastlane/metadata/android/nn/images/featureGraphic.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/1.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/2.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/3.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/4.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/5.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/6.png create mode 100644 fastlane/metadata/android/nn/images/phoneScreenshots/7.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 3408d0272..1eb3cd86b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Info: added day filter with item date - Widget: option to update image on tap - Slideshow / Screen saver: option for random transition +- Norwegian (Nynorsk) translation (thanks tryvseu) ### Changed diff --git a/fastlane/metadata/android/nn/images/featureGraphic.png b/fastlane/metadata/android/nn/images/featureGraphic.png new file mode 100644 index 0000000000000000000000000000000000000000..e9e800f6b27ad69a82e06fe399d5f8dcfee67ebb GIT binary patch literal 16651 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 z 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 Zl9^VCTZ72XpmLxF22WQ%mvv4FO#qQuI#2)r literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/2.png b/fastlane/metadata/android/nn/images/phoneScreenshots/2.png new file mode 100644 index 0000000000000000000000000000000000000000..9fd360a649917d69658758460a7553a066f09664 GIT binary patch literal 510706 zcmV)SK(fDyP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 z 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⪼>q#^&s8F0 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

  • 6=TP38ri>%;D6ExnLNRR{zyp; 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 @_$Dz`h!;I<8$T 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�G^4M^ZMk>O>Bs#Z_qm3u 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%0DBJ$o+ePl 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 My85}Sb4q9e0Dx}3dH?_b literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/3.png b/fastlane/metadata/android/nn/images/phoneScreenshots/3.png new file mode 100644 index 0000000000000000000000000000000000000000..927ddecd030c3723d54fe36afc5f04d27d17c406 GIT binary patch literal 207407 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