diff --git a/.github/actions/flutter_build/action.yml b/.github/actions/flutter_build/action.yml index 81b2845949..66bfce44a5 100644 --- a/.github/actions/flutter_build/action.yml +++ b/.github/actions/flutter_build/action.yml @@ -63,7 +63,7 @@ runs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev libmpv-dev mpv elif [ "$RUNNER_OS" == "Windows" ]; then vcpkg integrate install elif [ "$RUNNER_OS" == "macOS" ]; then diff --git a/.github/actions/flutter_integration_test/action.yml b/.github/actions/flutter_integration_test/action.yml index 6df3ec005d..63066e0f38 100644 --- a/.github/actions/flutter_integration_test/action.yml +++ b/.github/actions/flutter_integration_test/action.yml @@ -52,7 +52,7 @@ runs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev network-manager + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev network-manager libmpv-dev mpv shell: bash - name: Enable Flutter Desktop diff --git a/.github/workflows/flutter_ci.yaml b/.github/workflows/flutter_ci.yaml index b944187ec4..c1cdd7bc17 100644 --- a/.github/workflows/flutter_ci.yaml +++ b/.github/workflows/flutter_ci.yaml @@ -89,6 +89,7 @@ jobs: with: os: ${{ matrix.os }} flutter_version: ${{ env.FLUTTER_VERSION }} + DISABLE_CI_TEST_LOG: "true" rust_toolchain: ${{ env.RUST_TOOLCHAIN }} cargo_make_version: ${{ env.CARGO_MAKE_VERSION }} rust_target: ${{ matrix.target }} @@ -172,7 +173,7 @@ jobs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev libmpv-dev mpv fi shell: bash @@ -202,6 +203,7 @@ jobs: - name: Run Flutter unit tests env: DISABLE_EVENT_LOG: true + DISABLE_CI_TEST_LOG: "true" working-directory: frontend run: | if [ "$RUNNER_OS" == "macOS" ]; then @@ -272,7 +274,7 @@ jobs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev libmpv-dev mpv shell: bash - name: Enable Flutter Desktop @@ -319,6 +321,12 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 + - name: Install video dependency + run: | + sudo apt-get update + sudo apt-get -y install libmpv-dev mpv + shell: bash + - name: Flutter Integration Test 1 uses: ./.github/actions/flutter_integration_test with: @@ -343,6 +351,12 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 + - name: Install video dependency + run: | + sudo apt-get update + sudo apt-get -y install libmpv-dev mpv + shell: bash + - name: Flutter Integration Test 2 uses: ./.github/actions/flutter_integration_test with: @@ -367,6 +381,12 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 + - name: Install video dependency + run: | + sudo apt-get update + sudo apt-get -y install libmpv-dev mpv + shell: bash + - name: Flutter Integration Test 3 uses: ./.github/actions/flutter_integration_test with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e91d95f969..3c589b2611 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -367,8 +367,8 @@ jobs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo apt-get update sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev - sudo apt-get install keybinder-3.0 libnotify-dev - sudo apt-get -y install alien + sudo apt-get install keybinder-3.0 + sudo apt-get install -y alien libnotify-dev libmpv-dev mpv source $HOME/.cargo/env cargo install --force cargo-make cargo install --force duckscript_cli diff --git a/.github/workflows/web2_ci.yaml b/.github/workflows/web2_ci.yaml index 68df8d805f..c52f71dd84 100644 --- a/.github/workflows/web2_ci.yaml +++ b/.github/workflows/web2_ci.yaml @@ -52,11 +52,11 @@ jobs: working-directory: frontend/appflowy_web_app run: | pnpm install - - name: test and lint + - name: Run lint check working-directory: frontend/appflowy_web_app run: | pnpm run lint - pnpm run test:unit + - name: build and analyze working-directory: frontend/appflowy_web_app run: | diff --git a/.github/workflows/web_cypress_ci.yaml b/.github/workflows/web_coverage.yaml similarity index 80% rename from .github/workflows/web_cypress_ci.yaml rename to .github/workflows/web_coverage.yaml index 15e52d3e8d..258119664a 100644 --- a/.github/workflows/web_cypress_ci.yaml +++ b/.github/workflows/web_coverage.yaml @@ -1,4 +1,4 @@ -name: Cypress Tests +name: Web Code Coverage on: pull_request: @@ -13,7 +13,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: - cypress-run: + test: if: github.event.pull_request.draft != true runs-on: ubuntu-22.04 steps: @@ -45,4 +45,15 @@ jobs: component: true build: pnpm run build start: pnpm run start - browser: chrome \ No newline at end of file + browser: chrome + + - name: Jest run + working-directory: frontend/appflowy_web_app + run: | + pnpm run test:unit + + - name: Generate and post coverage summary + working-directory: frontend/appflowy_web_app + run: | + pnpm run merge-coverage + diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 5a962f3cbf..a71ffec1fc 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -APPFLOWY_VERSION = "0.5.8" +APPFLOWY_VERSION = "0.5.9" FLUTTER_DESKTOP_FEATURES = "dart" PRODUCT_NAME = "AppFlowy" MACOSX_DEPLOYMENT_TARGET = "11.0" diff --git a/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml b/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml index 351994354d..279b17320c 100644 --- a/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml +++ b/frontend/appflowy_flutter/android/app/src/main/AndroidManifest.xml @@ -58,4 +58,11 @@ + + + \ No newline at end of file diff --git a/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart b/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart index 46550aa81a..958910dd80 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/settings/notifications_settings_test.dart @@ -8,8 +8,8 @@ import '../../shared/util.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('board add row test', () { - testWidgets('Add card from header', (tester) async { + group('notification test', () { + testWidgets('enable notification', (tester) async { await tester.initializeAppFlowy(); await tester.tapAnonymousSignInButton(); @@ -17,7 +17,7 @@ void main() { await tester.openSettingsPage(SettingsPage.notifications); await tester.pumpAndSettle(); - final switchFinder = find.byType(Switch); + final switchFinder = find.byType(Switch).first; // Defaults to enabled Switch switchWidget = tester.widget(switchFinder); diff --git a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_icon_test.dart b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_icon_test.dart index 1782c0d0ba..4659c98b55 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_icon_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_icon_test.dart @@ -18,6 +18,9 @@ void main() { // create document, board, grid and calendar views for (final value in ViewLayoutPB.values) { + if (value == ViewLayoutPB.Chat) { + continue; + } await tester.createNewPageWithNameUnderParent( name: value.name, parentName: gettingStarted, @@ -46,6 +49,9 @@ void main() { // create document, board, grid and calendar views for (final value in ViewLayoutPB.values) { + if (value == ViewLayoutPB.Chat) { + continue; + } await tester.createNewPageWithNameUnderParent( name: value.name, parentName: gettingStarted, diff --git a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test.dart b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test.dart index 158a8db882..006d7ff0b6 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/sidebar/sidebar_test.dart @@ -39,6 +39,9 @@ void main() { await tester.tapAnonymousSignInButton(); for (final layout in ViewLayoutPB.values) { + if (layout == ViewLayoutPB.Chat) { + continue; + } // create a new page final name = 'AppFlowy_$layout'; await tester.createNewPageWithNameUnderParent( @@ -66,6 +69,8 @@ void main() { case ViewLayoutPB.Calendar: expect(find.byType(CalendarPage), findsOneWidget); break; + case ViewLayoutPB.Chat: + break; } await tester.openPage(gettingStarted); diff --git a/frontend/appflowy_flutter/integration_test/shared/base.dart b/frontend/appflowy_flutter/integration_test/shared/base.dart index ab72247c24..bd2577b96c 100644 --- a/frontend/appflowy_flutter/integration_test/shared/base.dart +++ b/frontend/appflowy_flutter/integration_test/shared/base.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/services.dart'; @@ -36,6 +37,8 @@ extension AppFlowyTestBase on WidgetTester { AuthenticatorType? cloudType, String? email, }) async { + VideoBlockKit.ensureInitialized(); + if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) { // Set the window size await binding.setSurfaceSize(windowSize); diff --git a/frontend/appflowy_flutter/ios/Podfile.lock b/frontend/appflowy_flutter/ios/Podfile.lock index 93a8eb77e1..6f75b60ade 100644 --- a/frontend/appflowy_flutter/ios/Podfile.lock +++ b/frontend/appflowy_flutter/ios/Podfile.lock @@ -58,6 +58,12 @@ PODS: - Flutter - keyboard_height_plugin (0.0.1): - Flutter + - media_kit_libs_ios_video (1.0.4): + - Flutter + - media_kit_native_event_loop (1.0.0): + - Flutter + - media_kit_video (0.0.1): + - Flutter - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): @@ -66,6 +72,8 @@ PODS: - permission_handler_apple (9.3.0): - Flutter - ReachabilitySwift (5.0.0) + - screen_brightness_ios (0.1.0): + - Flutter - SDWebImage (5.14.2): - SDWebImage/Core (= 5.14.2) - SDWebImage/Core (5.14.2) @@ -83,6 +91,10 @@ PODS: - Toast (4.0.0) - url_launcher_ios (0.0.1): - Flutter + - volume_controller (0.0.1): + - Flutter + - wakelock_plus (0.0.1): + - Flutter DEPENDENCIES: - app_links (from `.symlinks/plugins/app_links/ios`) @@ -98,14 +110,20 @@ DEPENDENCIES: - integration_test (from `.symlinks/plugins/integration_test/ios`) - irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`) - keyboard_height_plugin (from `.symlinks/plugins/keyboard_height_plugin/ios`) + - media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`) + - media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`) + - media_kit_video (from `.symlinks/plugins/media_kit_video/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite (from `.symlinks/plugins/sqflite/darwin`) - super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - volume_controller (from `.symlinks/plugins/volume_controller/ios`) + - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) SPEC REPOS: trunk: @@ -143,12 +161,20 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/irondash_engine_context/ios" keyboard_height_plugin: :path: ".symlinks/plugins/keyboard_height_plugin/ios" + media_kit_libs_ios_video: + :path: ".symlinks/plugins/media_kit_libs_ios_video/ios" + media_kit_native_event_loop: + :path: ".symlinks/plugins/media_kit_native_event_loop/ios" + media_kit_video: + :path: ".symlinks/plugins/media_kit_video/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" + screen_brightness_ios: + :path: ".symlinks/plugins/screen_brightness_ios/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: @@ -159,6 +185,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/super_native_extensions/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" + volume_controller: + :path: ".symlinks/plugins/volume_controller/ios" + wakelock_plus: + :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: app_links: 5ef33d0d295a89d9d16bb81b0e3b0d5f70d6c875 @@ -170,16 +200,20 @@ SPEC CHECKSUMS: file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 flowy_infra_ui: 0455e1fa8c51885aa1437848e361e99419f34ebc Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265 + fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425 integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4 irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9 keyboard_height_plugin: 43fa8bba20fd5c4fdeed5076466b8b9d43cc6b86 + media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1 + media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a + media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 + screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625 SDWebImage: b9a731e1d6307f44ca703b3976d18c24ca561e84 share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 @@ -188,7 +222,9 @@ SPEC CHECKSUMS: SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 + volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9 + wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 PODFILE CHECKSUM: d0d9b4ff572d8695c38eb3f9b490f55cdfc57eca -COCOAPODS: 1.15.2 +COCOAPODS: 1.11.3 diff --git a/frontend/appflowy_flutter/ios/Runner/Info.plist b/frontend/appflowy_flutter/ios/Runner/Info.plist index 8c605b9d3a..5ec528b05e 100644 --- a/frontend/appflowy_flutter/ios/Runner/Info.plist +++ b/frontend/appflowy_flutter/ios/Runner/Info.plist @@ -66,5 +66,10 @@ UIViewControllerBasedStatusBarAppearance + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + \ No newline at end of file diff --git a/frontend/appflowy_flutter/lib/core/config/kv_keys.dart b/frontend/appflowy_flutter/lib/core/config/kv_keys.dart index ff97b61241..00e79153e4 100644 --- a/frontend/appflowy_flutter/lib/core/config/kv_keys.dart +++ b/frontend/appflowy_flutter/lib/core/config/kv_keys.dart @@ -65,6 +65,11 @@ class KVKeys { /// {'feature_flag_1': true, 'feature_flag_2': false} static const String featureFlag = 'featureFlag'; + /// The key for saving show notification icon option + /// + /// The value is a boolean string + static const String showNotificationIcon = 'showNotificationIcon'; + /// The key for saving the last opened workspace id /// /// The workspace id is a string. @@ -75,4 +80,15 @@ class KVKeys { /// /// The value is a double string. static const String scaleFactor = 'scaleFactor'; + + /// The key for saving the last opened space + /// + /// The value is a int string. + static const String lastOpenedSpace = 'lastOpenedSpace'; + + /// The key for saving the space order + /// + /// The value is a json string with the following format: + /// [0, 1, 2] + static const String spaceOrder = 'spaceOrder'; } diff --git a/frontend/appflowy_flutter/lib/core/frameless_window.dart b/frontend/appflowy_flutter/lib/core/frameless_window.dart index 7877615a98..fcd955fc93 100644 --- a/frontend/appflowy_flutter/lib/core/frameless_window.dart +++ b/frontend/appflowy_flutter/lib/core/frameless_window.dart @@ -3,12 +3,13 @@ import 'dart:io'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/window_title_bar.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class CocoaWindowChannel { @@ -102,13 +103,25 @@ class MoveWindowDetectorState extends State { return const SizedBox.shrink(); } + final color = Theme.of(context).isLightMode ? Colors.white : Colors.black; + final textSpan = TextSpan( + children: [ + TextSpan( + text: '${LocaleKeys.sideBar_openSidebar.tr()}\n', + style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: color), + ), + TextSpan( + text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Theme.of(context).hintColor), + ), + ], + ); + return FlowyTooltip( - richMessage: TextSpan( - children: [ - TextSpan(text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n'), - const TextSpan(text: 'Ctrl+\\'), - ], - ), + richMessage: textSpan, child: FlowyIconButton( hoverColor: Colors.transparent, onPressed: () => context diff --git a/frontend/appflowy_flutter/lib/main.dart b/frontend/appflowy_flutter/lib/main.dart index 9f140489c4..bee524b574 100644 --- a/frontend/appflowy_flutter/lib/main.dart +++ b/frontend/appflowy_flutter/lib/main.dart @@ -1,9 +1,12 @@ import 'package:scaled_app/scaled_app.dart'; +import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; + import 'startup/startup.dart'; Future main() async { ScaledWidgetsFlutterBinding.ensureInitialized(scaleFactor: (_) => 1.0); + VideoBlockKit.ensureInitialized(); await runAppFlowy(); } diff --git a/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart b/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart index 600dace29f..8b9f1e70ff 100644 --- a/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart +++ b/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart @@ -1,5 +1,7 @@ +import 'dart:async'; import 'dart:convert'; +import 'package:appflowy/mobile/presentation/chat/mobile_chat_screen.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:flutter/material.dart'; @@ -14,15 +16,15 @@ import 'package:go_router/go_router.dart'; extension MobileRouter on BuildContext { Future pushView(ViewPB view, [Map? arguments]) async { - await push( - Uri( - path: view.routeName, - queryParameters: view.queryParameters(arguments), - ).toString(), - ).then((value) { - getIt().latestOpenView = view; - getIt().updateRecentViews([view.id], true); - }); + // set the current view before pushing the new view + getIt().latestOpenView = view; + unawaited(getIt().updateRecentViews([view.id], true)); + + final uri = Uri( + path: view.routeName, + queryParameters: view.queryParameters(arguments), + ).toString(); + await push(uri); } } @@ -37,6 +39,9 @@ extension on ViewPB { return MobileCalendarScreen.routeName; case ViewLayoutPB.Board: return MobileBoardScreen.routeName; + case ViewLayoutPB.Chat: + return MobileChatScreen.routeName; + default: throw UnimplementedError('routeName for $this is not implemented'); } @@ -65,6 +70,11 @@ extension on ViewPB { MobileBoardScreen.viewId: id, MobileBoardScreen.viewTitle: name, }; + case ViewLayoutPB.Chat: + return { + MobileChatScreen.viewId: id, + MobileChatScreen.viewTitle: name, + }; default: throw UnimplementedError( 'queryParameters for $this is not implemented', diff --git a/frontend/appflowy_flutter/lib/mobile/application/recent/recent_view_bloc.dart b/frontend/appflowy_flutter/lib/mobile/application/recent/recent_view_bloc.dart index 410bc68c4e..547c81f00b 100644 --- a/frontend/appflowy_flutter/lib/mobile/application/recent/recent_view_bloc.dart +++ b/frontend/appflowy_flutter/lib/mobile/application/recent/recent_view_bloc.dart @@ -57,7 +57,19 @@ class RecentViewBloc extends Bloc { } }, ); + + // only document supports the cover + if (view.layout != ViewLayoutPB.Document) { + emit( + state.copyWith( + name: view.name, + icon: view.icon.value, + ), + ); + } + final cover = getCoverV2(); + if (cover != null) { emit( state.copyWith( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index 22b46ced57..591f708546 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -8,6 +8,7 @@ import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; import 'package:appflowy/plugins/document/presentation/document_collaborators.dart'; import 'package:appflowy/plugins/shared/sync_indicator.dart'; import 'package:appflowy/shared/feature_flags.dart'; +import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; @@ -154,7 +155,10 @@ class _MobileViewPageState extends State { (view) { final plugin = view.plugin(arguments: widget.arguments ?? const {}) ..init(); - return plugin.widgetBuilder.buildWidget(shrinkWrap: false); + return plugin.widgetBuilder.buildWidget( + shrinkWrap: false, + context: PluginContext(userProfile: state.userProfilePB), + ); }, (error) { return FlowyMobileStateContainer.error( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart index 37a5cb0221..18c5c3a6df 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart @@ -23,7 +23,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { text: LocaleKeys.document_menuName.tr(), leftIcon: const FlowySvg( FlowySvgs.document_s, - size: Size.square(20), + size: Size.square(18), ), showTopBorder: false, onTap: () => onAction(ViewLayoutPB.Document), @@ -32,7 +32,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { text: LocaleKeys.grid_menuName.tr(), leftIcon: const FlowySvg( FlowySvgs.grid_s, - size: Size.square(20), + size: Size.square(18), ), showTopBorder: false, onTap: () => onAction(ViewLayoutPB.Grid), @@ -41,7 +41,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { text: LocaleKeys.board_menuName.tr(), leftIcon: const FlowySvg( FlowySvgs.board_s, - size: Size.square(20), + size: Size.square(18), ), showTopBorder: false, onTap: () => onAction(ViewLayoutPB.Board), @@ -49,8 +49,8 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { FlowyOptionTile.text( text: LocaleKeys.calendar_menuName.tr(), leftIcon: const FlowySvg( - FlowySvgs.date_s, - size: Size.square(20), + FlowySvgs.calendar_s, + size: Size.square(18), ), showTopBorder: false, onTap: () => onAction(ViewLayoutPB.Calendar), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item.dart index c1e2560e48..75b0151a3a 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item.dart @@ -1,9 +1,17 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; +import 'package:appflowy/mobile/presentation/widgets/show_flowy_mobile_confirm_dialog.dart'; +import 'package:appflowy/startup/tasks/app_widget.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/recent/recent_views_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:fluttertoast/fluttertoast.dart'; enum MobileBottomSheetType { view, @@ -14,11 +22,13 @@ class MobileViewItemBottomSheet extends StatefulWidget { const MobileViewItemBottomSheet({ super.key, required this.view, + required this.actions, this.defaultType = MobileBottomSheetType.view, }); final ViewPB view; final MobileBottomSheetType defaultType; + final List actions; @override State createState() => @@ -27,12 +37,14 @@ class MobileViewItemBottomSheet extends StatefulWidget { class _MobileViewItemBottomSheetState extends State { MobileBottomSheetType type = MobileBottomSheetType.view; + final fToast = FToast(); @override void initState() { super.initState(); type = widget.defaultType; + fToast.init(AppGlobals.context); } @override @@ -40,6 +52,7 @@ class _MobileViewItemBottomSheetState extends State { switch (type) { case MobileBottomSheetType.view: return MobileViewItemBottomSheetBody( + actions: widget.actions, isFavorite: widget.view.isFavorite, onAction: (action) { switch (action) { @@ -59,7 +72,6 @@ class _MobileViewItemBottomSheetState extends State { case MobileViewItemBottomSheetBodyAction.delete: Navigator.pop(context); context.read().add(const ViewEvent.delete()); - break; case MobileViewItemBottomSheetBodyAction.addToFavorites: case MobileViewItemBottomSheetBodyAction.removeFromFavorites: @@ -68,6 +80,11 @@ class _MobileViewItemBottomSheetState extends State { .read() .add(FavoriteEvent.toggle(widget.view)); break; + case MobileViewItemBottomSheetBodyAction.removeFromRecent: + _removeFromRecent(context); + break; + case MobileViewItemBottomSheetBodyAction.divider: + break; } }, ); @@ -83,4 +100,74 @@ class _MobileViewItemBottomSheetState extends State { ); } } + + Future _removeFromRecent(BuildContext context) async { + final viewId = context.read().view.id; + final recentViewsBloc = context.read(); + Navigator.pop(context); + + await _showConfirmDialog( + onDelete: () { + recentViewsBloc.add(RecentViewsEvent.removeRecentViews([viewId])); + + fToast.showToast( + child: const _RemoveToast(), + positionedToastBuilder: (context, child) { + return Positioned.fill( + top: 450, + child: child, + ); + }, + ); + }, + ); + } + + Future _showConfirmDialog({required VoidCallback onDelete}) async { + await showFlowyCupertinoConfirmDialog( + title: LocaleKeys.sideBar_removePageFromRecent.tr(), + leftButton: FlowyText.regular( + LocaleKeys.button_cancel.tr(), + color: const Color(0xFF1456F0), + ), + rightButton: FlowyText.medium( + LocaleKeys.button_delete.tr(), + color: const Color(0xFFFE0220), + ), + onRightButtonPressed: (context) { + onDelete(); + Navigator.pop(context); + }, + ); + } +} + +class _RemoveToast extends StatelessWidget { + const _RemoveToast(); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 13.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.0), + color: const Color(0xE5171717), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const FlowySvg( + FlowySvgs.success_s, + blendMode: null, + ), + const HSpace(8.0), + FlowyText.regular( + LocaleKeys.sideBar_removeSuccess.tr(), + fontSize: 16.0, + color: Colors.white, + ), + ], + ), + ); + } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart index 624ae33b9f..d9c6382288 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart @@ -1,6 +1,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart'; +import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -11,6 +11,8 @@ enum MobileViewItemBottomSheetBodyAction { delete, addToFavorites, removeFromFavorites, + divider, + removeFromRecent, } class MobileViewItemBottomSheetBody extends StatelessWidget { @@ -18,63 +20,124 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { super.key, this.isFavorite = false, required this.onAction, + required this.actions, }); final bool isFavorite; final void Function(MobileViewItemBottomSheetBodyAction action) onAction; + final List actions; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - MobileQuickActionButton( - text: LocaleKeys.button_rename.tr(), - icon: FlowySvgs.m_rename_s, - onTap: () => onAction( - MobileViewItemBottomSheetBodyAction.rename, - ), - ), - _divider(), - MobileQuickActionButton( - text: isFavorite - ? LocaleKeys.button_removeFromFavorites.tr() - : LocaleKeys.button_addToFavorites.tr(), - icon: isFavorite - ? FlowySvgs.m_favorite_selected_lg - : FlowySvgs.m_favorite_unselected_lg, - iconColor: isFavorite ? Colors.yellow : null, - onTap: () => onAction( - isFavorite - ? MobileViewItemBottomSheetBodyAction.removeFromFavorites - : MobileViewItemBottomSheetBodyAction.addToFavorites, - ), - ), - _divider(), - MobileQuickActionButton( - text: LocaleKeys.button_duplicate.tr(), - icon: FlowySvgs.m_duplicate_s, - onTap: () => onAction( - MobileViewItemBottomSheetBodyAction.duplicate, - ), - ), - _divider(), - MobileQuickActionButton( - text: LocaleKeys.button_delete.tr(), - textColor: Theme.of(context).colorScheme.error, - icon: FlowySvgs.m_delete_s, - iconColor: Theme.of(context).colorScheme.error, - onTap: () => onAction( - MobileViewItemBottomSheetBodyAction.delete, - ), - ), - _divider(), - ], + children: + actions.map((action) => _buildActionButton(context, action)).toList(), ); } - Widget _divider() => const Divider( - height: 8.5, - thickness: 0.5, - ); + Widget _buildActionButton( + BuildContext context, + MobileViewItemBottomSheetBodyAction action, + ) { + switch (action) { + case MobileViewItemBottomSheetBodyAction.rename: + return FlowyOptionTile.text( + text: LocaleKeys.button_rename.tr(), + leftIcon: const FlowySvg( + FlowySvgs.view_item_rename_s, + size: Size.square(18), + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.rename, + ), + ); + case MobileViewItemBottomSheetBodyAction.duplicate: + return FlowyOptionTile.text( + text: LocaleKeys.button_duplicate.tr(), + leftIcon: const FlowySvg( + FlowySvgs.duplicate_s, + size: Size.square(18), + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.duplicate, + ), + ); + + case MobileViewItemBottomSheetBodyAction.share: + return FlowyOptionTile.text( + text: LocaleKeys.button_share.tr(), + leftIcon: const FlowySvg( + FlowySvgs.share_s, + size: Size.square(18), + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.share, + ), + ); + case MobileViewItemBottomSheetBodyAction.delete: + return FlowyOptionTile.text( + text: LocaleKeys.button_delete.tr(), + textColor: Theme.of(context).colorScheme.error, + leftIcon: FlowySvg( + FlowySvgs.delete_s, + size: const Size.square(18), + color: Theme.of(context).colorScheme.error, + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.delete, + ), + ); + case MobileViewItemBottomSheetBodyAction.addToFavorites: + return FlowyOptionTile.text( + text: LocaleKeys.button_addToFavorites.tr(), + leftIcon: const FlowySvg( + FlowySvgs.favorite_s, + size: Size.square(18), + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.addToFavorites, + ), + ); + case MobileViewItemBottomSheetBodyAction.removeFromFavorites: + return FlowyOptionTile.text( + text: LocaleKeys.button_removeFromFavorites.tr(), + leftIcon: const FlowySvg( + FlowySvgs.favorite_section_remove_from_favorite_s, + size: Size.square(18), + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.removeFromFavorites, + ), + ); + case MobileViewItemBottomSheetBodyAction.removeFromRecent: + return FlowyOptionTile.text( + text: LocaleKeys.button_removeFromRecent.tr(), + leftIcon: const FlowySvg( + FlowySvgs.remove_from_recent_s, + size: Size.square(18), + ), + showTopBorder: false, + showBottomBorder: false, + onTap: () => onAction( + MobileViewItemBottomSheetBodyAction.removeFromRecent, + ), + ); + + case MobileViewItemBottomSheetBodyAction.divider: + return const Divider(height: 0.5); + } + } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart index 80330de3c7..327db627c4 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart @@ -65,8 +65,21 @@ enum MobilePaneActionType { ], child: BlocBuilder( builder: (context, state) { + final isFavorite = state.view.isFavorite; return MobileViewItemBottomSheet( view: viewBloc.state.view, + actions: [ + isFavorite + ? MobileViewItemBottomSheetBodyAction + .removeFromFavorites + : MobileViewItemBottomSheetBodyAction + .addToFavorites, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.rename, + MobileViewItemBottomSheetBodyAction.duplicate, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.delete, + ], ); }, ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/chat/mobile_chat_screen.dart b/frontend/appflowy_flutter/lib/mobile/presentation/chat/mobile_chat_screen.dart new file mode 100644 index 0000000000..31fcbdcdfd --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/chat/mobile_chat_screen.dart @@ -0,0 +1,28 @@ +import 'package:appflowy/mobile/presentation/base/mobile_view_page.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:flutter/material.dart'; + +class MobileChatScreen extends StatelessWidget { + const MobileChatScreen({ + super.key, + required this.id, + this.title, + }); + + /// view id + final String id; + final String? title; + + static const routeName = '/chat'; + static const viewId = 'id'; + static const viewTitle = 'title'; + + @override + Widget build(BuildContext context) { + return MobileViewPage( + id: id, + title: title, + viewLayout: ViewLayoutPB.Chat, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart index f9fcba5754..ca012891f6 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart'; @@ -10,6 +8,7 @@ import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; @@ -17,14 +16,15 @@ class MobileFavoritePageFolder extends StatelessWidget { const MobileFavoritePageFolder({ super.key, required this.userProfile, - required this.workspaceId, }); final UserProfilePB userProfile; - final String workspaceId; @override Widget build(BuildContext context) { + final workspaceId = + context.read().state.currentWorkspace?.workspaceId ?? + ''; return MultiBlocProvider( providers: [ BlocProvider( @@ -67,7 +67,8 @@ class MobileFavoritePageFolder extends StatelessWidget { MobileFavoriteFolder( showHeader: false, forceExpanded: true, - views: favoriteState.views, + views: + favoriteState.views.map((e) => e.item).toList(), ), const VSpace(100.0), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart index 7afc740b45..e6d2d895b1 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_page.dart @@ -64,8 +64,6 @@ class MobileFavoriteScreen extends StatelessWidget { builder: (context, state) { return MobileFavoritePage( userProfile: userProfile, - workspaceId: state.currentWorkspace?.workspaceId ?? - workspaceSetting.workspaceId, ); }, ), @@ -81,11 +79,9 @@ class MobileFavoritePage extends StatelessWidget { const MobileFavoritePage({ super.key, required this.userProfile, - required this.workspaceId, }); final UserProfilePB userProfile; - final String workspaceId; @override Widget build(BuildContext context) { @@ -108,7 +104,6 @@ class MobileFavoritePage extends StatelessWidget { Expanded( child: MobileFavoritePageFolder( userProfile: userProfile, - workspaceId: workspaceId, ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart new file mode 100644 index 0000000000..684442a74a --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/favorite_space.dart @@ -0,0 +1,126 @@ +import 'package:appflowy/mobile/application/mobile_router.dart'; +import 'package:appflowy/mobile/presentation/home/shared/empty_placeholder.dart'; +import 'package:appflowy/mobile/presentation/home/shared/mobile_view_card.dart'; +import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/user/prelude.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class MobileFavoriteSpace extends StatefulWidget { + const MobileFavoriteSpace({ + super.key, + required this.userProfile, + }); + + final UserProfilePB userProfile; + + @override + State createState() => _MobileFavoriteSpaceState(); +} + +class _MobileFavoriteSpaceState extends State + with AutomaticKeepAliveClientMixin { + @override + bool get wantKeepAlive => true; + + @override + Widget build(BuildContext context) { + super.build(context); + final workspaceId = + context.read().state.currentWorkspace?.workspaceId ?? + ''; + return MultiBlocProvider( + providers: [ + BlocProvider( + create: (_) => SidebarSectionsBloc() + ..add( + SidebarSectionsEvent.initial(widget.userProfile, workspaceId), + ), + ), + BlocProvider( + create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()), + ), + ], + child: BlocListener( + listener: (context, state) => + context.read().add(const FavoriteEvent.initial()), + child: MultiBlocListener( + listeners: [ + BlocListener( + listenWhen: (p, c) => + p.lastCreatedRootView?.id != c.lastCreatedRootView?.id, + listener: (context, state) => + context.pushView(state.lastCreatedRootView!), + ), + ], + child: Builder( + builder: (context) { + final favoriteState = context.watch().state; + + if (favoriteState.isLoading) { + return const SizedBox.shrink(); + } + + if (favoriteState.views.isEmpty) { + return const EmptySpacePlaceholder( + type: MobileViewCardType.favorite, + ); + } + + return _FavoriteViews( + favoriteViews: favoriteState.views.reversed.toList(), + ); + }, + ), + ), + ), + ); + } +} + +class _FavoriteViews extends StatelessWidget { + const _FavoriteViews({ + required this.favoriteViews, + }); + + final List favoriteViews; + + @override + Widget build(BuildContext context) { + return Scrollbar( + child: ListView.separated( + key: const PageStorageKey('favorite_views_page_storage_key'), + padding: const EdgeInsets.symmetric( + horizontal: HomeSpaceViewSizes.mHorizontalPadding, + ), + itemBuilder: (context, index) { + final view = favoriteViews[index]; + return Container( + padding: const EdgeInsets.symmetric(vertical: 24.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5, + ), + ), + ), + child: MobileViewCard( + key: ValueKey(view.item.id), + view: view.item, + timestamp: view.timestamp, + type: MobileViewCardType.favorite, + ), + ); + }, + separatorBuilder: (context, index) => const HSpace(8), + itemCount: favoriteViews.length, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/home_space/home_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/home_space/home_space.dart new file mode 100644 index 0000000000..6ba27a6766 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/home_space/home_space.dart @@ -0,0 +1,44 @@ +import 'package:appflowy/mobile/presentation/home/mobile_folders.dart'; +import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class MobileHomeSpace extends StatefulWidget { + const MobileHomeSpace({super.key, required this.userProfile}); + + final UserProfilePB userProfile; + + @override + State createState() => _MobileHomeSpaceState(); +} + +class _MobileHomeSpaceState extends State + with AutomaticKeepAliveClientMixin { + @override + bool get wantKeepAlive => true; + + @override + Widget build(BuildContext context) { + super.build(context); + final workspaceId = + context.read().state.currentWorkspace?.workspaceId ?? + ''; + return Scrollbar( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: HomeSpaceViewSizes.mHorizontalPadding, + vertical: HomeSpaceViewSizes.mVerticalPadding, + ), + child: MobileFolders( + user: widget.userProfile, + workspaceId: workspaceId, + showFavorite: false, + ), + ), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart index 6e695ea0e4..100649701d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart @@ -1,5 +1,7 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; +import 'package:appflowy/mobile/presentation/home/home.dart'; import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; @@ -11,6 +13,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; +import 'package:go_router/go_router.dart'; // Contains Public And Private Sections class MobileFolders extends StatelessWidget { @@ -87,7 +90,8 @@ class MobileFolders extends StatelessWidget { views: state.section.publicViews, ), ], - const VSpace(8.0), + const VSpace(4.0), + const _TrashButton(), ], ), ); @@ -97,3 +101,28 @@ class MobileFolders extends StatelessWidget { ); } } + +class _TrashButton extends StatelessWidget { + const _TrashButton(); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 52, + child: FlowyButton( + expand: true, + margin: const EdgeInsets.symmetric(vertical: 8), + leftIcon: const FlowySvg( + FlowySvgs.m_delete_s, + ), + leftIconSize: const Size.square(18), + iconPadding: 10.0, + text: FlowyText.regular( + LocaleKeys.trash_text.tr(), + fontSize: 16.0, + ), + onTap: () => context.push(MobileHomeTrashPage.routeName), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart index 69759fc508..d01fada530 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart @@ -1,23 +1,22 @@ import 'dart:io'; -import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/mobile/presentation/home/home.dart'; -import 'package:appflowy/mobile/presentation/home/mobile_folders.dart'; import 'package:appflowy/mobile/presentation/home/mobile_home_page_header.dart'; -import 'package:appflowy/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart'; +import 'package:appflowy/mobile/presentation/home/tab/mobile_space_tab.dart'; +import 'package:appflowy/mobile/presentation/home/tab/space_order_bloc.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; +import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/recent/cached_recent_service.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; +import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; class MobileHomeScreen extends StatelessWidget { @@ -72,7 +71,7 @@ class MobileHomeScreen extends StatelessWidget { } } -class MobileHomePage extends StatelessWidget { +class MobileHomePage extends StatefulWidget { const MobileHomePage({ super.key, required this.userProfile, @@ -82,68 +81,67 @@ class MobileHomePage extends StatelessWidget { final UserProfilePB userProfile; final WorkspaceSettingPB workspaceSetting; + @override + State createState() => _MobileHomePageState(); +} + +class _MobileHomePageState extends State { + @override + void initState() { + super.initState(); + + getIt().addLatestViewListener(_onLatestViewChange); + } + + @override + void dispose() { + getIt().removeLatestViewListener(_onLatestViewChange); + super.dispose(); + } + @override Widget build(BuildContext context) { - return BlocProvider( - create: (_) => UserWorkspaceBloc(userProfile: userProfile) - ..add( - const UserWorkspaceEvent.initial(), + return MultiBlocProvider( + providers: [ + BlocProvider( + create: (_) => UserWorkspaceBloc(userProfile: widget.userProfile) + ..add(const UserWorkspaceEvent.initial()), ), - child: BlocBuilder( + BlocProvider( + create: (context) => + FavoriteBloc()..add(const FavoriteEvent.initial()), + ), + ], + child: BlocConsumer( buildWhen: (previous, current) => previous.currentWorkspace?.workspaceId != current.currentWorkspace?.workspaceId, + listener: (context, state) => getIt().reset(), builder: (context, state) { if (state.currentWorkspace == null) { return const SizedBox.shrink(); } + return Column( children: [ // Header Padding( padding: EdgeInsets.only( - left: 16, - right: 16, + left: HomeSpaceViewSizes.mHorizontalPadding, + right: 8.0, top: Platform.isAndroid ? 8.0 : 0.0, ), child: MobileHomePageHeader( - userProfile: userProfile, + userProfile: widget.userProfile, ), ), - const Divider(), - // Folder Expanded( - child: Scrollbar( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - // Recent files - const MobileRecentFolder(), - - // Folders - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: MobileFolders( - user: userProfile, - workspaceId: - state.currentWorkspace?.workspaceId ?? - workspaceSetting.workspaceId, - showFavorite: false, - ), - ), - const SizedBox(height: 8), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 24), - child: _TrashButton(), - ), - ], - ), - ), + child: BlocProvider( + create: (context) => + SpaceOrderBloc()..add(const SpaceOrderEvent.initial()), + child: MobileSpaceTab( + userProfile: widget.userProfile, ), ), ), @@ -153,26 +151,12 @@ class MobileHomePage extends StatelessWidget { ), ); } -} -class _TrashButton extends StatelessWidget { - const _TrashButton(); - - @override - Widget build(BuildContext context) { - return FlowyButton( - expand: true, - margin: const EdgeInsets.symmetric(vertical: 8), - leftIcon: FlowySvg( - FlowySvgs.m_delete_m, - color: Theme.of(context).colorScheme.onSurface, - ), - leftIconSize: const Size.square(24), - text: FlowyText.medium( - LocaleKeys.trash_text.tr(), - fontSize: 18.0, - ), - onTap: () => context.push(MobileHomeTrashPage.routeName), - ); + void _onLatestViewChange() async { + final id = getIt().latestOpenView?.id; + if (id == null) { + return; + } + await FolderEventSetLatestView(ViewIdPB(value: id)).send(); } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index be47ef1b32..5ae2ff1430 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -35,7 +35,7 @@ class MobileHomePageHeader extends StatelessWidget { final isCollaborativeWorkspace = context.read().state.isCollabWorkspaceOn; return ConstrainedBox( - constraints: const BoxConstraints(minHeight: 52), + constraints: const BoxConstraints(minHeight: 56), child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -44,11 +44,14 @@ class MobileHomePageHeader extends StatelessWidget { ? _MobileWorkspace(userProfile: userProfile) : _MobileUser(userProfile: userProfile), ), - IconButton( - onPressed: () => context.push( + GestureDetector( + onTap: () => context.push( MobileHomeSettingPage.routeName, ), - icon: const FlowySvg(FlowySvgs.m_setting_m), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: FlowySvg(FlowySvgs.m_setting_m), + ), ), ], ), @@ -119,7 +122,6 @@ class _MobileWorkspace extends StatelessWidget { }, child: Row( children: [ - const HSpace(2.0), SizedBox.square( dimension: 34.0, child: WorkspaceIcon( @@ -142,7 +144,7 @@ class _MobileWorkspace extends StatelessWidget { children: [ Row( children: [ - FlowyText.medium( + FlowyText.semibold( currentWorkspace.name, fontSize: 16.0, overflow: TextOverflow.ellipsis, @@ -151,7 +153,7 @@ class _MobileWorkspace extends StatelessWidget { const FlowySvg(FlowySvgs.list_dropdown_s), ], ), - FlowyText.medium( + FlowyText.regular( userProfile.email.isNotEmpty ? userProfile.email : userProfile.name, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart index fa585903f3..a2b9ae52c7 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart @@ -38,7 +38,8 @@ class _MobileRecentFolderState extends State { builder: (context, state) { final ids = {}; - List recentViews = state.views.reversed.toList(); + List recentViews = + state.views.reversed.map((e) => e.item).toList(); recentViews.retainWhere((element) => ids.add(element.id)); // only keep the first 20 items. diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart new file mode 100644 index 0000000000..3cab831c23 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart @@ -0,0 +1,96 @@ +import 'package:appflowy/mobile/presentation/home/shared/empty_placeholder.dart'; +import 'package:appflowy/mobile/presentation/home/shared/mobile_view_card.dart'; +import 'package:appflowy/workspace/application/recent/prelude.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class MobileRecentSpace extends StatefulWidget { + const MobileRecentSpace({super.key}); + + @override + State createState() => _MobileRecentSpaceState(); +} + +class _MobileRecentSpaceState extends State + with AutomaticKeepAliveClientMixin { + @override + bool get wantKeepAlive => true; + + @override + Widget build(BuildContext context) { + super.build(context); + return BlocProvider( + create: (context) => + RecentViewsBloc()..add(const RecentViewsEvent.initial()), + child: BlocBuilder( + builder: (context, state) { + if (state.isLoading) { + return const SizedBox.shrink(); + } + + final recentViews = _filterRecentViews(state.views); + + if (recentViews.isEmpty) { + return const Center( + child: EmptySpacePlaceholder(type: MobileViewCardType.recent), + ); + } + + return _RecentViews(recentViews: recentViews); + }, + ), + ); + } + + List _filterRecentViews(List recentViews) { + final ids = {}; + final filteredRecentViews = recentViews.reversed.toList(); + filteredRecentViews.retainWhere((e) => ids.add(e.item.id)); + return filteredRecentViews; + } +} + +class _RecentViews extends StatelessWidget { + const _RecentViews({ + required this.recentViews, + }); + + final List recentViews; + + @override + Widget build(BuildContext context) { + return Scrollbar( + child: ListView.separated( + key: const PageStorageKey('recent_views_page_storage_key'), + padding: const EdgeInsets.symmetric( + horizontal: HomeSpaceViewSizes.mHorizontalPadding, + ), + itemBuilder: (context, index) { + final sectionView = recentViews[index]; + return Container( + padding: const EdgeInsets.symmetric(vertical: 24.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5, + ), + ), + ), + child: MobileViewCard( + key: ValueKey(sectionView.item.id), + view: sectionView.item, + timestamp: sectionView.timestamp, + type: MobileViewCardType.recent, + ), + ); + }, + separatorBuilder: (context, index) => const HSpace(8), + itemCount: recentViews.length, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart index 4d9d109d3f..7a14a4d48d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart @@ -1,15 +1,12 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; -import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart'; import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; -import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -36,29 +33,28 @@ class MobileSectionFolder extends StatelessWidget { builder: (context, state) { return Column( children: [ - MobileSectionFolderHeader( - title: title, - isExpanded: context.read().state.isExpanded, - onPressed: () => context - .read() - .add(const FolderEvent.expandOrUnExpand()), - onAdded: () { - context.read().add( - SidebarSectionsEvent.createRootViewInSection( - name: - LocaleKeys.menuAppHeader_defaultNewPageName.tr(), - index: 0, - viewSection: spaceType.toViewSectionPB, - ), - ); - context.read().add( - const FolderEvent.expandOrUnExpand(isExpanded: true), - ); - }, - ), - const VSpace(8.0), - const Divider( - height: 1, + SizedBox( + height: HomeSpaceViewSizes.mViewHeight, + child: MobileSectionFolderHeader( + title: title, + isExpanded: context.read().state.isExpanded, + onPressed: () => context + .read() + .add(const FolderEvent.expandOrUnExpand()), + onAdded: () { + context.read().add( + SidebarSectionsEvent.createRootViewInSection( + name: LocaleKeys.menuAppHeader_defaultNewPageName + .tr(), + index: 0, + viewSection: spaceType.toViewSectionPB, + ), + ); + context.read().add( + const FolderEvent.expandOrUnExpand(isExpanded: true), + ); + }, + ), ), if (state.isExpanded) ...views.map( @@ -73,16 +69,6 @@ class MobileSectionFolder extends StatelessWidget { leftPadding: HomeSpaceViewSizes.leftPadding, isFeedback: false, onSelected: context.pushView, - endActionPane: (context) { - final view = context.read().state.view; - return buildEndActionPane(context, [ - MobilePaneActionType.delete, - view.isFavorite - ? MobilePaneActionType.removeFromFavorites - : MobilePaneActionType.addToFavorites, - MobilePaneActionType.more, - ]); - }, ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart index 3ba15df25d..49a9829d8a 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart @@ -1,4 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; @@ -29,24 +30,23 @@ class _MobileSectionFolderHeaderState extends State { @override Widget build(BuildContext context) { - const iconSize = 32.0; return Row( children: [ Expanded( child: FlowyButton( - text: FlowyText.semibold( + text: FlowyText.medium( widget.title, - fontSize: 20.0, + fontSize: 16.0, ), margin: const EdgeInsets.symmetric(vertical: 8), expandText: false, + iconPadding: 2, mainAxisAlignment: MainAxisAlignment.start, rightIcon: AnimatedRotation( duration: const Duration(milliseconds: 200), turns: _turns, - child: const Icon( - Icons.keyboard_arrow_down_rounded, - color: Colors.grey, + child: const FlowySvg( + FlowySvgs.m_spaces_expand_s, ), ), onTap: () { @@ -60,12 +60,10 @@ class _MobileSectionFolderHeaderState extends State { FlowyIconButton( key: mobileCreateNewPageButtonKey, hoverColor: Theme.of(context).colorScheme.secondaryContainer, - iconPadding: const EdgeInsets.all(2), - height: iconSize, - width: iconSize, + height: HomeSpaceViewSizes.mViewButtonDimension, + width: HomeSpaceViewSizes.mViewButtonDimension, icon: const FlowySvg( - FlowySvgs.add_s, - size: Size.square(iconSize), + FlowySvgs.m_space_add_s, ), onPressed: widget.onAdded, ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/empty_placeholder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/empty_placeholder.dart new file mode 100644 index 0000000000..e59fa87538 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/empty_placeholder.dart @@ -0,0 +1,55 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/presentation/home/shared/mobile_view_card.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; + +class EmptySpacePlaceholder extends StatelessWidget { + const EmptySpacePlaceholder({super.key, required this.type}); + + final MobileViewCardType type; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 48.0), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const FlowySvg( + FlowySvgs.m_empty_page_xl, + ), + const VSpace(16.0), + FlowyText.medium( + _emptyPageText, + fontSize: 18.0, + textAlign: TextAlign.center, + ), + const VSpace(8.0), + FlowyText.regular( + _emptyPageSubText, + fontSize: 17.0, + maxLines: 10, + textAlign: TextAlign.center, + lineHeight: 1.3, + color: Theme.of(context).hintColor, + ), + ], + ), + ); + } + + String get _emptyPageText => switch (type) { + MobileViewCardType.recent => LocaleKeys.sideBar_emptyRecent.tr(), + MobileViewCardType.favorite => LocaleKeys.sideBar_emptyFavorite.tr(), + }; + + String get _emptyPageSubText => switch (type) { + MobileViewCardType.recent => + LocaleKeys.sideBar_emptyRecentDescription.tr(), + MobileViewCardType.favorite => + LocaleKeys.sideBar_emptyFavoriteDescription.tr(), + }; +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart new file mode 100644 index 0000000000..c4498a27cd --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart @@ -0,0 +1,399 @@ +import 'dart:io'; + +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/application/mobile_router.dart'; +import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart'; +import 'package:appflowy/mobile/application/recent/recent_view_bloc.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy/shared/appflowy_network_image.dart'; +import 'package:appflowy/shared/flowy_gradient_colors.dart'; +import 'package:appflowy/util/string_extension.dart'; +import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/recent/recent_views_bloc.dart'; +import 'package:appflowy/workspace/application/view/view_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:fixnum/fixnum.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; +import 'package:string_validator/string_validator.dart'; + +enum MobileViewCardType { + recent, + favorite; + + String get lastOperationHintText => switch (this) { + MobileViewCardType.recent => LocaleKeys.sideBar_lastViewed.tr(), + MobileViewCardType.favorite => LocaleKeys.sideBar_favoriteAt.tr(), + }; +} + +class MobileViewCard extends StatelessWidget { + const MobileViewCard({ + super.key, + required this.view, + this.timestamp, + required this.type, + }); + + final ViewPB view; + final Int64? timestamp; + final MobileViewCardType type; + + @override + Widget build(BuildContext context) { + return MultiBlocProvider( + providers: [ + BlocProvider( + create: (context) => ViewBloc(view: view, shouldLoadChildViews: false) + ..add(const ViewEvent.initial()), + ), + BlocProvider( + create: (context) => + RecentViewBloc(view: view)..add(const RecentViewEvent.initial()), + ), + ], + child: BlocBuilder( + builder: (context, state) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTapUp: (_) => context.pushView(view), + onLongPressUp: () => _showActionSheet(context), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded(child: _buildDescription(context, state)), + const HSpace(20.0), + SizedBox( + width: 84, + height: 60, + child: _buildCover(context, state), + ), + ], + ), + ); + }, + ), + ); + } + + Widget _buildDescription(BuildContext context, RecentViewState state) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // page icon & page title + _buildTitle(context, state), + const VSpace(12.0), + // author & last viewed + _buildNameAndLastViewed(context, state), + ], + ); + } + + Widget _buildNameAndLastViewed(BuildContext context, RecentViewState state) { + final supportAvatar = isURL(state.icon); + if (!supportAvatar) { + return _buildLastViewed(context); + } + return Row( + children: [ + _buildAvatar(context, state), + Flexible(child: _buildAuthor(context, state)), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 3.0), + child: FlowySvg(FlowySvgs.dot_s), + ), + _buildLastViewed(context), + ], + ); + } + + Widget _buildAvatar(BuildContext context, RecentViewState state) { + final userProfile = Provider.of(context); + final iconUrl = userProfile?.iconUrl; + if (iconUrl == null || + iconUrl.isEmpty || + view.createdBy != userProfile?.id) { + return const SizedBox.shrink(); + } + + return Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2, right: 8), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.0), + child: SizedBox.square( + dimension: 16.0, + child: FlowyNetworkImage( + url: iconUrl, + ), + ), + ), + ); + } + + Widget _buildCover(BuildContext context, RecentViewState state) { + return ClipRRect( + borderRadius: BorderRadius.circular(8), + child: _ViewCover( + coverTypeV1: state.coverTypeV1, + coverTypeV2: state.coverTypeV2, + value: state.coverValue, + ), + ); + } + + Widget _buildTitle(BuildContext context, RecentViewState state) { + final name = state.name; + final icon = state.icon; + final fontFamily = Platform.isAndroid || Platform.isLinux + ? GoogleFonts.notoColorEmoji().fontFamily + : null; + return RichText( + maxLines: 3, + overflow: TextOverflow.ellipsis, + text: TextSpan( + children: [ + TextSpan( + text: icon, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontSize: 17.0, + fontWeight: FontWeight.w600, + fontFamily: fontFamily, + ), + ), + if (icon.isNotEmpty) const WidgetSpan(child: HSpace(2.0)), + TextSpan( + text: name, + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + fontSize: 16.0, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ); + } + + Widget _buildAuthor(BuildContext context, RecentViewState state) { + return FlowyText.regular( + // view.createdBy.toString(), + 'Lucas', + fontSize: 12.0, + color: Theme.of(context).hintColor, + overflow: TextOverflow.ellipsis, + ); + } + + Widget _buildLastViewed(BuildContext context) { + if (timestamp == null) { + return const SizedBox.shrink(); + } + final date = _formatTimestamp( + timestamp!.toInt() * 1000, + ); + return FlowyText.regular( + date, + fontSize: 12.0, + color: Theme.of(context).hintColor, + ); + } + + String _formatTimestamp(int timestamp) { + final now = DateTime.now(); + final dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp); + final difference = now.difference(dateTime); + final String date; + + if (difference.inMinutes < 1) { + date = LocaleKeys.sideBar_justNow.tr(); + } else if (difference.inHours < 1) { + // Less than 1 hour + date = LocaleKeys.sideBar_minutesAgo + .tr(namedArgs: {'count': difference.inMinutes.toString()}); + } else if (difference.inHours >= 1 && difference.inHours < 24) { + // Between 1 hour and 24 hours + date = DateFormat('h:mm a').format(dateTime); + } else if (difference.inDays >= 1 && dateTime.year == now.year) { + // More than 24 hours but within the current year + date = DateFormat('M/d, h:mm a').format(dateTime); + } else { + // Other cases (previous years) + date = DateFormat('M/d/yyyy, h:mm a').format(dateTime); + } + + if (difference.inHours >= 1) { + return '${type.lastOperationHintText} $date'; + } + + return date; + } + + Future _showActionSheet(BuildContext context) async { + final viewBloc = context.read(); + final favoriteBloc = context.read(); + final recentViewsBloc = context.read(); + await showMobileBottomSheet( + context, + showDragHandle: true, + showDivider: false, + backgroundColor: AFThemeExtension.of(context).background, + useRootNavigator: true, + builder: (context) { + return MultiBlocProvider( + providers: [ + BlocProvider.value(value: viewBloc), + BlocProvider.value(value: favoriteBloc), + if (recentViewsBloc != null) + BlocProvider.value(value: recentViewsBloc), + ], + child: BlocBuilder( + builder: (context, state) { + final isFavorite = state.view.isFavorite; + return MobileViewItemBottomSheet( + view: viewBloc.state.view, + actions: _buildActions(isFavorite), + ); + }, + ), + ); + }, + ); + } + + List _buildActions(bool isFavorite) { + switch (type) { + case MobileViewCardType.recent: + return [ + isFavorite + ? MobileViewItemBottomSheetBodyAction.removeFromFavorites + : MobileViewItemBottomSheetBodyAction.addToFavorites, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.duplicate, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.removeFromRecent, + ]; + case MobileViewCardType.favorite: + return [ + MobileViewItemBottomSheetBodyAction.removeFromFavorites, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.duplicate, + ]; + } + } +} + +class _ViewCover extends StatelessWidget { + const _ViewCover({ + required this.coverTypeV1, + this.coverTypeV2, + this.value, + }); + + final CoverType coverTypeV1; + final PageStyleCoverImageType? coverTypeV2; + final String? value; + + @override + Widget build(BuildContext context) { + final placeholder = Container( + color: const Color(0xFFE1FBFF), + ); + final value = this.value; + if (value == null) { + return placeholder; + } + if (coverTypeV2 != null) { + return _buildCoverV2(context, value, placeholder); + } + return _buildCoverV1(context, value, placeholder); + } + + Widget _buildCoverV2(BuildContext context, String value, Widget placeholder) { + final type = coverTypeV2; + if (type == null) { + return placeholder; + } + if (type == PageStyleCoverImageType.customImage || + type == PageStyleCoverImageType.unsplashImage) { + final userProfilePB = Provider.of(context); + return FlowyNetworkImage( + url: value, + userProfilePB: userProfilePB, + ); + } + + if (type == PageStyleCoverImageType.builtInImage) { + return Image.asset( + PageStyleCoverImageType.builtInImagePath(value), + fit: BoxFit.cover, + ); + } + + if (type == PageStyleCoverImageType.pureColor) { + final color = value.coverColor(context); + if (color != null) { + return ColoredBox( + color: color, + ); + } + } + + if (type == PageStyleCoverImageType.gradientColor) { + return Container( + decoration: BoxDecoration( + gradient: FlowyGradientColor.fromId(value).linear, + ), + ); + } + + if (type == PageStyleCoverImageType.localImage) { + return Image.file( + File(value), + fit: BoxFit.cover, + ); + } + + return placeholder; + } + + Widget _buildCoverV1(BuildContext context, String value, Widget placeholder) { + switch (coverTypeV1) { + case CoverType.file: + if (isURL(value)) { + final userProfilePB = Provider.of(context); + return FlowyNetworkImage( + url: value, + userProfilePB: userProfilePB, + ); + } + final imageFile = File(value); + if (!imageFile.existsSync()) { + return placeholder; + } + return Image.file( + imageFile, + ); + case CoverType.asset: + return Image.asset( + value, + fit: BoxFit.cover, + ); + case CoverType.color: + final color = value.tryToColor() ?? Colors.white; + return Container( + color: color, + ); + case CoverType.none: + return placeholder; + } + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/_round_underline_tab_indicator.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/_round_underline_tab_indicator.dart new file mode 100644 index 0000000000..1a3eb121f3 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/_round_underline_tab_indicator.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; + +class RoundUnderlineTabIndicator extends Decoration { + const RoundUnderlineTabIndicator({ + this.borderRadius, + this.borderSide = const BorderSide(width: 2.0, color: Colors.white), + this.insets = EdgeInsets.zero, + required this.width, + }); + + final BorderRadius? borderRadius; + final BorderSide borderSide; + final EdgeInsetsGeometry insets; + final double width; + + @override + Decoration? lerpFrom(Decoration? a, double t) { + if (a is UnderlineTabIndicator) { + return UnderlineTabIndicator( + borderSide: BorderSide.lerp(a.borderSide, borderSide, t), + insets: EdgeInsetsGeometry.lerp(a.insets, insets, t)!, + ); + } + return super.lerpFrom(a, t); + } + + @override + Decoration? lerpTo(Decoration? b, double t) { + if (b is UnderlineTabIndicator) { + return UnderlineTabIndicator( + borderSide: BorderSide.lerp(borderSide, b.borderSide, t), + insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!, + ); + } + return super.lerpTo(b, t); + } + + @override + BoxPainter createBoxPainter([VoidCallback? onChanged]) { + return _UnderlinePainter(this, borderRadius, onChanged); + } + + Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { + final Rect indicator = insets.resolve(textDirection).deflateRect(rect); + final center = indicator.center.dx; + return Rect.fromLTWH( + center - width / 2.0, + indicator.bottom - borderSide.width, + width, + borderSide.width, + ); + } + + @override + Path getClipPath(Rect rect, TextDirection textDirection) { + if (borderRadius != null) { + return Path() + ..addRRect( + borderRadius!.toRRect(_indicatorRectFor(rect, textDirection)), + ); + } + return Path()..addRect(_indicatorRectFor(rect, textDirection)); + } +} + +class _UnderlinePainter extends BoxPainter { + _UnderlinePainter( + this.decoration, + this.borderRadius, + super.onChanged, + ); + + final RoundUnderlineTabIndicator decoration; + final BorderRadius? borderRadius; + + @override + void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { + assert(configuration.size != null); + final Rect rect = offset & configuration.size!; + final TextDirection textDirection = configuration.textDirection!; + final Paint paint; + if (borderRadius != null) { + paint = Paint()..color = decoration.borderSide.color; + final Rect indicator = decoration._indicatorRectFor(rect, textDirection); + final RRect rrect = RRect.fromRectAndCorners( + indicator, + topLeft: borderRadius!.topLeft, + topRight: borderRadius!.topRight, + bottomRight: borderRadius!.bottomRight, + bottomLeft: borderRadius!.bottomLeft, + ); + canvas.drawRRect(rrect, paint); + } else { + paint = decoration.borderSide.toPaint()..strokeCap = StrokeCap.round; + final Rect indicator = decoration + ._indicatorRectFor(rect, textDirection) + .deflate(decoration.borderSide.width / 2.0); + canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint); + } + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/_tab_bar.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/_tab_bar.dart new file mode 100644 index 0000000000..adf13ed667 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/_tab_bar.dart @@ -0,0 +1,57 @@ +import 'package:appflowy/mobile/presentation/home/tab/_round_underline_tab_indicator.dart'; +import 'package:appflowy/mobile/presentation/home/tab/space_order_bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:reorderable_tabbar/reorderable_tabbar.dart'; + +class MobileSpaceTabBar extends StatelessWidget { + const MobileSpaceTabBar({ + super.key, + this.height = 38.0, + required this.tabController, + required this.tabs, + required this.onReorder, + }); + + final double height; + final List tabs; + final TabController tabController; + final OnReorder onReorder; + + @override + Widget build(BuildContext context) { + final baseStyle = Theme.of(context).textTheme.bodyMedium; + final labelStyle = baseStyle?.copyWith( + fontWeight: FontWeight.w500, + fontSize: 15.0, + ); + final unselectedLabelStyle = baseStyle?.copyWith( + fontWeight: FontWeight.w400, + fontSize: 15.0, + ); + + return Container( + height: height, + padding: const EdgeInsets.only(left: 8.0), + child: ReorderableTabBar( + controller: tabController, + tabs: tabs.map((e) => Tab(text: e.tr)).toList(), + indicatorSize: TabBarIndicatorSize.label, + indicatorColor: Theme.of(context).primaryColor, + isScrollable: true, + labelStyle: labelStyle, + labelColor: baseStyle?.color, + labelPadding: const EdgeInsets.symmetric(horizontal: 12.0), + unselectedLabelStyle: unselectedLabelStyle, + overlayColor: WidgetStateProperty.all(Colors.transparent), + indicator: RoundUnderlineTabIndicator( + width: 28.0, + borderSide: BorderSide( + color: Theme.of(context).primaryColor, + width: 3, + ), + ), + onReorder: onReorder, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/mobile_space_tab.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/mobile_space_tab.dart new file mode 100644 index 0000000000..097bd22910 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/mobile_space_tab.dart @@ -0,0 +1,107 @@ +import 'package:appflowy/mobile/presentation/home/favorite_folder/favorite_space.dart'; +import 'package:appflowy/mobile/presentation/home/home_space/home_space.dart'; +import 'package:appflowy/mobile/presentation/home/recent_folder/recent_space.dart'; +import 'package:appflowy/mobile/presentation/home/tab/_tab_bar.dart'; +import 'package:appflowy/mobile/presentation/home/tab/space_order_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; + +class MobileSpaceTab extends StatefulWidget { + const MobileSpaceTab({super.key, required this.userProfile}); + + final UserProfilePB userProfile; + + @override + State createState() => _MobileSpaceTabState(); +} + +class _MobileSpaceTabState extends State + with SingleTickerProviderStateMixin { + TabController? tabController; + + @override + void dispose() { + tabController?.removeListener(_onTabChange); + tabController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Provider.value( + value: widget.userProfile, + child: BlocBuilder( + builder: (context, state) { + if (state.isLoading) { + return const SizedBox.shrink(); + } + + _initTabController(state); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MobileSpaceTabBar( + tabController: tabController!, + tabs: state.tabsOrder, + onReorder: (from, to) { + context.read().add( + SpaceOrderEvent.reorder(from, to), + ); + }, + ), + const HSpace(12.0), + Expanded( + child: TabBarView( + controller: tabController, + children: _buildTabs(state), + ), + ), + ], + ); + }, + ), + ); + } + + void _initTabController(SpaceOrderState state) { + if (tabController != null) { + return; + } + tabController = TabController( + length: state.tabsOrder.length, + vsync: this, + initialIndex: state.tabsOrder.indexOf(state.defaultTab), + ); + tabController?.addListener(_onTabChange); + } + + void _onTabChange() { + if (tabController == null) { + return; + } + context.read().add( + SpaceOrderEvent.open( + tabController!.index, + ), + ); + } + + List _buildTabs(SpaceOrderState state) { + return state.tabsOrder.map((tab) { + switch (tab) { + case MobileSpaceTabType.recent: + return const MobileRecentSpace(); + case MobileSpaceTabType.spaces: + return MobileHomeSpace(userProfile: widget.userProfile); + case MobileSpaceTabType.favorites: + return MobileFavoriteSpace(userProfile: widget.userProfile); + default: + throw Exception('Unknown tab type: $tab'); + } + }).toList(); + } +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/space_order_bloc.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/space_order_bloc.dart new file mode 100644 index 0000000000..e3c1439dd4 --- /dev/null +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/tab/space_order_bloc.dart @@ -0,0 +1,127 @@ +import 'dart:convert'; + +import 'package:appflowy/core/config/kv.dart'; +import 'package:appflowy/core/config/kv_keys.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:bloc/bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'space_order_bloc.freezed.dart'; + +enum MobileSpaceTabType { + // DO NOT CHANGE THE ORDER + spaces, + recent, + favorites; + + String get tr { + switch (this) { + case MobileSpaceTabType.recent: + return LocaleKeys.sideBar_RecentSpace.tr(); + case MobileSpaceTabType.spaces: + return LocaleKeys.sideBar_Spaces.tr(); + case MobileSpaceTabType.favorites: + return LocaleKeys.sideBar_favoriteSpace.tr(); + } + } +} + +class SpaceOrderBloc extends Bloc { + SpaceOrderBloc() : super(const SpaceOrderState()) { + on( + (event, emit) async { + await event.when( + initial: () async { + final tabsOrder = await _getTabsOrder(); + final defaultTab = await _getDefaultTab(); + emit( + state.copyWith( + tabsOrder: tabsOrder, + defaultTab: defaultTab, + isLoading: false, + ), + ); + }, + open: (index) async { + final tab = state.tabsOrder[index]; + await _setDefaultTab(tab); + }, + reorder: (from, to) async { + final tabsOrder = List.of(state.tabsOrder); + tabsOrder.insert(to, tabsOrder.removeAt(from)); + await _setTabsOrder(tabsOrder); + emit(state.copyWith(tabsOrder: tabsOrder)); + }, + ); + }, + ); + } + + final _storage = getIt(); + + Future _getDefaultTab() async { + try { + return await _storage.getWithFormat( + KVKeys.lastOpenedSpace, (value) { + return MobileSpaceTabType.values[int.parse(value)]; + }) ?? + MobileSpaceTabType.spaces; + } catch (e) { + return MobileSpaceTabType.spaces; + } + } + + Future _setDefaultTab(MobileSpaceTabType tab) async { + await _storage.set( + KVKeys.lastOpenedSpace, + tab.index.toString(), + ); + } + + Future> _getTabsOrder() async { + try { + return await _storage.getWithFormat>( + KVKeys.spaceOrder, (value) { + final order = jsonDecode(value).cast(); + if (order.isEmpty) { + return MobileSpaceTabType.values; + } + return order + .map((e) => MobileSpaceTabType.values[e]) + .cast() + .toList(); + }) ?? + MobileSpaceTabType.values; + } catch (e) { + return MobileSpaceTabType.values; + } + } + + Future _setTabsOrder(List tabsOrder) async { + await _storage.set( + KVKeys.spaceOrder, + jsonEncode(tabsOrder.map((e) => e.index).toList()), + ); + } +} + +@freezed +class SpaceOrderEvent with _$SpaceOrderEvent { + const factory SpaceOrderEvent.initial() = Initial; + const factory SpaceOrderEvent.open(int index) = Open; + const factory SpaceOrderEvent.reorder(int from, int to) = Reorder; +} + +@freezed +class SpaceOrderState with _$SpaceOrderState { + const factory SpaceOrderState({ + @Default(MobileSpaceTabType.spaces) MobileSpaceTabType defaultTab, + @Default(MobileSpaceTabType.values) List tabsOrder, + @Default(true) bool isLoading, + }) = _SpaceOrderState; + + factory SpaceOrderState.initial() => const SpaceOrderState(); +} diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart b/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart index 101a546294..411623cb87 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart @@ -1,7 +1,37 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/application/mobile_router.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; +import 'package:appflowy/workspace/application/workspace/workspace_service.dart'; +import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +const _homeLabel = 'home'; +const _addLabel = 'add'; +const _notificationLabel = 'notification'; +final _items = [ + const BottomNavigationBarItem( + label: _homeLabel, + icon: FlowySvg(FlowySvgs.m_home_unselected_m), + activeIcon: FlowySvg(FlowySvgs.m_home_selected_m, blendMode: null), + ), + const BottomNavigationBarItem( + label: _addLabel, + icon: FlowySvg(FlowySvgs.m_home_add_m), + ), + const BottomNavigationBarItem( + label: _notificationLabel, + icon: FlowySvg(FlowySvgs.m_home_notification_m), + activeIcon: FlowySvg( + FlowySvgs.m_home_notification_m, + ), + ), +]; + /// Builds the "shell" for the app by building a Scaffold with a /// BottomNavigationBar, where [child] is placed in the body of the Scaffold. class MobileBottomNavigationBar extends StatelessWidget { @@ -16,53 +46,23 @@ class MobileBottomNavigationBar extends StatelessWidget { @override Widget build(BuildContext context) { - final style = Theme.of(context); - return Scaffold( body: navigationShell, - bottomNavigationBar: BottomNavigationBar( - showSelectedLabels: false, - showUnselectedLabels: false, - enableFeedback: true, - type: BottomNavigationBarType.fixed, - items: [ - BottomNavigationBarItem( - // There is no text shown on the bottom navigation bar, but Exception will be thrown if label is null here. - label: 'home', - icon: const FlowySvg(FlowySvgs.m_home_unselected_lg), - activeIcon: FlowySvg( - FlowySvgs.m_home_selected_lg, - color: style.colorScheme.primary, - ), - ), - const BottomNavigationBarItem( - label: 'favorite', - icon: FlowySvg(FlowySvgs.m_favorite_unselected_lg), - activeIcon: FlowySvg( - FlowySvgs.m_favorite_selected_lg, - blendMode: null, - ), - ), - // Enable this when search is ready. - // BottomNavigationBarItem( - // label: 'search', - // icon: const FlowySvg(FlowySvgs.m_search_lg), - // activeIcon: FlowySvg( - // FlowySvgs.m_search_lg, - // color: style.colorScheme.primary, - // ), - // ), - BottomNavigationBarItem( - label: 'notification', - icon: const FlowySvg(FlowySvgs.m_notification_unselected_lg), - activeIcon: FlowySvg( - FlowySvgs.m_notification_selected_lg, - color: style.colorScheme.primary, - ), - ), - ], - currentIndex: navigationShell.currentIndex, - onTap: (int bottomBarIndex) => _onTap(context, bottomBarIndex), + bottomNavigationBar: Theme( + data: Theme.of(context).copyWith( + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + ), + child: BottomNavigationBar( + showSelectedLabels: false, + showUnselectedLabels: false, + enableFeedback: false, + type: BottomNavigationBarType.fixed, + elevation: 0, + items: _items, + currentIndex: navigationShell.currentIndex, + onTap: (int bottomBarIndex) => _onTap(context, bottomBarIndex), + ), ), ); } @@ -70,6 +70,11 @@ class MobileBottomNavigationBar extends StatelessWidget { /// Navigate to the current location of the branch at the provided index when /// tapping an item in the BottomNavigationBar. void _onTap(BuildContext context, int bottomBarIndex) { + if (_items[bottomBarIndex].label == _addLabel) { + // show an add dialog + _showCreatePageBottomSheet(context); + return; + } // When navigating to a new branch, it's recommended to use the goBranch // method, as doing so makes sure the last navigation state of the // Navigator for the branch is restored. @@ -82,4 +87,40 @@ class MobileBottomNavigationBar extends StatelessWidget { initialLocation: bottomBarIndex == navigationShell.currentIndex, ); } + + void _showCreatePageBottomSheet(BuildContext context) { + showMobileBottomSheet( + context, + showHeader: true, + title: LocaleKeys.sideBar_addAPage.tr(), + showDragHandle: true, + showCloseButton: true, + useRootNavigator: true, + builder: (sheetContext) { + return AddNewPageWidgetBottomSheet( + view: ViewPB(), + onAction: (layout) async { + Navigator.of(sheetContext).pop(); + final currentWorkspaceId = + await FolderEventReadCurrentWorkspace().send(); + await currentWorkspaceId.fold((s) async { + final workspaceService = WorkspaceService(workspaceId: s.id); + final result = await workspaceService.createView( + name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(), + viewSection: ViewSectionPB.Private, + layout: layout, + ); + result.fold((s) { + context.pushView(s); + }, (e) { + Log.error('Failed to create new page: $e'); + }); + }, (e) { + Log.error('Failed to read current workspace: $e'); + }); + }, + ); + }, + ); + } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart index 862ce794b6..e21ff3be20 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart @@ -1,11 +1,13 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_view_item_add_button.dart'; -import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; +import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -17,8 +19,6 @@ import 'package:flutter_slidable/flutter_slidable.dart'; typedef ViewItemOnSelected = void Function(ViewPB); typedef ActionPaneBuilder = ActionPane Function(BuildContext context); -const _itemHeight = 48.0; - class MobileViewItem extends StatelessWidget { const MobileViewItem({ super.key, @@ -177,48 +177,10 @@ class InnerMobileViewItem extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ child, - const Divider( - height: 1, - ), ...children, ], ); - } else { - child = Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - child, - const Divider( - height: 1, - ), - Container( - height: _itemHeight, - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only(left: (level + 2) * leftPadding), - child: FlowyText.medium( - LocaleKeys.noPagesInside.tr(), - color: Colors.grey, - ), - ), - ), - const Divider( - height: 1, - ), - ], - ); } - } else { - child = Column( - mainAxisSize: MainAxisSize.min, - children: [ - child, - const Divider( - height: 1, - ), - ], - ); } // wrap the child with DraggableItem if isDraggable is true @@ -226,7 +188,6 @@ class InnerMobileViewItem extends StatelessWidget { child = DraggableViewItem( isFirstChild: isFirstChild, view: view, - // FIXME: use better color centerHighlightColor: Colors.blue.shade200, topHighlightColor: Colors.blue.shade200, bottomHighlightColor: Colors.blue.shade200, @@ -296,15 +257,14 @@ class _SingleMobileInnerViewItemState extends State { final children = [ // expand icon _buildLeftIcon(), - const HSpace(4), // icon _buildViewIcon(), const HSpace(8), // title Expanded( - child: FlowyText.medium( + child: FlowyText.regular( widget.view.name, - fontSize: 18.0, + fontSize: 16.0, overflow: TextOverflow.ellipsis, ), ), @@ -313,10 +273,11 @@ class _SingleMobileInnerViewItemState extends State { // hover action // ··· more action button - // children.add(_buildViewMoreActionButton(context)); + children.add(_buildViewMoreButton(context)); // only support add button for document layout if (!widget.isFeedback && widget.view.layout == ViewLayoutPB.Document) { // + button + children.add(_buildViewAddButton(context)); } @@ -324,7 +285,7 @@ class _SingleMobileInnerViewItemState extends State { borderRadius: BorderRadius.circular(4.0), onTap: () => widget.onSelected(widget.view), child: SizedBox( - height: _itemHeight, + height: HomeSpaceViewSizes.mViewHeight, child: Padding( padding: EdgeInsets.only(left: widget.level * widget.leftPadding), child: Row( @@ -349,12 +310,12 @@ class _SingleMobileInnerViewItemState extends State { Widget _buildViewIcon() { final icon = widget.view.icon.value.isNotEmpty - ? EmojiText( - emoji: widget.view.icon.value, - fontSize: 24.0, + ? FlowyText.emoji( + widget.view.icon.value, + fontSize: 20.0, ) : SizedBox.square( - dimension: 26.0, + dimension: 18.0, child: widget.view.defaultIcon(), ); return icon; @@ -364,17 +325,17 @@ class _SingleMobileInnerViewItemState extends State { // show > if the view is expandable. // show · if the view can't contain child views. Widget _buildLeftIcon() { - if (isReferencedDatabaseView(widget.view, widget.parentView)) { - return const _DotIconWidget(); + if (context.read().state.view.childViews.isEmpty) { + return HSpace(widget.leftPadding); } return GestureDetector( - child: AnimatedRotation( - duration: const Duration(milliseconds: 250), - turns: widget.isExpanded ? 0 : -0.25, - child: const Icon( - Icons.keyboard_arrow_down_rounded, - size: 28, + behavior: HitTestBehavior.opaque, + child: Padding( + padding: const EdgeInsets.only(right: 6.0, top: 6.0, bottom: 6.0), + child: FlowySvg( + widget.isExpanded ? FlowySvgs.m_expand_s : FlowySvgs.m_collapse_s, + blendMode: null, ), ), onTap: () { @@ -418,23 +379,49 @@ class _SingleMobileInnerViewItemState extends State { }, ); } -} -class _DotIconWidget extends StatelessWidget { - const _DotIconWidget(); + // + button + Widget _buildViewMoreButton(BuildContext context) { + return MobileViewMoreButton(onPressed: () => _showMoreActions(context)); + } - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(6.0), - child: Container( - width: 4, - height: 4, - decoration: BoxDecoration( - color: Theme.of(context).iconTheme.color, - borderRadius: BorderRadius.circular(2), - ), - ), + Future _showMoreActions(BuildContext context) async { + final viewBloc = context.read(); + final favoriteBloc = context.read(); + await showMobileBottomSheet( + context, + showHeader: true, + title: widget.view.name, + showDragHandle: true, + showCloseButton: true, + useRootNavigator: true, + builder: (context) { + return MultiBlocProvider( + providers: [ + BlocProvider.value(value: viewBloc), + BlocProvider.value(value: favoriteBloc), + ], + child: BlocBuilder( + builder: (context, state) { + final isFavorite = state.view.isFavorite; + return MobileViewItemBottomSheet( + view: viewBloc.state.view, + actions: [ + isFavorite + ? MobileViewItemBottomSheetBodyAction.removeFromFavorites + : MobileViewItemBottomSheetBodyAction.addToFavorites, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.rename, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.duplicate, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.delete, + ], + ); + }, + ), + ); + }, ); } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item_add_button.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item_add_button.dart index eb2f8ea9f8..77bb57773f 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item_add_button.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item_add_button.dart @@ -1,9 +1,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; -const _iconSize = 32.0; - class MobileViewAddButton extends StatelessWidget { const MobileViewAddButton({ super.key, @@ -15,12 +14,31 @@ class MobileViewAddButton extends StatelessWidget { @override Widget build(BuildContext context) { return FlowyIconButton( - iconPadding: const EdgeInsets.all(2), - width: _iconSize, - height: _iconSize, + width: HomeSpaceViewSizes.mViewButtonDimension, + height: HomeSpaceViewSizes.mViewButtonDimension, icon: const FlowySvg( - FlowySvgs.add_s, - size: Size.square(_iconSize), + FlowySvgs.m_space_add_s, + ), + onPressed: onPressed, + ); + } +} + +class MobileViewMoreButton extends StatelessWidget { + const MobileViewMoreButton({ + super.key, + required this.onPressed, + }); + + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return FlowyIconButton( + width: HomeSpaceViewSizes.mViewButtonDimension, + height: HomeSpaceViewSizes.mViewButtonDimension, + icon: const FlowySvg( + FlowySvgs.m_space_more_s, ), onPressed: onPressed, ); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart index ba2d2b00cc..5be3d3e78c 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/flowy_mobile_quick_action_button.dart @@ -1,7 +1,6 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; class MobileQuickActionButton extends StatelessWidget { const MobileQuickActionButton({ @@ -32,20 +31,20 @@ class MobileQuickActionButton extends StatelessWidget { enable ? null : const WidgetStatePropertyAll(Colors.transparent), splashColor: Colors.transparent, child: Container( - height: 44, + height: 52, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ FlowySvg( icon, - size: const Size.square(20), + size: const Size.square(18), color: enable ? iconColor : Theme.of(context).disabledColor, ), const HSpace(12), Expanded( - child: FlowyText( + child: FlowyText.regular( text, - fontSize: 15, + fontSize: 16, color: enable ? textColor : Theme.of(context).disabledColor, ), ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/show_flowy_mobile_confirm_dialog.dart b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/show_flowy_mobile_confirm_dialog.dart index 5a481eaa68..321632a36a 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/widgets/show_flowy_mobile_confirm_dialog.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/widgets/show_flowy_mobile_confirm_dialog.dart @@ -1,6 +1,8 @@ import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/startup/tasks/app_widget.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; enum ConfirmDialogActionAlignment { @@ -85,3 +87,46 @@ Future showFlowyMobileConfirmDialog( }, ); } + +Future showFlowyCupertinoConfirmDialog({ + BuildContext? context, + required String title, + required Widget leftButton, + required Widget rightButton, + void Function(BuildContext context)? onLeftButtonPressed, + void Function(BuildContext context)? onRightButtonPressed, +}) { + return showDialog( + context: context ?? AppGlobals.context, + builder: (context) => CupertinoAlertDialog( + title: FlowyText.medium( + title, + fontSize: 18, + maxLines: 10, + lineHeight: 1.3, + ), + actions: [ + CupertinoDialogAction( + onPressed: () { + if (onLeftButtonPressed != null) { + onLeftButtonPressed(context); + } else { + Navigator.of(context).pop(); + } + }, + child: leftButton, + ), + CupertinoDialogAction( + onPressed: () { + if (onRightButtonPressed != null) { + onRightButtonPressed(context); + } else { + Navigator.of(context).pop(); + } + }, + child: rightButton, + ), + ], + ), + ); +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart new file mode 100644 index 0000000000..2c5c8f5b0e --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_ai_message_bloc.dart @@ -0,0 +1,42 @@ +import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'chat_ai_message_bloc.freezed.dart'; + +class ChatAIMessageBloc extends Bloc { + ChatAIMessageBloc({ + required Message message, + }) : super(ChatAIMessageState.initial(message)) { + on( + (event, emit) async { + await event.when( + initial: () async {}, + update: (userProfile, deviceId, states) {}, + ); + }, + ); + } +} + +@freezed +class ChatAIMessageEvent with _$ChatAIMessageEvent { + const factory ChatAIMessageEvent.initial() = Initial; + const factory ChatAIMessageEvent.update( + UserProfilePB userProfile, + String deviceId, + DocumentAwarenessStatesPB states, + ) = Update; +} + +@freezed +class ChatAIMessageState with _$ChatAIMessageState { + const factory ChatAIMessageState({ + required Message message, + }) = _ChatAIMessageState; + + factory ChatAIMessageState.initial(Message message) => + ChatAIMessageState(message: message); +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart new file mode 100644 index 0000000000..17eaad8c92 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_bloc.dart @@ -0,0 +1,423 @@ +import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:collection/collection.dart'; +import 'package:fixnum/fixnum.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:nanoid/nanoid.dart'; +import 'chat_message_listener.dart'; + +part 'chat_bloc.freezed.dart'; + +const canRetryKey = "canRetry"; +const sendMessageErrorKey = "sendMessageError"; + +class ChatBloc extends Bloc { + ChatBloc({ + required ViewPB view, + required UserProfilePB userProfile, + }) : listener = ChatMessageListener(chatId: view.id), + chatId = view.id, + super( + ChatState.initial(view, userProfile), + ) { + _dispatch(); + + listener.start( + chatMessageCallback: _handleChatMessage, + lastUserSentMessageCallback: (message) { + if (!isClosed) { + add(ChatEvent.didSentUserMessage(message)); + } + }, + chatErrorMessageCallback: (err) { + if (!isClosed) { + Log.error("chat error: ${err.errorMessage}"); + final metadata = OnetimeShotType.serverStreamError.toMap(); + if (state.lastSentMessage != null) { + metadata[canRetryKey] = "true"; + } + final error = CustomMessage( + metadata: metadata, + author: const User(id: "system"), + id: 'system', + ); + add(ChatEvent.streaming([error])); + add(const ChatEvent.didFinishStreaming()); + } + }, + latestMessageCallback: (list) { + if (!isClosed) { + final messages = list.messages.map(_createChatMessage).toList(); + add(ChatEvent.didLoadLatestMessages(messages)); + } + }, + prevMessageCallback: (list) { + if (!isClosed) { + final messages = list.messages.map(_createChatMessage).toList(); + add(ChatEvent.didLoadPreviousMessages(messages, list.hasMore)); + } + }, + finishAnswerQuestionCallback: () { + if (!isClosed) { + add(const ChatEvent.didFinishStreaming()); + if (state.lastSentMessage != null) { + final payload = ChatMessageIdPB( + chatId: chatId, + messageId: state.lastSentMessage!.messageId, + ); + // When user message was sent to the server, we start gettting related question + ChatEventGetRelatedQuestion(payload).send().then((result) { + if (!isClosed) { + result.fold( + (list) { + add( + ChatEvent.didReceiveRelatedQuestion(list.items), + ); + }, + (err) { + Log.error("Failed to get related question: $err"); + }, + ); + } + }); + } + } + }, + ); + } + + final ChatMessageListener listener; + final String chatId; + + @override + Future close() { + listener.stop(); + return super.close(); + } + + void _dispatch() { + on( + (event, emit) async { + await event.when( + initialLoad: () { + final payload = LoadNextChatMessagePB( + chatId: state.view.id, + limit: Int64(10), + ); + ChatEventLoadNextMessage(payload).send(); + }, + startLoadingPrevMessage: () async { + Int64? beforeMessageId; + if (state.messages.isNotEmpty) { + beforeMessageId = Int64.parseInt(state.messages.last.id); + } + _loadPrevMessage(beforeMessageId); + emit( + state.copyWith( + loadingPreviousStatus: const LoadingState.loading(), + ), + ); + }, + didLoadPreviousMessages: (List messages, bool hasMore) { + Log.debug("did load previous messages: ${messages.length}"); + final uniqueMessages = {...state.messages, ...messages}.toList() + ..sort((a, b) => b.id.compareTo(a.id)); + emit( + state.copyWith( + messages: uniqueMessages, + loadingPreviousStatus: const LoadingState.finish(), + hasMorePrevMessage: hasMore, + ), + ); + }, + didLoadLatestMessages: (List messages) { + final uniqueMessages = {...state.messages, ...messages}.toList() + ..sort((a, b) => b.id.compareTo(a.id)); + emit( + state.copyWith( + messages: uniqueMessages, + initialLoadingStatus: const LoadingState.finish(), + ), + ); + }, + streaming: (List messages) { + final allMessages = _perminentMessages(); + allMessages.insertAll(0, messages); + emit(state.copyWith(messages: allMessages)); + }, + didFinishStreaming: () { + emit( + state.copyWith( + answerQuestionStatus: const LoadingState.finish(), + ), + ); + }, + sendMessage: (String message) async { + await _handleSentMessage(message, emit); + + // Create a loading indicator + final loadingMessage = + _loadingMessage(state.userProfile.id.toString()); + final allMessages = List.from(state.messages) + ..insert(0, loadingMessage); + + emit( + state.copyWith( + lastSentMessage: null, + messages: allMessages, + answerQuestionStatus: const LoadingState.loading(), + relatedQuestions: [], + ), + ); + }, + retryGenerate: () { + if (state.lastSentMessage == null) { + return; + } + final payload = ChatMessageIdPB( + chatId: chatId, + messageId: state.lastSentMessage!.messageId, + ); + ChatEventGetAnswerForQuestion(payload).send().then((result) { + if (!isClosed) { + result.fold( + (answer) => _handleChatMessage(answer), + (err) { + Log.error("Failed to get answer: $err"); + }, + ); + } + }); + }, + didReceiveRelatedQuestion: (List questions) { + final allMessages = _perminentMessages(); + final message = CustomMessage( + metadata: OnetimeShotType.relatedQuestion.toMap(), + author: const User(id: "system"), + id: 'system', + ); + allMessages.insert(0, message); + emit( + state.copyWith( + messages: allMessages, + relatedQuestions: questions, + ), + ); + }, + clearReleatedQuestion: () { + emit( + state.copyWith( + relatedQuestions: [], + ), + ); + }, + didSentUserMessage: (ChatMessagePB message) { + emit( + state.copyWith( + lastSentMessage: message, + ), + ); + }, + ); + }, + ); + } + +// Returns the list of messages that are not include one-time messages. + List _perminentMessages() { + final allMessages = state.messages.where((element) { + return !(element.metadata?.containsKey(onetimeShotType) == true); + }).toList(); + + return allMessages; + } + + void _loadPrevMessage(Int64? beforeMessageId) { + final payload = LoadPrevChatMessagePB( + chatId: state.view.id, + limit: Int64(10), + beforeMessageId: beforeMessageId, + ); + ChatEventLoadPrevMessage(payload).send(); + } + + Future _handleSentMessage( + String message, + Emitter emit, + ) async { + final payload = SendChatPayloadPB( + chatId: state.view.id, + message: message, + messageType: ChatMessageTypePB.User, + ); + final result = await ChatEventSendMessage(payload).send(); + result.fold( + (_) {}, + (err) { + if (!isClosed) { + Log.error("Failed to send message: ${err.msg}"); + final metadata = OnetimeShotType.invalidSendMesssage.toMap(); + metadata[sendMessageErrorKey] = err.msg; + final error = CustomMessage( + metadata: metadata, + author: const User(id: "system"), + id: 'system', + ); + + add(ChatEvent.streaming([error])); + } + }, + ); + } + + void _handleChatMessage(ChatMessagePB pb) { + if (!isClosed) { + final message = _createChatMessage(pb); + final messages = pb.hasFollowing + ? [_loadingMessage(0.toString()), message] + : [message]; + add(ChatEvent.streaming(messages)); + } + } + + Message _loadingMessage(String id) { + return CustomMessage( + author: User(id: id), + metadata: OnetimeShotType.loading.toMap(), + // fake id + id: nanoid(), + ); + } + + Message _createChatMessage(ChatMessagePB message) { + final messageId = message.messageId.toString(); + return TextMessage( + author: User(id: message.authorId), + id: messageId, + text: message.content, + createdAt: message.createdAt.toInt(), + repliedMessage: _getReplyMessage(state.messages, messageId), + ); + } + + Message? _getReplyMessage(List messages, String messageId) { + return messages.firstWhereOrNull((element) => element?.id == messageId); + } +} + +@freezed +class ChatEvent with _$ChatEvent { + const factory ChatEvent.initialLoad() = _InitialLoadMessage; + const factory ChatEvent.sendMessage(String message) = _SendMessage; + const factory ChatEvent.startLoadingPrevMessage() = _StartLoadPrevMessage; + const factory ChatEvent.didLoadPreviousMessages( + List messages, + bool hasMore, + ) = _DidLoadPreviousMessages; + const factory ChatEvent.didLoadLatestMessages(List messages) = + _DidLoadMessages; + const factory ChatEvent.streaming(List messages) = _DidStreamMessage; + const factory ChatEvent.didFinishStreaming() = _FinishStreamingMessage; + const factory ChatEvent.didReceiveRelatedQuestion( + List questions, + ) = _DidReceiveRelatedQueston; + const factory ChatEvent.clearReleatedQuestion() = _ClearRelatedQuestion; + const factory ChatEvent.retryGenerate() = _RetryGenerate; + const factory ChatEvent.didSentUserMessage(ChatMessagePB message) = + _DidSendUserMessage; +} + +@freezed +class ChatState with _$ChatState { + const factory ChatState({ + required ViewPB view, + required List messages, + required UserProfilePB userProfile, + // When opening the chat, the initial loading status will be set as loading. + //After the initial loading is done, the status will be set as finished. + required LoadingState initialLoadingStatus, + // When loading previous messages, the status will be set as loading. + // After the loading is done, the status will be set as finished. + required LoadingState loadingPreviousStatus, + // When sending a user message, the status will be set as loading. + // After the message is sent, the status will be set as finished. + required LoadingState answerQuestionStatus, + // Indicate whether there are more previous messages to load. + required bool hasMorePrevMessage, + // The related questions that are received after the user message is sent. + required List relatedQuestions, + // The last user message that is sent to the server. + ChatMessagePB? lastSentMessage, + }) = _ChatState; + + factory ChatState.initial(ViewPB view, UserProfilePB userProfile) => + ChatState( + view: view, + messages: [], + userProfile: userProfile, + initialLoadingStatus: const LoadingState.finish(), + loadingPreviousStatus: const LoadingState.finish(), + answerQuestionStatus: const LoadingState.finish(), + hasMorePrevMessage: true, + relatedQuestions: [], + ); +} + +@freezed +class LoadingState with _$LoadingState { + const factory LoadingState.loading() = _Loading; + const factory LoadingState.finish() = _Finish; +} + +enum OnetimeShotType { + unknown, + loading, + serverStreamError, + relatedQuestion, + invalidSendMesssage +} + +const onetimeShotType = "OnetimeShotType"; + +extension OnetimeMessageTypeExtension on OnetimeShotType { + static OnetimeShotType fromString(String value) { + switch (value) { + case 'OnetimeShotType.loading': + return OnetimeShotType.loading; + case 'OnetimeShotType.serverStreamError': + return OnetimeShotType.serverStreamError; + case 'OnetimeShotType.relatedQuestion': + return OnetimeShotType.relatedQuestion; + case 'OnetimeShotType.invalidSendMesssage': + return OnetimeShotType.invalidSendMesssage; + default: + Log.error('Unknown OnetimeShotType: $value'); + return OnetimeShotType.unknown; + } + } + + Map toMap() { + return { + onetimeShotType: toString(), + }; + } +} + +OnetimeShotType? onetimeMessageTypeFromMeta(Map? metadata) { + if (metadata == null) { + return null; + } + + for (final entry in metadata.entries) { + if (entry.key == onetimeShotType) { + return OnetimeMessageTypeExtension.fromString(entry.value as String); + } + } + return null; +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart new file mode 100644 index 0000000000..3b40c18d36 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_message_listener.dart @@ -0,0 +1,87 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-chat/notification.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart'; +import 'package:appflowy_backend/rust_stream.dart'; +import 'package:appflowy_result/appflowy_result.dart'; + +import 'chat_notification.dart'; + +typedef ChatMessageCallback = void Function(ChatMessagePB message); +typedef ChatErrorMessageCallback = void Function(ChatMessageErrorPB message); +typedef LatestMessageCallback = void Function(ChatMessageListPB list); +typedef PrevMessageCallback = void Function(ChatMessageListPB list); + +class ChatMessageListener { + ChatMessageListener({required this.chatId}) { + _parser = ChatNotificationParser(id: chatId, callback: _callback); + _subscription = RustStreamReceiver.listen( + (observable) => _parser?.parse(observable), + ); + } + + final String chatId; + StreamSubscription? _subscription; + ChatNotificationParser? _parser; + + ChatMessageCallback? chatMessageCallback; + ChatMessageCallback? lastUserSentMessageCallback; + ChatErrorMessageCallback? chatErrorMessageCallback; + LatestMessageCallback? latestMessageCallback; + PrevMessageCallback? prevMessageCallback; + void Function()? finishAnswerQuestionCallback; + + void start({ + ChatMessageCallback? chatMessageCallback, + ChatErrorMessageCallback? chatErrorMessageCallback, + LatestMessageCallback? latestMessageCallback, + PrevMessageCallback? prevMessageCallback, + ChatMessageCallback? lastUserSentMessageCallback, + void Function()? finishAnswerQuestionCallback, + }) { + this.chatMessageCallback = chatMessageCallback; + this.chatErrorMessageCallback = chatErrorMessageCallback; + this.latestMessageCallback = latestMessageCallback; + this.prevMessageCallback = prevMessageCallback; + this.lastUserSentMessageCallback = lastUserSentMessageCallback; + this.finishAnswerQuestionCallback = finishAnswerQuestionCallback; + } + + void _callback( + ChatNotification ty, + FlowyResult result, + ) { + result.map((r) { + switch (ty) { + case ChatNotification.DidReceiveChatMessage: + chatMessageCallback?.call(ChatMessagePB.fromBuffer(r)); + break; + case ChatNotification.LastUserSentMessage: + lastUserSentMessageCallback?.call(ChatMessagePB.fromBuffer(r)); + break; + case ChatNotification.StreamChatMessageError: + chatErrorMessageCallback?.call(ChatMessageErrorPB.fromBuffer(r)); + break; + case ChatNotification.DidLoadLatestChatMessage: + latestMessageCallback?.call(ChatMessageListPB.fromBuffer(r)); + break; + case ChatNotification.DidLoadPrevChatMessage: + prevMessageCallback?.call(ChatMessageListPB.fromBuffer(r)); + break; + case ChatNotification.FinishAnswerQuestion: + finishAnswerQuestionCallback?.call(); + break; + default: + break; + } + }); + } + + Future stop() async { + await _subscription?.cancel(); + _subscription = null; + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart new file mode 100644 index 0000000000..194748858b --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_notification.dart @@ -0,0 +1,45 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:appflowy/core/notification/notification_helper.dart'; +import 'package:appflowy_backend/protobuf/flowy-chat/notification.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart'; +import 'package:appflowy_backend/rust_stream.dart'; +import 'package:appflowy_result/appflowy_result.dart'; + +class ChatNotificationParser + extends NotificationParser { + ChatNotificationParser({ + super.id, + required super.callback, + }) : super( + tyParser: (ty, source) => + source == "Chat" ? ChatNotification.valueOf(ty) : null, + errorParser: (bytes) => FlowyError.fromBuffer(bytes), + ); +} + +typedef ChatNotificationHandler = Function( + ChatNotification ty, + FlowyResult result, +); + +class ChatNotificationListener { + ChatNotificationListener({ + required String objectId, + required ChatNotificationHandler handler, + }) : _parser = ChatNotificationParser(id: objectId, callback: handler) { + _subscription = + RustStreamReceiver.listen((observable) => _parser?.parse(observable)); + } + + ChatNotificationParser? _parser; + StreamSubscription? _subscription; + + Future stop() async { + _parser = null; + await _subscription?.cancel(); + _subscription = null; + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_related_question_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_related_question_bloc.dart new file mode 100644 index 0000000000..d6db6afc37 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_related_question_bloc.dart @@ -0,0 +1,103 @@ +import 'package:appflowy/plugins/ai_chat/application/chat_message_listener.dart'; +import 'package:appflowy_backend/dispatch/dispatch.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'chat_related_question_bloc.freezed.dart'; + +class ChatRelatedMessageBloc + extends Bloc { + ChatRelatedMessageBloc({ + required String chatId, + }) : listener = ChatMessageListener(chatId: chatId), + super(ChatRelatedMessageState.initial()) { + on( + (event, emit) async { + await event.when( + initial: () async { + listener.start( + lastUserSentMessageCallback: (message) { + if (!isClosed) { + add(ChatRelatedMessageEvent.updateLastSentMessage(message)); + } + }, + ); + }, + didReceiveRelatedQuestion: (List questions) { + Log.debug("Related questions: $questions"); + emit( + state.copyWith( + relatedQuestions: questions, + ), + ); + }, + updateLastSentMessage: (ChatMessagePB message) { + final payload = + ChatMessageIdPB(chatId: chatId, messageId: message.messageId); + ChatEventGetRelatedQuestion(payload).send().then((result) { + if (!isClosed) { + result.fold( + (list) { + add( + ChatRelatedMessageEvent.didReceiveRelatedQuestion( + list.items, + ), + ); + }, + (err) { + Log.error("Failed to get related question: $err"); + }, + ); + } + }); + + emit( + state.copyWith( + lastSentMessage: message, + relatedQuestions: [], + ), + ); + }, + clear: () { + emit( + state.copyWith( + relatedQuestions: [], + ), + ); + }, + ); + }, + ); + } + + final ChatMessageListener listener; + @override + Future close() { + listener.stop(); + return super.close(); + } +} + +@freezed +class ChatRelatedMessageEvent with _$ChatRelatedMessageEvent { + const factory ChatRelatedMessageEvent.initial() = Initial; + const factory ChatRelatedMessageEvent.updateLastSentMessage( + ChatMessagePB message, + ) = _LastSentMessage; + const factory ChatRelatedMessageEvent.didReceiveRelatedQuestion( + List questions, + ) = _RelatedQuestion; + const factory ChatRelatedMessageEvent.clear() = _Clear; +} + +@freezed +class ChatRelatedMessageState with _$ChatRelatedMessageState { + const factory ChatRelatedMessageState({ + ChatMessagePB? lastSentMessage, + @Default([]) List relatedQuestions, + }) = _ChatRelatedMessageState; + + factory ChatRelatedMessageState.initial() => const ChatRelatedMessageState(); +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart new file mode 100644 index 0000000000..d75b0533e2 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/application/chat_user_message_bloc.dart @@ -0,0 +1,44 @@ +import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'chat_user_message_bloc.freezed.dart'; + +class ChatUserMessageBloc + extends Bloc { + ChatUserMessageBloc({ + required Message message, + }) : super(ChatUserMessageState.initial(message)) { + on( + (event, emit) async { + await event.when( + initial: () async {}, + update: (userProfile, deviceId, states) {}, + ); + }, + ); + } +} + +@freezed +class ChatUserMessageEvent with _$ChatUserMessageEvent { + const factory ChatUserMessageEvent.initial() = Initial; + const factory ChatUserMessageEvent.update( + UserProfilePB userProfile, + String deviceId, + DocumentAwarenessStatesPB states, + ) = Update; +} + +@freezed +class ChatUserMessageState with _$ChatUserMessageState { + const factory ChatUserMessageState({ + required Message message, + WorkspaceMemberPB? member, + }) = _ChatUserMessageState; + + factory ChatUserMessageState.initial(Message message) => + ChatUserMessageState(message: message); +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart new file mode 100644 index 0000000000..cb69ee8d8d --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart @@ -0,0 +1,114 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/ai_chat/chat_page.dart'; +import 'package:appflowy/plugins/util.dart'; +import 'package:appflowy/startup/plugin/plugin.dart'; +import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/home_stack.dart'; +import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart'; +import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class AIChatPluginBuilder extends PluginBuilder { + @override + Plugin build(dynamic data) { + if (data is ViewPB) { + return AIChatPagePlugin(view: data); + } + + throw FlowyPluginException.invalidData; + } + + @override + String get menuName => "AIChat"; + + @override + FlowySvgData get icon => FlowySvgs.chat_ai_page_s; + + @override + PluginType get pluginType => PluginType.chat; + + @override + ViewLayoutPB get layoutType => ViewLayoutPB.Chat; +} + +class AIChatPluginConfig implements PluginConfig { + @override + bool get creatable => true; +} + +class AIChatPagePlugin extends Plugin { + AIChatPagePlugin({ + required ViewPB view, + }) : notifier = ViewPluginNotifier(view: view); + + late final ViewInfoBloc _viewInfoBloc; + + @override + final ViewPluginNotifier notifier; + + @override + PluginWidgetBuilder get widgetBuilder => AIChatPagePluginWidgetBuilder( + bloc: _viewInfoBloc, + notifier: notifier, + ); + + @override + PluginId get id => notifier.view.id; + + @override + PluginType get pluginType => PluginType.chat; + + @override + void init() { + _viewInfoBloc = ViewInfoBloc(view: notifier.view) + ..add(const ViewInfoEvent.started()); + } +} + +class AIChatPagePluginWidgetBuilder extends PluginWidgetBuilder + with NavigationItem { + AIChatPagePluginWidgetBuilder({ + required this.bloc, + required this.notifier, + }); + + final ViewInfoBloc bloc; + final ViewPluginNotifier notifier; + int? deletedViewIndex; + + @override + Widget get leftBarItem => + ViewTitleBar(key: ValueKey(notifier.view.id), view: notifier.view); + + @override + Widget tabBarItem(String pluginId) => ViewTabBarItem(view: notifier.view); + + @override + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }) { + notifier.isDeleted.addListener(() { + final deletedView = notifier.isDeleted.value; + if (deletedView != null && deletedView.hasIndex()) { + deletedViewIndex = deletedView.index; + } + }); + + return BlocProvider.value( + value: bloc, + child: AIChatPage( + userProfile: context.userProfile!, + key: ValueKey(notifier.view.id), + view: notifier.view, + onDeleted: () => + context.onDeleted?.call(notifier.view, deletedViewIndex), + ), + ); + } + + @override + List get navigationItems => [this]; +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart new file mode 100644 index 0000000000..4d103e342f --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart @@ -0,0 +1,332 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_ai_message.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_streaming_error_message.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_related_question.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_user_message.dart'; +import 'package:appflowy/workspace/presentation/home/toast.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; +import 'package:flutter_chat_ui/flutter_chat_ui.dart' show Chat; +import 'package:flutter_chat_types/flutter_chat_types.dart' as types; + +import 'presentation/chat_input.dart'; +import 'presentation/chat_loading.dart'; +import 'presentation/chat_popmenu.dart'; +import 'presentation/chat_theme.dart'; +import 'presentation/chat_user_invalid_message.dart'; +import 'presentation/chat_welcome_page.dart'; + +class AIChatPage extends StatefulWidget { + const AIChatPage({ + super.key, + required this.view, + required this.onDeleted, + required this.userProfile, + }); + + final ViewPB view; + final VoidCallback onDeleted; + final UserProfilePB userProfile; + + @override + State createState() => _AIChatPageState(); +} + +class _AIChatPageState extends State { + late types.User _user; + + @override + void initState() { + super.initState(); + _user = types.User(id: widget.userProfile.id.toString()); + } + + @override + Widget build(BuildContext context) { + if (widget.userProfile.authenticator == AuthenticatorPB.AppFlowyCloud) { + return buildChatWidget(); + } else { + return Center( + child: FlowyText( + LocaleKeys.chat_unsupportedCloudPrompt.tr(), + fontSize: 20, + ), + ); + } + } + + Widget buildChatWidget() { + return SizedBox.expand( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: BlocProvider( + create: (context) => ChatBloc( + view: widget.view, + userProfile: widget.userProfile, + )..add(const ChatEvent.initialLoad()), + child: BlocBuilder( + builder: (blocContext, state) { + return Chat( + messages: state.messages, + onAttachmentPressed: () {}, + onSendPressed: (types.PartialText message) { + // We use custom bottom widget for chat input, so + // do not need to handle this event. + }, + customBottomWidget: buildChatInput(blocContext), + user: _user, + theme: buildTheme(context), + customMessageBuilder: _customMessageBuilder, + onEndReached: () async { + if (state.hasMorePrevMessage && + state.loadingPreviousStatus != + const LoadingState.loading()) { + blocContext + .read() + .add(const ChatEvent.startLoadingPrevMessage()); + } + }, + emptyState: BlocBuilder( + builder: (context, state) { + return state.initialLoadingStatus == + const LoadingState.finish() + ? const ChatWelcomePage() + : const Center( + child: CircularProgressIndicator.adaptive(), + ); + }, + ), + messageWidthRatio: isMobile ? 0.8 : 0.86, + bubbleBuilder: ( + child, { + required message, + required nextMessageInGroup, + }) { + if (message.author.id == _user.id) { + return ChatUserMessageBubble( + message: message, + child: child, + ); + } else { + final messageType = onetimeMessageTypeFromMeta( + message.metadata, + ); + if (messageType == OnetimeShotType.serverStreamError) { + return ChatStreamingError( + message: message, + onRetryPressed: () { + blocContext + .read() + .add(const ChatEvent.retryGenerate()); + }, + ); + } + + if (messageType == OnetimeShotType.invalidSendMesssage) { + return ChatInvalidUserMessage( + message: message, + ); + } + + if (messageType == OnetimeShotType.relatedQuestion) { + return RelatedQuestionList( + onQuestionSelected: (question) { + blocContext + .read() + .add(ChatEvent.sendMessage(question)); + blocContext + .read() + .add(const ChatEvent.clearReleatedQuestion()); + }, + chatId: widget.view.id, + relatedQuestions: state.relatedQuestions, + ); + } + + return ChatAIMessageBubble( + message: message, + customMessageType: messageType, + child: child, + ); + } + }, + ); + }, + ), + ), + ), + ); + } + + Widget buildBubble(Message message, Widget child) { + final isAuthor = message.author.id == _user.id; + const borderRadius = BorderRadius.all(Radius.circular(6)); + + final childWithPadding = isAuthor + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), + child: child, + ) + : Padding( + padding: const EdgeInsets.all(8), + child: child, + ); + + // If the message is from the author, we will decorate it with a different color + final decoratedChild = isAuthor + ? DecoratedBox( + decoration: BoxDecoration( + borderRadius: borderRadius, + color: !isAuthor || message.type == types.MessageType.image + ? AFThemeExtension.of(context).tint1 + : Theme.of(context).colorScheme.secondary, + ), + child: childWithPadding, + ) + : childWithPadding; + + // If the message is from the author, no further actions are needed + if (isAuthor) { + return ClipRRect( + borderRadius: borderRadius, + child: decoratedChild, + ); + } else { + if (isMobile) { + return ChatPopupMenu( + onAction: (action) { + switch (action) { + case ChatMessageAction.copy: + if (message is TextMessage) { + Clipboard.setData(ClipboardData(text: message.text)); + showMessageToast(LocaleKeys.grid_row_copyProperty.tr()); + } + break; + } + }, + builder: (context) => + ClipRRect(borderRadius: borderRadius, child: decoratedChild), + ); + } else { + // Show hover effect only on desktop + return ClipRRect( + borderRadius: borderRadius, + child: ChatAIMessageHover( + message: message, + child: decoratedChild, + ), + ); + } + } + } + + Widget _customMessageBuilder( + types.CustomMessage message, { + required int messageWidth, + }) { + // iteration custom message type + final messageType = onetimeMessageTypeFromMeta(message.metadata); + if (messageType == null) { + return const SizedBox.shrink(); + } + + switch (messageType) { + case OnetimeShotType.loading: + return const ChatAILoading(); + default: + return const SizedBox.shrink(); + } + } + + Widget buildChatInput(BuildContext context) { + final query = MediaQuery.of(context); + final safeAreaInsets = isMobile + ? EdgeInsets.fromLTRB( + query.padding.left, + 0, + query.padding.right, + query.viewInsets.bottom + query.padding.bottom, + ) + : const EdgeInsets.symmetric(horizontal: 70); + return Column( + children: [ + ClipRect( + child: Padding( + padding: safeAreaInsets, + child: ChatInput( + chatId: widget.view.id, + onSendPressed: (message) => onSendPressed(context, message.text), + ), + ), + ), + const VSpace(6), + Opacity( + opacity: 0.6, + child: FlowyText( + LocaleKeys.chat_aiMistakePrompt.tr(), + fontSize: 12, + ), + ), + ], + ); + } + + AFDefaultChatTheme buildTheme(BuildContext context) { + return AFDefaultChatTheme( + backgroundColor: AFThemeExtension.of(context).background, + primaryColor: Theme.of(context).colorScheme.primary, + secondaryColor: AFThemeExtension.of(context).tint1, + receivedMessageDocumentIconColor: Theme.of(context).primaryColor, + receivedMessageCaptionTextStyle: TextStyle( + color: AFThemeExtension.of(context).textColor, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + receivedMessageBodyTextStyle: TextStyle( + color: AFThemeExtension.of(context).textColor, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + receivedMessageLinkTitleTextStyle: TextStyle( + color: AFThemeExtension.of(context).textColor, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + receivedMessageBodyLinkTextStyle: const TextStyle( + color: Colors.lightBlue, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + sentMessageBodyTextStyle: TextStyle( + color: AFThemeExtension.of(context).textColor, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + sentMessageBodyLinkTextStyle: const TextStyle( + color: Colors.blue, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + inputElevation: 2, + ); + } + + void onSendPressed(BuildContext context, String message) { + context.read().add(ChatEvent.sendMessage(message)); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart new file mode 100644 index 0000000000..5a8e65012d --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart @@ -0,0 +1,197 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_ai_message_bloc.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_avatar.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_input.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_popmenu.dart'; +import 'package:appflowy/workspace/presentation/home/toast.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; +import 'package:styled_widget/styled_widget.dart'; + +const _leftPadding = 16.0; + +class ChatAIMessageBubble extends StatelessWidget { + const ChatAIMessageBubble({ + super.key, + required this.message, + required this.child, + this.customMessageType, + }); + + final Message message; + final Widget child; + final OnetimeShotType? customMessageType; + + @override + Widget build(BuildContext context) { + const padding = EdgeInsets.symmetric(horizontal: _leftPadding); + final childWithPadding = Padding(padding: padding, child: child); + + return BlocProvider( + create: (context) => ChatAIMessageBloc(message: message), + child: BlocBuilder( + builder: (context, state) { + final widget = isMobile + ? _wrapPopMenu(childWithPadding) + : _wrapHover(childWithPadding); + + return Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ChatBorderedCircleAvatar( + backgroundColor: Theme.of(context).colorScheme.secondary, + child: const FlowySvg( + FlowySvgs.flowy_ai_chat_logo_s, + size: Size.square(24), + ), + ), + Expanded(child: widget), + ], + ); + }, + ), + ); + } + + ChatAIMessageHover _wrapHover(Padding child) { + return ChatAIMessageHover( + message: message, + customMessageType: customMessageType, + child: child, + ); + } + + ChatPopupMenu _wrapPopMenu(Padding childWithPadding) { + return ChatPopupMenu( + onAction: (action) { + if (action == ChatMessageAction.copy && message is TextMessage) { + Clipboard.setData(ClipboardData(text: (message as TextMessage).text)); + showMessageToast(LocaleKeys.grid_row_copyProperty.tr()); + } + }, + builder: (context) => childWithPadding, + ); + } +} + +class ChatAIMessageHover extends StatefulWidget { + const ChatAIMessageHover({ + super.key, + required this.child, + required this.message, + this.customMessageType, + }); + + final Widget child; + final Message message; + final bool autoShowHover = true; + final OnetimeShotType? customMessageType; + + @override + State createState() => _ChatAIMessageHoverState(); +} + +class _ChatAIMessageHoverState extends State { + bool _isHover = false; + + @override + void initState() { + super.initState(); + _isHover = widget.autoShowHover ? false : true; + } + + @override + Widget build(BuildContext context) { + final List children = [ + DecoratedBox( + decoration: const BoxDecoration( + color: Colors.transparent, + borderRadius: Corners.s6Border, + ), + child: Padding( + padding: const EdgeInsets.only(bottom: 40), + child: widget.child, + ), + ), + ]; + + if (_isHover) { + children.addAll(_buildOnHoverItems()); + } + + return MouseRegion( + cursor: SystemMouseCursors.click, + opaque: false, + onEnter: (p) => setState(() { + if (widget.autoShowHover) { + _isHover = true; + } + }), + onExit: (p) => setState(() { + if (widget.autoShowHover) { + _isHover = false; + } + }), + child: Stack( + alignment: AlignmentDirectional.centerStart, + children: children, + ), + ); + } + + List _buildOnHoverItems() { + final List children = []; + if (widget.customMessageType != null) { + // + } else { + if (widget.message is TextMessage) { + children.add( + CopyButton( + textMessage: widget.message as TextMessage, + ).positioned(left: _leftPadding, bottom: 0), + ); + } + } + + return children; + } +} + +class CopyButton extends StatelessWidget { + const CopyButton({ + super.key, + required this.textMessage, + }); + final TextMessage textMessage; + + @override + Widget build(BuildContext context) { + return FlowyTooltip( + message: LocaleKeys.settings_menu_clickToCopy.tr(), + child: FlowyIconButton( + width: 24, + hoverColor: AFThemeExtension.of(context).lightGreyHover, + fillColor: Theme.of(context).cardColor, + icon: FlowySvg( + FlowySvgs.ai_copy_s, + size: const Size.square(14), + color: Theme.of(context).colorScheme.primary, + ), + onPressed: () { + Clipboard.setData(ClipboardData(text: textMessage.text)); + showMessageToast(LocaleKeys.grid_row_copyProperty.tr()); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart new file mode 100644 index 0000000000..141432520b --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart @@ -0,0 +1,184 @@ +import 'package:flutter/material.dart'; +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/util/built_in_svgs.dart'; +import 'package:appflowy/util/color_generator/color_generator.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:string_validator/string_validator.dart'; + +class ChatChatUserAvatar extends StatelessWidget { + const ChatChatUserAvatar({required this.userId, super.key}); + + final String userId; + + @override + Widget build(BuildContext context) { + return const ChatBorderedCircleAvatar(); + } +} + +class ChatBorderedCircleAvatar extends StatelessWidget { + const ChatBorderedCircleAvatar({ + super.key, + this.border = const BorderSide(), + this.backgroundImage, + this.backgroundColor, + this.child, + }); + + final BorderSide border; + final ImageProvider? backgroundImage; + final Color? backgroundColor; + final Widget? child; + + @override + Widget build(BuildContext context) { + return CircleAvatar( + backgroundColor: border.color, + child: ConstrainedBox( + constraints: const BoxConstraints.expand(), + child: CircleAvatar( + backgroundImage: backgroundImage, + backgroundColor: backgroundColor, + child: child, + ), + ), + ); + } +} + +class ChatUserAvatar extends StatelessWidget { + const ChatUserAvatar({ + super.key, + required this.iconUrl, + required this.name, + required this.size, + this.isHovering = false, + }); + + final String iconUrl; + final String name; + final double size; + + // If true, a border will be applied on top of the avatar + final bool isHovering; + + @override + Widget build(BuildContext context) { + if (iconUrl.isEmpty) { + return _buildEmptyAvatar(context); + } else if (isURL(iconUrl)) { + return _buildUrlAvatar(context); + } else { + return _buildEmojiAvatar(context); + } + } + + Widget _buildEmptyAvatar(BuildContext context) { + final String nameOrDefault = _userName(name); + final Color color = ColorGenerator(name).toColor(); + const initialsCount = 2; + + // Taking the first letters of the name components and limiting to 2 elements + final nameInitials = nameOrDefault + .split(' ') + .where((element) => element.isNotEmpty) + .take(initialsCount) + .map((element) => element[0].toUpperCase()) + .join(); + + return Container( + width: size, + height: size, + alignment: Alignment.center, + decoration: BoxDecoration( + color: color, + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: _darken(color), + width: 4, + ) + : null, + ), + child: FlowyText.regular( + nameInitials, + color: Colors.black, + ), + ); + } + + Widget _buildUrlAvatar(BuildContext context) { + return SizedBox.square( + dimension: size, + child: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: Theme.of(context).colorScheme.primary, + width: 4, + ) + : null, + ), + child: ClipRRect( + borderRadius: Corners.s5Border, + child: CircleAvatar( + backgroundColor: Colors.transparent, + child: Image.network( + iconUrl, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) => + _buildEmptyAvatar(context), + ), + ), + ), + ), + ); + } + + Widget _buildEmojiAvatar(BuildContext context) { + return SizedBox.square( + dimension: size, + child: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: Theme.of(context).colorScheme.primary, + width: 4, + ) + : null, + ), + child: ClipRRect( + borderRadius: Corners.s5Border, + child: CircleAvatar( + backgroundColor: Colors.transparent, + child: builtInSVGIcons.contains(iconUrl) + ? FlowySvg( + FlowySvgData('emoji/$iconUrl'), + blendMode: null, + ) + : FlowyText.emoji(iconUrl), + ), + ), + ), + ); + } + + /// Return the user name, if the user name is empty, + /// return the default user name. + /// + String _userName(String name) => + name.isEmpty ? LocaleKeys.defaultUsername.tr() : name; + + /// Used to darken the generated color for the hover border effect. + /// The color is darkened by 15% - Hence the 0.15 value. + /// + Color _darken(Color color) { + final hsl = HSLColor.fromColor(color); + return hsl.withLightness((hsl.lightness - 0.15).clamp(0.0, 1.0)).toColor(); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart new file mode 100644 index 0000000000..732726b952 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart @@ -0,0 +1,257 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart' as types; +import 'package:flutter_chat_ui/flutter_chat_ui.dart'; + +class ChatInput extends StatefulWidget { + /// Creates [ChatInput] widget. + const ChatInput({ + super.key, + this.isAttachmentUploading, + this.onAttachmentPressed, + required this.onSendPressed, + required this.chatId, + this.options = const InputOptions(), + }); + + final bool? isAttachmentUploading; + final VoidCallback? onAttachmentPressed; + final void Function(types.PartialText) onSendPressed; + final InputOptions options; + final String chatId; + + @override + State createState() => _ChatInputState(); +} + +/// [ChatInput] widget state. +class _ChatInputState extends State { + late final _inputFocusNode = FocusNode( + onKeyEvent: (node, event) { + if (event.physicalKey == PhysicalKeyboardKey.enter && + !HardwareKeyboard.instance.physicalKeysPressed.any( + (el) => { + PhysicalKeyboardKey.shiftLeft, + PhysicalKeyboardKey.shiftRight, + }.contains(el), + )) { + if (kIsWeb && _textController.value.isComposingRangeValid) { + return KeyEventResult.ignored; + } + if (event is KeyDownEvent) { + _handleSendPressed(); + } + return KeyEventResult.handled; + } else { + return KeyEventResult.ignored; + } + }, + ); + + bool _sendButtonVisible = false; + late TextEditingController _textController; + + @override + void initState() { + super.initState(); + + _textController = + widget.options.textEditingController ?? InputTextFieldController(); + _handleSendButtonVisibilityModeChange(); + } + + void _handleSendButtonVisibilityModeChange() { + _textController.removeListener(_handleTextControllerChange); + if (widget.options.sendButtonVisibilityMode == + SendButtonVisibilityMode.hidden) { + _sendButtonVisible = false; + } else if (widget.options.sendButtonVisibilityMode == + SendButtonVisibilityMode.editing) { + _sendButtonVisible = _textController.text.trim() != ''; + _textController.addListener(_handleTextControllerChange); + } else { + _sendButtonVisible = true; + } + } + + void _handleSendPressed() { + final trimmedText = _textController.text.trim(); + if (trimmedText != '') { + final partialText = types.PartialText(text: trimmedText); + widget.onSendPressed(partialText); + + if (widget.options.inputClearMode == InputClearMode.always) { + _textController.clear(); + } + } + } + + void _handleTextControllerChange() { + if (_textController.value.isComposingRangeValid) { + return; + } + setState(() { + _sendButtonVisible = _textController.text.trim() != ''; + }); + } + + Widget _inputBuilder() { + const textPadding = EdgeInsets.symmetric(horizontal: 16, vertical: 6); + const buttonPadding = EdgeInsets.symmetric(horizontal: 16, vertical: 6); + const inputPadding = EdgeInsets.all(6); + + return Focus( + autofocus: !widget.options.autofocus, + child: Padding( + padding: inputPadding, + child: Material( + borderRadius: BorderRadius.circular(12), + color: isMobile + ? Theme.of(context).colorScheme.surfaceContainer + : Theme.of(context).colorScheme.surfaceContainerHighest, + elevation: 0.6, + child: Row( + children: [ + if (widget.onAttachmentPressed != null) + AttachmentButton( + isLoading: widget.isAttachmentUploading ?? false, + onPressed: widget.onAttachmentPressed, + padding: buttonPadding, + ), + Expanded(child: _inputTextField(textPadding)), + _sendButton(buttonPadding), + ], + ), + ), + ), + ); + } + + Padding _inputTextField(EdgeInsets textPadding) { + return Padding( + padding: textPadding, + child: TextField( + controller: _textController, + focusNode: _inputFocusNode, + decoration: InputDecoration( + border: InputBorder.none, + hintText: LocaleKeys.chat_inputMessageHint.tr(), + hintStyle: TextStyle( + color: AFThemeExtension.of(context).textColor.withOpacity(0.5), + ), + ), + style: TextStyle( + color: AFThemeExtension.of(context).textColor, + ), + enabled: widget.options.enabled, + autocorrect: widget.options.autocorrect, + autofocus: widget.options.autofocus, + enableSuggestions: widget.options.enableSuggestions, + spellCheckConfiguration: const SpellCheckConfiguration(), + keyboardType: widget.options.keyboardType, + textCapitalization: TextCapitalization.sentences, + maxLines: 10, + minLines: 1, + onChanged: widget.options.onTextChanged, + onTap: widget.options.onTextFieldTap, + ), + ); + } + + ConstrainedBox _sendButton(EdgeInsets buttonPadding) { + return ConstrainedBox( + constraints: BoxConstraints( + minHeight: buttonPadding.bottom + buttonPadding.top + 24, + ), + child: Visibility( + visible: _sendButtonVisible, + child: SendButton( + onPressed: _handleSendPressed, + padding: buttonPadding, + ), + ), + ); + } + + @override + void didUpdateWidget(covariant ChatInput oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.options.sendButtonVisibilityMode != + oldWidget.options.sendButtonVisibilityMode) { + _handleSendButtonVisibilityModeChange(); + } + } + + @override + void dispose() { + _inputFocusNode.dispose(); + _textController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => GestureDetector( + onTap: () => _inputFocusNode.requestFocus(), + child: _inputBuilder(), + ); +} + +@immutable +class InputOptions { + const InputOptions({ + this.inputClearMode = InputClearMode.always, + this.keyboardType = TextInputType.multiline, + this.onTextChanged, + this.onTextFieldTap, + this.sendButtonVisibilityMode = SendButtonVisibilityMode.editing, + this.textEditingController, + this.autocorrect = true, + this.autofocus = false, + this.enableSuggestions = true, + this.enabled = true, + }); + + /// Controls the [ChatInput] clear behavior. Defaults to [InputClearMode.always]. + final InputClearMode inputClearMode; + + /// Controls the [ChatInput] keyboard type. Defaults to [TextInputType.multiline]. + final TextInputType keyboardType; + + /// Will be called whenever the text inside [TextField] changes. + final void Function(String)? onTextChanged; + + /// Will be called on [TextField] tap. + final VoidCallback? onTextFieldTap; + + /// Controls the visibility behavior of the [SendButton] based on the + /// [TextField] state inside the [ChatInput] widget. + /// Defaults to [SendButtonVisibilityMode.editing]. + final SendButtonVisibilityMode sendButtonVisibilityMode; + + /// Custom [TextEditingController]. If not provided, defaults to the + /// [InputTextFieldController], which extends [TextEditingController] and has + /// additional fatures like markdown support. If you want to keep additional + /// features but still need some methods from the default [TextEditingController], + /// you can create your own [InputTextFieldController] (imported from this lib) + /// and pass it here. + final TextEditingController? textEditingController; + + /// Controls the [TextInput] autocorrect behavior. Defaults to [true]. + final bool autocorrect; + + /// Whether [TextInput] should have focus. Defaults to [false]. + final bool autofocus; + + /// Controls the [TextInput] enableSuggestions behavior. Defaults to [true]. + final bool enableSuggestions; + + /// Controls the [TextInput] enabled behavior. Defaults to [true]. + final bool enabled; +} + +final isMobile = defaultTargetPlatform == TargetPlatform.android || + defaultTargetPlatform == TargetPlatform.iOS; diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_loading.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_loading.dart new file mode 100644 index 0000000000..4b5c984382 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_loading.dart @@ -0,0 +1,69 @@ +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; + +class ChatAILoading extends StatelessWidget { + const ChatAILoading({super.key}); + + @override + Widget build(BuildContext context) { + return Shimmer.fromColors( + baseColor: AFThemeExtension.of(context).lightGreyHover, + highlightColor: + AFThemeExtension.of(context).lightGreyHover.withOpacity(0.5), + period: const Duration(seconds: 3), + child: const ContentPlaceholder(), + ); + } +} + +class ContentPlaceholder extends StatelessWidget { + const ContentPlaceholder({super.key}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 30, + height: 16.0, + margin: const EdgeInsets.only(bottom: 8.0), + decoration: BoxDecoration( + color: AFThemeExtension.of(context).lightGreyHover, + borderRadius: BorderRadius.circular(4.0), + ), + ), + const HSpace(10), + Container( + width: 100, + height: 16.0, + margin: const EdgeInsets.only(bottom: 8.0), + decoration: BoxDecoration( + color: AFThemeExtension.of(context).lightGreyHover, + borderRadius: BorderRadius.circular(4.0), + ), + ), + ], + ), + Container( + width: 140, + height: 16.0, + margin: const EdgeInsets.only(bottom: 8.0), + decoration: BoxDecoration( + color: AFThemeExtension.of(context).lightGreyHover, + borderRadius: BorderRadius.circular(4.0), + ), + ), + ], + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_popmenu.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_popmenu.dart new file mode 100644 index 0000000000..6b0b50dcca --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_popmenu.dart @@ -0,0 +1,70 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; +import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:easy_localization/easy_localization.dart'; + +import 'package:flutter/material.dart'; + +class ChatPopupMenu extends StatefulWidget { + const ChatPopupMenu({ + super.key, + required this.onAction, + required this.builder, + }); + + final Function(ChatMessageAction) onAction; + final Widget Function(BuildContext context) builder; + + @override + State createState() => _ChatPopupMenuState(); +} + +class _ChatPopupMenuState extends State { + @override + Widget build(BuildContext context) { + return PopoverActionList( + asBarrier: true, + actions: ChatMessageAction.values + .map((action) => ChatMessageActionWrapper(action)) + .toList(), + buildChild: (controller) { + return GestureDetector( + onLongPress: () { + controller.show(); + }, + child: widget.builder(context), + ); + }, + onSelected: (action, controller) async { + widget.onAction(action.inner); + controller.close(); + }, + direction: PopoverDirection.bottomWithCenterAligned, + ); + } +} + +enum ChatMessageAction { + copy, +} + +class ChatMessageActionWrapper extends ActionCell { + ChatMessageActionWrapper(this.inner); + + final ChatMessageAction inner; + + @override + Widget? leftIcon(Color iconColor) => null; + + @override + String get name => inner.name; +} + +extension ChatMessageActionExtension on ChatMessageAction { + String get name { + switch (this) { + case ChatMessageAction.copy: + return LocaleKeys.document_plugins_contextMenu_copy.tr(); + } + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart new file mode 100644 index 0000000000..f4709f2263 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart @@ -0,0 +1,147 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_related_question_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-chat/entities.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class RelatedQuestionPage extends StatefulWidget { + const RelatedQuestionPage({ + required this.chatId, + required this.onQuestionSelected, + super.key, + }); + + final String chatId; + final Function(String) onQuestionSelected; + + @override + State createState() => _RelatedQuestionPageState(); +} + +class _RelatedQuestionPageState extends State { + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => ChatRelatedMessageBloc(chatId: widget.chatId) + ..add( + const ChatRelatedMessageEvent.initial(), + ), + child: BlocBuilder( + builder: (blocContext, state) { + return RelatedQuestionList( + chatId: widget.chatId, + onQuestionSelected: widget.onQuestionSelected, + relatedQuestions: state.relatedQuestions, + ); + }, + ), + ); + } +} + +class RelatedQuestionList extends StatelessWidget { + const RelatedQuestionList({ + required this.chatId, + required this.onQuestionSelected, + required this.relatedQuestions, + super.key, + }); + + final String chatId; + final Function(String) onQuestionSelected; + final List relatedQuestions; + + @override + Widget build(BuildContext context) { + return ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: relatedQuestions.length, + itemBuilder: (context, index) { + final question = relatedQuestions[index]; + if (index == 0) { + return Column( + children: [ + const Divider(height: 36), + Padding( + padding: const EdgeInsets.all(12), + child: Row( + children: [ + const FlowySvg( + FlowySvgs.ai_summary_generate_s, + size: Size.square(24), + ), + const HSpace(6), + FlowyText( + LocaleKeys.chat_relatedQuestion.tr(), + fontSize: 18, + ), + ], + ), + ), + const Divider(height: 6), + RelatedQuestionItem( + question: question, + onQuestionSelected: onQuestionSelected, + ), + ], + ); + } else { + return RelatedQuestionItem( + question: question, + onQuestionSelected: onQuestionSelected, + ); + } + }, + ); + } +} + +class RelatedQuestionItem extends StatefulWidget { + const RelatedQuestionItem({ + required this.question, + required this.onQuestionSelected, + super.key, + }); + + final RelatedQuestionPB question; + final Function(String) onQuestionSelected; + + @override + State createState() => _RelatedQuestionItemState(); +} + +class _RelatedQuestionItemState extends State { + bool _isHovered = false; + + @override + Widget build(BuildContext context) { + return MouseRegion( + onEnter: (_) => setState(() => _isHovered = true), + onExit: (_) => setState(() => _isHovered = false), + child: ListTile( + contentPadding: const EdgeInsets.symmetric( + horizontal: 12, + ), + title: Text( + widget.question.content, + style: TextStyle( + color: _isHovered ? Theme.of(context).colorScheme.primary : null, + fontSize: 14, + ), + ), + onTap: () { + widget.onQuestionSelected(widget.question.content); + }, + trailing: FlowySvg( + FlowySvgs.add_m, + color: Theme.of(context).colorScheme.primary, + ), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_streaming_error_message.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_streaming_error_message.dart new file mode 100644 index 0000000000..c0552a7e8e --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_streaming_error_message.dart @@ -0,0 +1,84 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; + +class ChatStreamingError extends StatelessWidget { + const ChatStreamingError({ + required this.message, + required this.onRetryPressed, + super.key, + }); + + final void Function() onRetryPressed; + final Message message; + @override + Widget build(BuildContext context) { + final canRetry = message.metadata?[canRetryKey] != null; + + if (canRetry) { + return Column( + children: [ + const Divider(height: 4, thickness: 1), + const VSpace(16), + Center( + child: Column( + children: [ + _aiUnvaliable(), + const VSpace(10), + _retryButton(), + ], + ), + ), + ], + ); + } else { + return Center( + child: Column( + children: [ + const Divider(height: 20, thickness: 1), + Padding( + padding: const EdgeInsets.all(8.0), + child: FlowyText( + LocaleKeys.chat_serverUnavailable.tr(), + fontSize: 14, + ), + ), + ], + ), + ); + } + } + + FlowyButton _retryButton() { + return FlowyButton( + radius: BorderRadius.circular(20), + useIntrinsicWidth: true, + text: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: FlowyText( + LocaleKeys.chat_regenerateAnswer.tr(), + fontSize: 14, + ), + ), + onTap: onRetryPressed, + iconPadding: 0, + leftIcon: const Icon( + Icons.refresh, + size: 20, + ), + ); + } + + Padding _aiUnvaliable() { + return Padding( + padding: const EdgeInsets.all(8.0), + child: FlowyText( + LocaleKeys.chat_aiServerUnavailable.tr(), + fontSize: 14, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_theme.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_theme.dart new file mode 100644 index 0000000000..456ac0c184 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_theme.dart @@ -0,0 +1,222 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_chat_ui/flutter_chat_ui.dart'; + +// For internal usage only. Use values from theme itself. + +/// See [ChatTheme.userAvatarNameColors]. +const colors = [ + Color(0xffff6767), + Color(0xff66e0da), + Color(0xfff5a2d9), + Color(0xfff0c722), + Color(0xff6a85e5), + Color(0xfffd9a6f), + Color(0xff92db6e), + Color(0xff73b8e5), + Color(0xfffd7590), + Color(0xffc78ae5), +]; + +/// Dark. +const dark = Color(0xff1f1c38); + +/// Error. +const error = Color(0xffff6767); + +/// N0. +const neutral0 = Color(0xff1d1c21); + +/// N1. +const neutral1 = Color(0xff615e6e); + +/// N2. +const neutral2 = Color(0xff9e9cab); + +/// N7. +const neutral7 = Color(0xffffffff); + +/// N7 with opacity. +const neutral7WithOpacity = Color(0x80ffffff); + +/// Primary. +const primary = Color(0xff6f61e8); + +/// Secondary. +const secondary = Color(0xfff5f5f7); + +/// Secondary dark. +const secondaryDark = Color(0xff2b2250); + +/// Default chat theme which extends [ChatTheme]. +@immutable +class AFDefaultChatTheme extends ChatTheme { + /// Creates a default chat theme. Use this constructor if you want to + /// override only a couple of properties, otherwise create a new class + /// which extends [ChatTheme]. + const AFDefaultChatTheme({ + super.attachmentButtonIcon, + super.attachmentButtonMargin, + super.backgroundColor = neutral7, + super.bubbleMargin, + super.dateDividerMargin = const EdgeInsets.only( + bottom: 32, + top: 16, + ), + super.dateDividerTextStyle = const TextStyle( + color: neutral2, + fontSize: 12, + fontWeight: FontWeight.w800, + height: 1.333, + ), + super.deliveredIcon, + super.documentIcon, + super.emptyChatPlaceholderTextStyle = const TextStyle( + color: neutral2, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + super.errorColor = error, + super.errorIcon, + super.inputBackgroundColor = neutral0, + super.inputSurfaceTintColor = neutral0, + super.inputElevation = 0, + super.inputBorderRadius = const BorderRadius.vertical( + top: Radius.circular(20), + ), + super.inputContainerDecoration, + super.inputMargin = EdgeInsets.zero, + super.inputPadding = const EdgeInsets.fromLTRB(14, 20, 14, 20), + super.inputTextColor = neutral7, + super.inputTextCursorColor, + super.inputTextDecoration = const InputDecoration( + border: InputBorder.none, + contentPadding: EdgeInsets.zero, + isCollapsed: true, + ), + super.inputTextStyle = const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + super.messageBorderRadius = 20, + super.messageInsetsHorizontal = 0, + super.messageInsetsVertical = 0, + super.messageMaxWidth = 1000, + super.primaryColor = primary, + super.receivedEmojiMessageTextStyle = const TextStyle(fontSize: 40), + super.receivedMessageBodyBoldTextStyle, + super.receivedMessageBodyCodeTextStyle, + super.receivedMessageBodyLinkTextStyle, + super.receivedMessageBodyTextStyle = const TextStyle( + color: neutral0, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + super.receivedMessageCaptionTextStyle = const TextStyle( + color: neutral2, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.333, + ), + super.receivedMessageDocumentIconColor = primary, + super.receivedMessageLinkDescriptionTextStyle = const TextStyle( + color: neutral0, + fontSize: 14, + fontWeight: FontWeight.w400, + height: 1.428, + ), + super.receivedMessageLinkTitleTextStyle = const TextStyle( + color: neutral0, + fontSize: 16, + fontWeight: FontWeight.w800, + height: 1.375, + ), + super.secondaryColor = secondary, + super.seenIcon, + super.sendButtonIcon, + super.sendButtonMargin, + super.sendingIcon, + super.sentEmojiMessageTextStyle = const TextStyle(fontSize: 40), + super.sentMessageBodyBoldTextStyle, + super.sentMessageBodyCodeTextStyle, + super.sentMessageBodyLinkTextStyle, + super.sentMessageBodyTextStyle = const TextStyle( + color: neutral7, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + super.sentMessageCaptionTextStyle = const TextStyle( + color: neutral7WithOpacity, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.333, + ), + super.sentMessageDocumentIconColor = neutral7, + super.sentMessageLinkDescriptionTextStyle = const TextStyle( + color: neutral7, + fontSize: 14, + fontWeight: FontWeight.w400, + height: 1.428, + ), + super.sentMessageLinkTitleTextStyle = const TextStyle( + color: neutral7, + fontSize: 16, + fontWeight: FontWeight.w800, + height: 1.375, + ), + super.statusIconPadding = const EdgeInsets.symmetric(horizontal: 4), + super.systemMessageTheme = const SystemMessageTheme( + margin: EdgeInsets.only( + bottom: 24, + top: 8, + left: 8, + right: 8, + ), + textStyle: TextStyle( + color: neutral2, + fontSize: 12, + fontWeight: FontWeight.w800, + height: 1.333, + ), + ), + super.typingIndicatorTheme = const TypingIndicatorTheme( + animatedCirclesColor: neutral1, + animatedCircleSize: 5.0, + bubbleBorder: BorderRadius.all(Radius.circular(27.0)), + bubbleColor: neutral7, + countAvatarColor: primary, + countTextColor: secondary, + multipleUserTextStyle: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: neutral2, + ), + ), + super.unreadHeaderTheme = const UnreadHeaderTheme( + color: secondary, + textStyle: TextStyle( + color: neutral2, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.333, + ), + ), + super.userAvatarImageBackgroundColor = Colors.transparent, + super.userAvatarNameColors = colors, + super.userAvatarTextStyle = const TextStyle( + color: neutral7, + fontSize: 12, + fontWeight: FontWeight.w800, + height: 1.333, + ), + super.userNameTextStyle = const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w800, + height: 1.333, + ), + super.highlightMessageColor, + }); +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_invalid_message.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_invalid_message.dart new file mode 100644 index 0000000000..8ae9b91d32 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_invalid_message.dart @@ -0,0 +1,31 @@ +import 'package:appflowy/plugins/ai_chat/application/chat_bloc.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; + +class ChatInvalidUserMessage extends StatelessWidget { + const ChatInvalidUserMessage({ + required this.message, + super.key, + }); + + final Message message; + @override + Widget build(BuildContext context) { + final errorMessage = message.metadata?[sendMessageErrorKey] ?? ""; + return Center( + child: Column( + children: [ + const Divider(height: 20, thickness: 1), + Padding( + padding: const EdgeInsets.all(8.0), + child: FlowyText( + errorMessage, + fontSize: 14, + ), + ), + ], + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart new file mode 100644 index 0000000000..f6e55b8090 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart @@ -0,0 +1,169 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/ai_chat/application/chat_user_message_bloc.dart'; +import 'package:appflowy/plugins/ai_chat/presentation/chat_avatar.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart'; +import 'package:styled_widget/styled_widget.dart'; + +class ChatUserMessageBubble extends StatelessWidget { + const ChatUserMessageBubble({ + super.key, + required this.message, + required this.child, + }); + + final Message message; + final Widget child; + + @override + Widget build(BuildContext context) { + const borderRadius = BorderRadius.all(Radius.circular(6)); + final backgroundColor = Theme.of(context).colorScheme.secondary; + + return BlocProvider( + create: (context) => ChatUserMessageBloc(message: message), + child: BlocBuilder( + builder: (context, state) { + return Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // _wrapHover( + Flexible( + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: borderRadius, + color: backgroundColor, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 12, + ), + child: child, + ), + ), + ), + // ), + BlocBuilder( + builder: (context, state) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: ChatUserAvatar( + iconUrl: state.member?.avatarUrl ?? "", + name: state.member?.name ?? "", + size: 36, + ), + ); + }, + ), + ], + ); + }, + ), + ); + } +} + +class ChatUserMessageHover extends StatefulWidget { + const ChatUserMessageHover({ + super.key, + required this.child, + required this.message, + }); + + final Widget child; + final Message message; + final bool autoShowHover = true; + + @override + State createState() => _ChatUserMessageHoverState(); +} + +class _ChatUserMessageHoverState extends State { + bool _isHover = false; + + @override + void initState() { + super.initState(); + _isHover = widget.autoShowHover ? false : true; + } + + @override + Widget build(BuildContext context) { + final List children = [ + DecoratedBox( + decoration: const BoxDecoration( + color: Colors.transparent, + borderRadius: Corners.s6Border, + ), + child: Padding( + padding: const EdgeInsets.only(bottom: 30), + child: widget.child, + ), + ), + ]; + + if (_isHover) { + if (widget.message is TextMessage) { + children.add( + EditButton( + textMessage: widget.message as TextMessage, + ).positioned(right: 0, bottom: 0), + ); + } + } + + return MouseRegion( + cursor: SystemMouseCursors.click, + opaque: false, + onEnter: (p) => setState(() { + if (widget.autoShowHover) { + _isHover = true; + } + }), + onExit: (p) => setState(() { + if (widget.autoShowHover) { + _isHover = false; + } + }), + child: Stack( + alignment: AlignmentDirectional.centerStart, + children: children, + ), + ); + } +} + +class EditButton extends StatelessWidget { + const EditButton({ + super.key, + required this.textMessage, + }); + final TextMessage textMessage; + + @override + Widget build(BuildContext context) { + return FlowyTooltip( + message: LocaleKeys.settings_menu_clickToCopy.tr(), + child: FlowyIconButton( + width: 24, + hoverColor: AFThemeExtension.of(context).lightGreyHover, + fillColor: Theme.of(context).cardColor, + icon: FlowySvg( + FlowySvgs.ai_copy_s, + size: const Size.square(14), + color: Theme.of(context).colorScheme.primary, + ), + onPressed: () {}, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart new file mode 100644 index 0000000000..e6fc55a15a --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class ChatWelcomePage extends StatelessWidget { + const ChatWelcomePage({super.key}); + + @override + Widget build(BuildContext context) { + return const SizedBox.shrink(); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/blank/blank.dart b/frontend/appflowy_flutter/lib/plugins/blank/blank.dart index 9e4a6ba373..1aec6b7037 100644 --- a/frontend/appflowy_flutter/lib/plugins/blank/blank.dart +++ b/frontend/appflowy_flutter/lib/plugins/blank/blank.dart @@ -2,6 +2,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; @@ -20,6 +21,9 @@ class BlankPluginBuilder extends PluginBuilder { @override PluginType get pluginType => PluginType.blank; + + @override + ViewLayoutPB get layoutType => ViewLayoutPB.Document; } class BlankPluginConfig implements PluginConfig { @@ -47,7 +51,10 @@ class BlankPagePluginWidgetBuilder extends PluginWidgetBuilder Widget tabBarItem(String pluginId) => leftBarItem; @override - Widget buildWidget({PluginContext? context, required bool shrinkWrap}) => + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }) => const BlankPage(); @override diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/board.dart b/frontend/appflowy_flutter/lib/plugins/database/board/board.dart index fb267220be..86851c4bbb 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/board.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/board.dart @@ -25,7 +25,7 @@ class BoardPluginBuilder implements PluginBuilder { PluginType get pluginType => PluginType.board; @override - ViewLayoutPB? get layoutType => ViewLayoutPB.Board; + ViewLayoutPB get layoutType => ViewLayoutPB.Board; } class BoardPluginConfig implements PluginConfig { diff --git a/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart b/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart index 099714c304..861d9f4303 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart @@ -25,7 +25,7 @@ class CalendarPluginBuilder extends PluginBuilder { PluginType get pluginType => PluginType.calendar; @override - ViewLayoutPB? get layoutType => ViewLayoutPB.Calendar; + ViewLayoutPB get layoutType => ViewLayoutPB.Calendar; } class CalendarPluginConfig implements PluginConfig { diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart index 3a10835489..1f8816d92b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart @@ -25,7 +25,7 @@ class GridPluginBuilder implements PluginBuilder { PluginType get pluginType => PluginType.grid; @override - ViewLayoutPB? get layoutType => ViewLayoutPB.Grid; + ViewLayoutPB get layoutType => ViewLayoutPB.Grid; } class GridPluginConfig implements PluginConfig { diff --git a/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart b/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart index 787e08760b..aec6d954b4 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/tab_bar/tab_bar_view.dart @@ -243,11 +243,14 @@ class DatabasePluginWidgetBuilder extends PluginWidgetBuilder { Widget tabBarItem(String pluginId) => ViewTabBarItem(view: notifier.view); @override - Widget buildWidget({PluginContext? context, required bool shrinkWrap}) { + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }) { notifier.isDeleted.addListener(() { final deletedView = notifier.isDeleted.value; if (deletedView != null && deletedView.hasIndex()) { - context?.onDeleted(notifier.view, deletedView.index); + context.onDeleted?.call(notifier.view, deletedView.index); } }); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart index 97e13a626a..ee64eb84af 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart @@ -54,6 +54,7 @@ class _DatabaseViewWidgetState extends State { valueListenable: _layoutTypeChangeNotifier, builder: (_, __, ___) => viewPlugin.widgetBuilder.buildWidget( shrinkWrap: widget.shrinkWrap, + context: PluginContext(), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart b/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart index ce3668b43d..cd709e2154 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart @@ -48,6 +48,9 @@ class DatabaseDocumentPluginBuilder extends PluginBuilder { @override PluginType get pluginType => PluginType.databaseDocument; + + @override + ViewLayoutPB get layoutType => ViewLayoutPB.Document; } class DatabaseDocumentPlugin extends Plugin { @@ -98,7 +101,10 @@ class DatabaseDocumentPluginWidgetBuilder extends PluginWidgetBuilder EdgeInsets get contentPadding => EdgeInsets.zero; @override - Widget buildWidget({PluginContext? context, required bool shrinkWrap}) { + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }) { return BlocBuilder( builder: (_, state) => DatabaseDocumentPage( key: ValueKey(documentId), diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index bd9e4891d2..cb48cd1bba 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -43,7 +43,7 @@ class DocumentPluginBuilder extends PluginBuilder { PluginType get pluginType => PluginType.document; @override - ViewLayoutPB? get layoutType => ViewLayoutPB.Document; + ViewLayoutPB get layoutType => ViewLayoutPB.Document; } class DocumentPlugin extends Plugin { @@ -107,7 +107,10 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder EdgeInsets get contentPadding => EdgeInsets.zero; @override - Widget buildWidget({PluginContext? context, required bool shrinkWrap}) { + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }) { notifier.isDeleted.addListener(() { final deletedView = notifier.isDeleted.value; if (deletedView != null && deletedView.hasIndex()) { @@ -121,7 +124,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder builder: (_, state) => DocumentPage( key: ValueKey(view.id), view: view, - onDeleted: () => context?.onDeleted(view, deletedViewIndex), + onDeleted: () => context.onDeleted?.call(view, deletedViewIndex), initialSelection: initialSelection, ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_configuration.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_configuration.dart index 39cd608d0e..966a5685f5 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_configuration.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_configuration.dart @@ -5,6 +5,8 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/mo import 'package:appflowy/plugins/document/presentation/editor_plugins/code_block/code_block_copy_button.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/image/custom_image_block_component.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/video/video_menu.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/video/video_placeholder.dart'; import 'package:appflowy/plugins/document/presentation/editor_style.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; @@ -53,9 +55,8 @@ Map getEditorBuilderMap({ configuration: configuration.copyWith( placeholderText: (_) => LocaleKeys.blockPlaceholders_todoList.tr(), ), - iconBuilder: PlatformExtension.isMobile - ? (_, node, onCheck) => TodoListIcon(node: node, onCheck: onCheck) - : null, + iconBuilder: (_, node, onCheck) => + TodoListIcon(node: node, onCheck: onCheck), toggleChildrenTriggers: [ LogicalKeyboardKey.shift, LogicalKeyboardKey.shiftLeft, @@ -66,18 +67,14 @@ Map getEditorBuilderMap({ configuration: configuration.copyWith( placeholderText: (_) => LocaleKeys.blockPlaceholders_bulletList.tr(), ), - iconBuilder: PlatformExtension.isMobile - ? (_, node) => BulletedListIcon(node: node) - : null, + iconBuilder: (_, node) => BulletedListIcon(node: node), ), NumberedListBlockKeys.type: NumberedListBlockComponentBuilder( configuration: configuration.copyWith( placeholderText: (_) => LocaleKeys.blockPlaceholders_numberList.tr(), ), - iconBuilder: PlatformExtension.isMobile - ? (_, node, textDirection) => - NumberedListIcon(node: node, textDirection: textDirection) - : null, + iconBuilder: (_, node, textDirection) => + NumberedListIcon(node: node, textDirection: textDirection), ), QuoteBlockKeys.type: QuoteBlockComponentBuilder( configuration: configuration.copyWith( @@ -99,9 +96,13 @@ Map getEditorBuilderMap({ return const EdgeInsets.only(top: 12.0, bottom: 4.0); }, - placeholderText: (node) => LocaleKeys.blockPlaceholders_heading.tr( - args: [node.attributes[HeadingBlockKeys.level].toString()], - ), + placeholderText: (node) { + int level = node.attributes[HeadingBlockKeys.level] ?? 6; + level = level.clamp(1, 6); + return LocaleKeys.blockPlaceholders_heading.tr( + args: [level.toString()], + ); + }, ), textStyleBuilder: (level) => styleCustomizer.headingStyleBuilder(level), ), @@ -110,7 +111,7 @@ Map getEditorBuilderMap({ showMenu: true, menuBuilder: (Node node, CustomImageBlockComponentState state) => Positioned( - top: 0, + top: 10, right: 10, child: ImageMenu(node: node, state: state), ), @@ -163,7 +164,10 @@ Map getEditorBuilderMap({ ), ), CalloutBlockKeys.type: CalloutBlockComponentBuilder( - configuration: configuration, + configuration: configuration.copyWith( + textStyle: (_) => styleCustomizer.calloutBlockStyleBuilder(), + placeholderTextStyle: (_) => styleCustomizer.calloutBlockStyleBuilder(), + ), defaultColor: calloutBGColor, ), DividerBlockKeys.type: DividerBlockComponentBuilder( @@ -180,7 +184,6 @@ Map getEditorBuilderMap({ configuration: configuration, ), CodeBlockKeys.type: CodeBlockComponentBuilder( - editorState: editorState, configuration: configuration.copyWith( textStyle: (_) => styleCustomizer.codeBlockStyleBuilder(), placeholderTextStyle: (_) => styleCustomizer.codeBlockStyleBuilder(), @@ -228,6 +231,16 @@ Map getEditorBuilderMap({ errorBlockComponentBuilderKey: ErrorBlockComponentBuilder( configuration: configuration, ), + VideoBlockKeys.type: VideoBlockComponentBuilder( + configuration: configuration, + showMenu: true, + menuBuilder: (node, state) => Positioned( + top: 10, + right: 10, + child: VideoMenu(node: node, state: state), + ), + placeholderBuilder: (node) => VideoPlaceholder(node: node), + ), }; final builders = { diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 13d2ba6ab9..2199d0bb3b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -1,5 +1,8 @@ import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_configuration.dart'; @@ -20,6 +23,7 @@ import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.dart'; import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; @@ -27,8 +31,6 @@ import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; final codeBlockLocalization = CodeBlockLocalizations( @@ -211,6 +213,10 @@ class _AppFlowyEditorPageState extends State { style: styleCustomizer.selectionMenuStyleBuilder(), ).handler(editorState); + AFFocusManager? focusManager; + + void _loseFocus() => widget.editorState.selection = null; + @override void initState() { super.initState(); @@ -251,17 +257,35 @@ class _AppFlowyEditorPageState extends State { // customize the dynamic theme color _customizeBlockComponentBackgroundColorDecorator(); - if (widget.initialSelection != null) { - WidgetsBinding.instance.addPostFrameCallback((_) { - widget.editorState.updateSelectionWithReason( - widget.initialSelection, - ); - }); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) { + return; + } + + focusManager = AFFocusManager.maybeOf(context); + focusManager?.loseFocusNotifier.addListener(_loseFocus); + + if (widget.initialSelection != null) { + widget.editorState.updateSelectionWithReason(widget.initialSelection); + } + }); + } + + @override + void didChangeDependencies() { + final currFocusManager = AFFocusManager.maybeOf(context); + if (focusManager != currFocusManager) { + focusManager?.loseFocusNotifier.removeListener(_loseFocus); + focusManager = currFocusManager; + focusManager?.loseFocusNotifier.addListener(_loseFocus); } + super.didChangeDependencies(); } @override void dispose() { + focusManager?.loseFocusNotifier.removeListener(_loseFocus); + if (widget.useViewInfoBloc && !viewInfoBloc.isClosed) { viewInfoBloc.add(const ViewInfoEvent.unregisterEditorState()); } @@ -388,6 +412,7 @@ class _AppFlowyEditorPageState extends State { emojiMenuItem, autoGeneratorMenuItem, dateMenuItem, + videoBlockItem(LocaleKeys.document_plugins_video_label.tr()), ]; } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/bulleted_list/bulleted_list_icon.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/bulleted_list/bulleted_list_icon.dart index d0551b03af..abb166ec12 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/bulleted_list/bulleted_list_icon.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/bulleted_list/bulleted_list_icon.dart @@ -37,7 +37,9 @@ class BulletedListIcon extends StatelessWidget { @override Widget build(BuildContext context) { - final iconPadding = context.read().state.iconPadding; + final iconPadding = PlatformExtension.isMobile + ? context.read().state.iconPadding + : 0.0; return Container( constraints: const BoxConstraints( minWidth: 22, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/cover/document_immersive_cover.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/cover/document_immersive_cover.dart index 741b3c16ee..92f04719a4 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/cover/document_immersive_cover.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/cover/document_immersive_cover.dart @@ -1,12 +1,14 @@ import 'dart:io'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart'; -import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart'; -import 'package:appflowy/plugins/base/icon/icon_picker.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/plugins/document/application/prelude.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/base/build_context_extension.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/cover/document_immersive_cover_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_icon_widget.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/icon/icon_selector.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_icon_bloc.dart'; import 'package:appflowy/shared/appflowy_network_image.dart'; import 'package:appflowy/shared/flowy_gradient_colors.dart'; import 'package:appflowy/shared/google_fonts_extension.dart'; @@ -16,11 +18,13 @@ import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:auto_size_text_field/auto_size_text_field.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/ignore_parent_gesture.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:go_router/go_router.dart'; double kDocumentCoverHeight = 98.0; double kDocumentTitlePadding = 20.0; @@ -133,9 +137,11 @@ class _DocumentImmersiveCoverState extends State { if (documentFontFamily != null && fontFamily != documentFontFamily) { fontFamily = getGoogleFontSafely(documentFontFamily).fontFamily; } - return TextField( + + return AutoSizeTextField( controller: textEditingController, focusNode: focusNode, + minFontSize: 18.0, decoration: const InputDecoration( border: InputBorder.none, enabledBorder: InputBorder.none, @@ -151,6 +157,7 @@ class _DocumentImmersiveCoverState extends State { fontFamily: fontFamily, color: state.cover.isNone || state.cover.isPresets ? null : Colors.white, + overflow: TextOverflow.ellipsis, ), onChanged: _rename, onSubmitted: _rename, @@ -167,12 +174,40 @@ class _DocumentImmersiveCoverState extends State { ), ), onTap: () async { - final result = await context.push( - MobileEmojiPickerScreen.routeName, + final pageStyleIconBloc = PageStyleIconBloc(view: widget.view) + ..add(const PageStyleIconEvent.initial()); + await showMobileBottomSheet( + context, + showDragHandle: true, + showDivider: false, + showDoneButton: true, + showHeader: true, + title: LocaleKeys.titleBar_pageIcon.tr(), + backgroundColor: AFThemeExtension.of(context).background, + enableDraggableScrollable: true, + minChildSize: 0.6, + initialChildSize: 0.61, + showRemoveButton: true, + onRemove: () { + pageStyleIconBloc.add( + const PageStyleIconEvent.updateIcon('', true), + ); + }, + scrollableWidgetBuilder: (_, controller) { + return BlocProvider.value( + value: pageStyleIconBloc, + child: Expanded( + child: Scrollbar( + controller: controller, + child: IconSelector( + scrollController: controller, + ), + ), + ), + ); + }, + builder: (_) => const SizedBox.shrink(), ); - if (result != null && context.mounted) { - context.read().add(ViewEvent.updateIcon(result.emoji)); - } }, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/icon/icon_selector.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/icon/icon_selector.dart new file mode 100644 index 0000000000..5da4528a3c --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/icon/icon_selector.dart @@ -0,0 +1,159 @@ +import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_search_text_field.dart'; +import 'package:appflowy/plugins/base/emoji/emoji_picker.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_icon_bloc.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_emoji_mart/flutter_emoji_mart.dart'; + +class IconSelector extends StatefulWidget { + const IconSelector({ + super.key, + required this.scrollController, + }); + + final ScrollController scrollController; + + @override + State createState() => _IconSelectorState(); +} + +class _IconSelectorState extends State { + EmojiData? emojiData; + List availableEmojis = []; + + PageStyleIconBloc? pageStyleIconBloc; + + @override + void initState() { + super.initState(); + + // load the emoji data from cache if it's available + if (kCachedEmojiData != null) { + emojiData = kCachedEmojiData; + availableEmojis = _setupAvailableEmojis(emojiData!); + } else { + EmojiData.builtIn().then( + (value) { + kCachedEmojiData = value; + setState(() { + emojiData = value; + availableEmojis = _setupAvailableEmojis(value); + }); + }, + ); + } + + pageStyleIconBloc = context.read(); + } + + @override + void dispose() { + pageStyleIconBloc?.close(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (emojiData == null) { + return const Center(child: CircularProgressIndicator()); + } + + return RepaintBoundary( + child: BlocBuilder( + builder: (_, state) => Column( + children: [ + _buildSearchBar(context), + Expanded( + child: GridView.count( + crossAxisCount: 7, + controller: widget.scrollController, + children: [ + for (final emoji in availableEmojis) + _buildEmoji(context, emoji, state.icon), + ], + ), + ), + ], + ), + ), + ); + } + + Widget _buildEmoji( + BuildContext context, + String emoji, + String? selectedEmoji, + ) { + Widget child = SizedBox.square( + dimension: 24.0, + child: Center( + child: FlowyText.emoji( + emoji, + fontSize: 24, + ), + ), + ); + + if (emoji == selectedEmoji) { + child = Center( + child: Container( + width: 40, + height: 40, + decoration: ShapeDecoration( + shape: RoundedRectangleBorder( + side: const BorderSide( + width: 1.40, + strokeAlign: BorderSide.strokeAlignOutside, + color: Color(0xFF00BCF0), + ), + borderRadius: BorderRadius.circular(10), + ), + ), + child: child, + ), + ); + } + + return GestureDetector( + onTap: () { + context.read().add( + PageStyleIconEvent.updateIcon(emoji, true), + ); + }, + child: child, + ); + } + + List _setupAvailableEmojis(EmojiData emojiData) { + final categories = emojiData.categories; + availableEmojis = categories + .map((e) => e.emojiIds.map((e) => emojiData.getEmojiById(e))) + .expand((e) => e) + .toList(); + return availableEmojis; + } + + Widget _buildSearchBar(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric( + vertical: 8.0, + horizontal: 12.0, + ), + child: FlowyMobileSearchTextField( + onChanged: (keyword) { + if (emojiData == null) { + return; + } + + final filtered = emojiData!.filterByKeyword(keyword); + final availableEmojis = _setupAvailableEmojis(filtered); + + setState(() { + this.availableEmojis = availableEmojis; + }); + }, + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/custom_image_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/custom_image_block_component.dart index c389977333..722a79c2f5 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/custom_image_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/custom_image_block_component.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; @@ -13,7 +15,6 @@ import 'package:appflowy/util/string_extension.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy_editor/appflowy_editor.dart' hide ResizableImage; import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; import 'package:string_validator/string_validator.dart'; @@ -109,10 +110,7 @@ class CustomImageBlockComponentBuilder extends BlockComponentBuilder { node: node, showActions: showActions(node), configuration: configuration, - actionBuilder: (context, state) => actionBuilder( - blockComponentContext, - state, - ), + actionBuilder: (_, state) => actionBuilder(blockComponentContext, state), showMenu: showMenu, menuBuilder: menuBuilder, ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart index 84ab2f7380..eda320bdb3 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart @@ -112,7 +112,7 @@ class _UnsplashImageWidgetState extends State { } } -class _UnsplashImages extends StatelessWidget { +class _UnsplashImages extends StatefulWidget { const _UnsplashImages({ required this.type, required this.photos, @@ -123,17 +123,24 @@ class _UnsplashImages extends StatelessWidget { final List photos; final OnSelectUnsplashImage onSelectUnsplashImage; + @override + State<_UnsplashImages> createState() => _UnsplashImagesState(); +} + +class _UnsplashImagesState extends State<_UnsplashImages> { + int _selectedPhotoIndex = -1; + @override Widget build(BuildContext context) { - final crossAxisCount = switch (type) { + final crossAxisCount = switch (widget.type) { UnsplashImageType.halfScreen => 3, UnsplashImageType.fullScreen => 2, }; - final mainAxisSpacing = switch (type) { + final mainAxisSpacing = switch (widget.type) { UnsplashImageType.halfScreen => 16.0, UnsplashImageType.fullScreen => 16.0, }; - final crossAxisSpacing = switch (type) { + final crossAxisSpacing = switch (widget.type) { UnsplashImageType.halfScreen => 10.0, UnsplashImageType.fullScreen => 16.0, }; @@ -142,17 +149,23 @@ class _UnsplashImages extends StatelessWidget { mainAxisSpacing: mainAxisSpacing, crossAxisSpacing: crossAxisSpacing, childAspectRatio: 4 / 3, - children: photos - .map( - (photo) => _UnsplashImage( - type: type, - photo: photo, - onTap: () => onSelectUnsplashImage( - photo.urls.full.toString(), - ), - ), - ) - .toList(), + children: widget.photos.asMap().entries.map((entry) { + final index = entry.key; + final photo = entry.value; + return _UnsplashImage( + type: widget.type, + photo: photo, + onTap: () { + widget.onSelectUnsplashImage( + photo.urls.regular.toString(), + ); + setState(() { + _selectedPhotoIndex = index; + }); + }, + isSelected: index == _selectedPhotoIndex, + ); + }).toList(), ); } } @@ -162,11 +175,13 @@ class _UnsplashImage extends StatelessWidget { required this.type, required this.photo, required this.onTap, + required this.isSelected, }); final UnsplashImageType type; final Photo photo; final VoidCallback onTap; + final bool isSelected; @override Widget build(BuildContext context) { @@ -177,7 +192,19 @@ class _UnsplashImage extends StatelessWidget { return GestureDetector( onTap: onTap, - child: child, + child: isSelected + ? Container( + clipBehavior: Clip.antiAlias, + decoration: ShapeDecoration( + shape: RoundedRectangleBorder( + side: const BorderSide(width: 1.50, color: Color(0xFF00BCF0)), + borderRadius: BorderRadius.circular(8.0), + ), + ), + padding: const EdgeInsets.all(2.0), + child: child, + ) + : child, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart index d0be5af466..7ce86c3035 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart @@ -197,6 +197,15 @@ class _AddBlockMenu extends StatelessWidget { }, ), + // video + TypeOptionMenuItemValue( + value: VideoBlockKeys.type, + backgroundColor: colorMap[VideoBlockKeys.type]!, + text: LocaleKeys.document_plugins_video_label.tr(), + icon: FlowySvgs.m_add_block_video_s, + onTap: (_, __) => _insertBlock(videoBlockNode()), + ), + // date TypeOptionMenuItemValue( value: ParagraphBlockKeys.type, @@ -287,6 +296,7 @@ class _AddBlockMenu extends StatelessWidget { NumberedListBlockKeys.type: const Color(0xFFA35F94), ToggleListBlockKeys.type: const Color(0xFFA35F94), ImageBlockKeys.type: const Color(0xFFBAAC74), + VideoBlockKeys.type: const Color(0xFFBAAC74), MentionBlockKeys.type: const Color(0xFF40AAB8), DividerBlockKeys.type: const Color(0xFF4BB299), CalloutBlockKeys.type: const Color(0xFF66599B), @@ -303,6 +313,7 @@ class _AddBlockMenu extends StatelessWidget { NumberedListBlockKeys.type: const Color(0xFFFFB9EF), ToggleListBlockKeys.type: const Color(0xFFFFB9EF), ImageBlockKeys.type: const Color(0xFFFDEDA7), + VideoBlockKeys.type: const Color(0xFFFDEDA7), MentionBlockKeys.type: const Color(0xFF91EAF5), DividerBlockKeys.type: const Color(0xFF98F4CD), CalloutBlockKeys.type: const Color(0xFFCABDFF), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/page_style/_page_style_icon.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/page_style/_page_style_icon.dart index 434dba7337..3f3ed87522 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/page_style/_page_style_icon.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/page_style/_page_style_icon.dart @@ -1,8 +1,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; -import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_search_text_field.dart'; -import 'package:appflowy/plugins/base/emoji/emoji_picker.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/icon/icon_selector.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_icon_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_util.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; @@ -11,7 +10,6 @@ import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_emoji_mart/flutter_emoji_mart.dart'; import 'package:go_router/go_router.dart'; class PageStyleIcon extends StatefulWidget { @@ -94,7 +92,7 @@ class _PageStyleIconState extends State { child: Expanded( child: Scrollbar( controller: controller, - child: _IconSelector( + child: IconSelector( scrollController: controller, ), ), @@ -105,154 +103,3 @@ class _PageStyleIconState extends State { ); } } - -class _IconSelector extends StatefulWidget { - const _IconSelector({ - required this.scrollController, - }); - - final ScrollController scrollController; - - @override - State<_IconSelector> createState() => _IconSelectorState(); -} - -class _IconSelectorState extends State<_IconSelector> { - EmojiData? emojiData; - List availableEmojis = []; - - PageStyleIconBloc? pageStyleIconBloc; - - @override - void initState() { - super.initState(); - - // load the emoji data from cache if it's available - if (kCachedEmojiData != null) { - emojiData = kCachedEmojiData; - availableEmojis = _setupAvailableEmojis(emojiData!); - } else { - EmojiData.builtIn().then( - (value) { - kCachedEmojiData = value; - setState(() { - emojiData = value; - availableEmojis = _setupAvailableEmojis(value); - }); - }, - ); - } - - pageStyleIconBloc = context.read(); - } - - @override - void dispose() { - pageStyleIconBloc?.close(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if (emojiData == null) { - return const Center(child: CircularProgressIndicator()); - } - - return RepaintBoundary( - child: BlocBuilder( - builder: (_, state) => Column( - children: [ - _buildSearchBar(context), - Expanded( - child: GridView.count( - crossAxisCount: 7, - controller: widget.scrollController, - children: [ - for (final emoji in availableEmojis) - _buildEmoji(context, emoji, state.icon), - ], - ), - ), - ], - ), - ), - ); - } - - Widget _buildEmoji( - BuildContext context, - String emoji, - String? selectedEmoji, - ) { - Widget child = SizedBox.square( - dimension: 24.0, - child: Center( - child: FlowyText.emoji( - emoji, - fontSize: 24, - ), - ), - ); - - if (emoji == selectedEmoji) { - child = Center( - child: Container( - width: 40, - height: 40, - decoration: ShapeDecoration( - shape: RoundedRectangleBorder( - side: const BorderSide( - width: 1.40, - strokeAlign: BorderSide.strokeAlignOutside, - color: Color(0xFF00BCF0), - ), - borderRadius: BorderRadius.circular(10), - ), - ), - child: child, - ), - ); - } - - return GestureDetector( - onTap: () { - context.read().add( - PageStyleIconEvent.updateIcon(emoji, true), - ); - }, - child: child, - ); - } - - List _setupAvailableEmojis(EmojiData emojiData) { - final categories = emojiData.categories; - availableEmojis = categories - .map((e) => e.emojiIds.map((e) => emojiData.getEmojiById(e))) - .expand((e) => e) - .toList(); - return availableEmojis; - } - - Widget _buildSearchBar(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric( - vertical: 8.0, - horizontal: 12.0, - ), - child: FlowyMobileSearchTextField( - onChanged: (keyword) { - if (emojiData == null) { - return; - } - - final filtered = emojiData!.filterByKeyword(keyword); - final availableEmojis = _setupAvailableEmojis(filtered); - - setState(() { - this.availableEmojis = availableEmojis; - }); - }, - ), - ); - } -} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/todo_list/todo_list_icon.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/todo_list/todo_list_icon.dart index deb45c2182..85972a3c2c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/todo_list/todo_list_icon.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/todo_list/todo_list_icon.dart @@ -17,7 +17,9 @@ class TodoListIcon extends StatelessWidget { @override Widget build(BuildContext context) { - final iconPadding = context.read().state.iconPadding; + final iconPadding = PlatformExtension.isMobile + ? context.read().state.iconPadding + : 0.0; final checked = node.attributes[TodoListBlockKeys.checked] ?? false; return GestureDetector( behavior: HitTestBehavior.opaque, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart new file mode 100644 index 0000000000..83fa36ceff --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/shared/patterns/common_patterns.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' hide ColorOption; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; + +class UploadVideoMenu extends StatefulWidget { + const UploadVideoMenu({ + super.key, + required this.onUrlSubmitted, + this.onSelectedColor, + }); + + final void Function(String url) onUrlSubmitted; + final void Function(String color)? onSelectedColor; + + @override + State createState() => _UploadVideoMenuState(); +} + +class _UploadVideoMenuState extends State { + @override + Widget build(BuildContext context) { + final constraints = + PlatformExtension.isMobile ? const BoxConstraints(minHeight: 92) : null; + + return Container( + padding: const EdgeInsets.all(8.0), + constraints: constraints, + child: _EmbedUrl(onSubmit: widget.onUrlSubmitted), + ); + } +} + +class _EmbedUrl extends StatefulWidget { + const _EmbedUrl({required this.onSubmit}); + + final void Function(String url) onSubmit; + + @override + State<_EmbedUrl> createState() => _EmbedUrlState(); +} + +class _EmbedUrlState extends State<_EmbedUrl> { + bool isUrlValid = true; + bool isYouTubeError = false; + String inputText = ''; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + FlowyTextField( + hintText: LocaleKeys.document_plugins_video_placeholder.tr(), + onChanged: (value) => inputText = value, + onEditingComplete: submit, + ), + if (!isUrlValid) ...[ + const VSpace(8), + FlowyText( + isYouTubeError + ? LocaleKeys.document_plugins_video_invalidVideoUrlYouTube.tr() + : LocaleKeys.document_plugins_video_invalidVideoUrl.tr(), + color: Theme.of(context).colorScheme.error, + ), + ], + const VSpace(8), + FlowyText( + LocaleKeys.document_plugins_video_supportedFormats.tr(), + color: Theme.of(context).hintColor, + ), + const VSpace(8), + SizedBox( + width: 160, + child: FlowyButton( + showDefaultBoxDecorationOnMobile: true, + margin: const EdgeInsets.all(8.0), + text: FlowyText( + LocaleKeys.document_plugins_video_insertVideo.tr(), + textAlign: TextAlign.center, + ), + onTap: submit, + ), + ), + ], + ); + } + + void submit() { + if (checkUrlValidity(inputText)) { + return widget.onSubmit(inputText); + } + + isYouTubeError = youtubeUrlRegex.hasMatch(inputText); + setState(() => isUrlValid = false); + } + + bool checkUrlValidity(String url) => videoUrlRegex.hasMatch(url); +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/video_menu.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/video_menu.dart new file mode 100644 index 0000000000..a82156586e --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/video_menu.dart @@ -0,0 +1,314 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_block_action_widget.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart'; +import 'package:appflowy/mobile/presentation/widgets/flowy_option_tile.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/block_menu/block_menu_button.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/workspace/presentation/home/toast.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; +import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/widget/ignore_parent_gesture.dart'; +import 'package:go_router/go_router.dart'; +import 'package:provider/provider.dart'; + +class VideoMenu extends StatefulWidget { + const VideoMenu({ + super.key, + required this.node, + required this.state, + }); + + final Node node; + final VideoBlockComponentState state; + + @override + State createState() => _VideoMenuState(); +} + +class _VideoMenuState extends State { + late final String? url = widget.node.attributes[VideoBlockKeys.url]; + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + return Container( + height: 32, + decoration: BoxDecoration( + color: theme.cardColor, + borderRadius: BorderRadius.circular(4.0), + boxShadow: [ + BoxShadow( + blurRadius: 5, + spreadRadius: 1, + color: Colors.black.withOpacity(0.1), + ), + ], + ), + child: PlatformExtension.isMobile + ? MenuBlockButton( + tooltip: LocaleKeys.button_edit.tr(), + iconData: FlowySvgs.more_s, + onTap: showMobileMenu, + ) + : Row( + children: [ + const HSpace(4), + MenuBlockButton( + tooltip: LocaleKeys.editor_copyLink.tr(), + iconData: FlowySvgs.copy_s, + onTap: copyVideoLink, + ), + const HSpace(4), + _VideoAlignButton( + node: widget.node, + state: widget.state, + ), + const _Divider(), + MenuBlockButton( + tooltip: LocaleKeys.button_delete.tr(), + iconData: FlowySvgs.delete_s, + onTap: deleteVideo, + ), + const HSpace(4), + ], + ), + ); + } + + void copyVideoLink() { + if (url != null) { + Clipboard.setData(ClipboardData(text: url!)); + showSnackBarMessage( + context, + LocaleKeys.document_plugins_video_copiedToPasteBoard.tr(), + ); + } + } + + void showMobileMenu() { + final editorState = context.read() + ..updateSelectionWithReason(null, extraInfo: {}); + final src = widget.node.attributes[VideoBlockKeys.url]; + showMobileBottomSheet( + context, + showHeader: true, + showCloseButton: true, + showDragHandle: true, + title: LocaleKeys.document_plugins_action.tr(), + builder: (context) { + return BlockActionBottomSheet( + extendActionWidgets: [ + FlowyOptionTile.text( + showTopBorder: false, + text: LocaleKeys.editor_copyLink.tr(), + leftIcon: const FlowySvg( + FlowySvgs.m_field_copy_s, + ), + onTap: () async { + context.pop(); + showSnackBarMessage( + context, + LocaleKeys.document_plugins_video_copiedToPasteBoard.tr(), + ); + await getIt().setPlainText(src); + }, + ), + ], + onAction: (action) async { + context.pop(); + + final transaction = editorState.transaction; + switch (action) { + case BlockActionBottomSheetType.delete: + transaction.deleteNode(widget.node); + break; + case BlockActionBottomSheetType.duplicate: + transaction.insertNode( + widget.node.path.next, + widget.node.copyWith(), + ); + break; + case BlockActionBottomSheetType.insertAbove: + case BlockActionBottomSheetType.insertBelow: + final path = action == BlockActionBottomSheetType.insertAbove + ? widget.node.path + : widget.node.path.next; + transaction + ..insertNode(path, paragraphNode()) + ..afterSelection = Selection.collapsed(Position(path: path)); + break; + default: + } + + if (transaction.operations.isNotEmpty) { + await editorState.apply(transaction); + } + }, + ); + }, + ); + } + + Future deleteVideo() async { + final node = widget.node; + final editorState = context.read(); + final transaction = editorState.transaction; + transaction.deleteNode(node); + transaction.afterSelection = null; + await editorState.apply(transaction); + } +} + +class _VideoAlignButton extends StatefulWidget { + const _VideoAlignButton({ + required this.node, + required this.state, + }); + + final Node node; + final VideoBlockComponentState state; + + @override + State<_VideoAlignButton> createState() => _VideoAlignButtonState(); +} + +const interceptorKey = 'video-align'; + +class _VideoAlignButtonState extends State<_VideoAlignButton> { + final gestureInterceptor = SelectionGestureInterceptor( + key: interceptorKey, + canTap: (_) => false, + ); + + String get align => + widget.node.attributes[VideoBlockKeys.alignment] ?? centerAlignmentKey; + final popoverController = PopoverController(); + late final EditorState editorState; + + @override + void initState() { + super.initState(); + editorState = context.read(); + } + + @override + void dispose() { + allowMenuClose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return IgnoreParentGestureWidget( + child: AppFlowyPopover( + onClose: allowMenuClose, + controller: popoverController, + windowPadding: const EdgeInsets.all(0), + margin: const EdgeInsets.all(0), + direction: PopoverDirection.bottomWithCenterAligned, + offset: const Offset(0, 10), + child: MenuBlockButton( + tooltip: LocaleKeys.document_plugins_optionAction_align.tr(), + iconData: iconFor(align), + ), + popupBuilder: (_) { + preventMenuClose(); + return _AlignButtons(onAlignChanged: onAlignChanged); + }, + ), + ); + } + + void onAlignChanged(String align) { + popoverController.close(); + + final transaction = editorState.transaction; + transaction.updateNode(widget.node, {VideoBlockKeys.alignment: align}); + editorState.apply(transaction); + + allowMenuClose(); + } + + void preventMenuClose() { + widget.state.preventClose = true; + editorState.service.selectionService + .registerGestureInterceptor(gestureInterceptor); + } + + void allowMenuClose() { + widget.state.preventClose = false; + editorState.service.selectionService + .unregisterGestureInterceptor(interceptorKey); + } + + FlowySvgData iconFor(String alignment) { + switch (alignment) { + case leftAlignmentKey: + return FlowySvgs.align_left_s; + case rightAlignmentKey: + return FlowySvgs.align_right_s; + case centerAlignmentKey: + default: + return FlowySvgs.align_center_s; + } + } +} + +class _AlignButtons extends StatelessWidget { + const _AlignButtons({required this.onAlignChanged}); + + final Function(String align) onAlignChanged; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 32, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const HSpace(4), + MenuBlockButton( + tooltip: LocaleKeys.document_plugins_optionAction_left, + iconData: FlowySvgs.align_left_s, + onTap: () => onAlignChanged(leftAlignmentKey), + ), + const _Divider(), + MenuBlockButton( + tooltip: LocaleKeys.document_plugins_optionAction_center, + iconData: FlowySvgs.align_center_s, + onTap: () => onAlignChanged(centerAlignmentKey), + ), + const _Divider(), + MenuBlockButton( + tooltip: LocaleKeys.document_plugins_optionAction_right, + iconData: FlowySvgs.align_right_s, + onTap: () => onAlignChanged(rightAlignmentKey), + ), + const HSpace(4), + ], + ), + ); + } +} + +class _Divider extends StatelessWidget { + const _Divider(); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8), + child: Container(width: 1, color: Colors.grey), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/video_placeholder.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/video_placeholder.dart new file mode 100644 index 0000000000..a7d853b145 --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/video_placeholder.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; + +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; +import 'package:appflowy/plugins/document/application/prelude.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/mobile_block_action_buttons.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart'; +import 'package:appflowy/workspace/presentation/home/toast.dart'; +import 'package:appflowy_editor/appflowy_editor.dart' hide Log, UploadImageMenu; +import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; +import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; +import 'package:string_validator/string_validator.dart'; + +class VideoPlaceholder extends StatefulWidget { + const VideoPlaceholder({super.key, required this.node}); + + final Node node; + + @override + State createState() => VideoPlaceholderState(); +} + +class VideoPlaceholderState extends State { + final controller = PopoverController(); + final documentService = DocumentService(); + late final editorState = context.read(); + + bool showLoading = false; + + @override + Widget build(BuildContext context) { + final Widget child = DecoratedBox( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainerHighest, + borderRadius: BorderRadius.circular(4), + ), + child: FlowyHover( + style: HoverStyle(borderRadius: BorderRadius.circular(4)), + child: SizedBox( + height: 52, + child: Row( + children: [ + const HSpace(10), + const Icon(Icons.featured_video_outlined, size: 24), + const HSpace(10), + FlowyText(LocaleKeys.document_plugins_video_emptyLabel.tr()), + ], + ), + ), + ), + ); + + if (PlatformExtension.isDesktopOrWeb) { + return AppFlowyPopover( + controller: controller, + direction: PopoverDirection.bottomWithCenterAligned, + constraints: const BoxConstraints( + maxWidth: 540, + maxHeight: 360, + minHeight: 80, + ), + clickHandler: PopoverClickHandler.gestureDetector, + popupBuilder: (_) => UploadVideoMenu( + onUrlSubmitted: (url) { + controller.close(); + WidgetsBinding.instance.addPostFrameCallback( + (_) async => updateSrc(url), + ); + }, + ), + child: child, + ); + } else { + return MobileBlockActionButtons( + node: widget.node, + editorState: editorState, + child: GestureDetector( + onTap: () { + editorState.updateSelectionWithReason(null, extraInfo: {}); + showUploadVideoMenu(); + }, + child: child, + ), + ); + } + } + + void showUploadVideoMenu() { + if (PlatformExtension.isDesktopOrWeb) { + controller.show(); + } else { + showMobileBottomSheet( + context, + title: LocaleKeys.document_plugins_video_label.tr(), + showHeader: true, + showCloseButton: true, + showDragHandle: true, + builder: (context) => Container( + margin: const EdgeInsets.only(top: 12.0), + constraints: const BoxConstraints( + maxHeight: 340, + minHeight: 80, + ), + child: UploadVideoMenu( + onUrlSubmitted: (url) async { + context.pop(); + await updateSrc(url); + }, + ), + ), + ); + } + } + + Future updateSrc(String url) async { + if (url.isEmpty || !isURL(url)) { + // show error + showSnackBarMessage( + context, + LocaleKeys.document_imageBlock_error_invalidImage.tr(), + ); + return; + } + + final transaction = editorState.transaction; + transaction.updateNode(widget.node, { + VideoBlockKeys.url: url, + }); + await editorState.apply(transaction); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart index 271aa0e340..0b3aca1ce7 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; @@ -60,6 +58,9 @@ class EditorStyleCustomizer { DefaultAppearanceSettings.getDefaultSelectionColor(context), defaultTextDirection: appearance.defaultTextDirection, textStyleConfiguration: TextStyleConfiguration( + lineHeight: 1.2, + applyHeightToFirstAscent: true, + applyHeightToLastDescent: true, text: baseTextStyle(fontFamily).copyWith( fontSize: fontSize, color: afThemeExtension.onBackground, @@ -80,7 +81,7 @@ class EditorStyleCustomizer { ), code: GoogleFonts.robotoMono( textStyle: baseTextStyle(fontFamily).copyWith( - fontSize: fontSize - 2, + fontSize: fontSize, fontWeight: FontWeight.normal, color: Colors.red, backgroundColor: theme.colorScheme.inverseSurface.withOpacity(0.8), @@ -105,7 +106,6 @@ class EditorStyleCustomizer { final textScaleFactor = context.read().state.textScaleFactor; final baseTextStyle = this.baseTextStyle(fontFamily); - final codeFontSize = max(0.0, fontSize - 2); return EditorStyle.mobile( padding: padding, defaultTextDirection: defaultTextDirection, @@ -127,7 +127,7 @@ class EditorStyleCustomizer { ), code: GoogleFonts.robotoMono( textStyle: baseTextStyle.copyWith( - fontSize: codeFontSize, + fontSize: fontSize, fontWeight: FontWeight.normal, fontStyle: FontStyle.italic, color: Colors.red, @@ -183,6 +183,14 @@ class EditorStyleCustomizer { ); } + TextStyle calloutBlockStyleBuilder() { + final fontSize = context.read().state.fontSize; + return baseTextStyle(null).copyWith( + fontSize: fontSize, + height: 1.5, + ); + } + TextStyle outlineBlockPlaceholderStyleBuilder() { final fontSize = context.read().state.fontSize; return TextStyle( diff --git a/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart b/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart index 0bbfd3359d..4da27109d2 100644 --- a/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart +++ b/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart @@ -1,7 +1,5 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/base/insert_page_command.dart'; @@ -20,6 +18,7 @@ import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; import 'package:flowy_infra_ui/widget/error_page.dart'; +import 'package:flutter/material.dart'; // const _channel = "InlinePageReference"; @@ -65,8 +64,11 @@ class InlinePageReferenceService extends InlineActionsDelegate { _recentViewsInitialized = true; - final views = - (await _recentService.recentViews()).reversed.toSet().toList(); + final views = (await _recentService.recentViews()) + .reversed + .map((e) => e.item) + .toSet() + .toList(); // Filter by viewLayout views.retainWhere( diff --git a/frontend/appflowy_flutter/lib/plugins/trash/trash.dart b/frontend/appflowy_flutter/lib/plugins/trash/trash.dart index a25609edd3..e2f312373e 100644 --- a/frontend/appflowy_flutter/lib/plugins/trash/trash.dart +++ b/frontend/appflowy_flutter/lib/plugins/trash/trash.dart @@ -5,6 +5,7 @@ export "./src/trash_header.dart"; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; @@ -26,6 +27,9 @@ class TrashPluginBuilder extends PluginBuilder { @override PluginType get pluginType => PluginType.trash; + + @override + ViewLayoutPB get layoutType => ViewLayoutPB.Document; } class TrashPluginConfig implements PluginConfig { @@ -59,7 +63,10 @@ class TrashPluginDisplay extends PluginWidgetBuilder { Widget? get rightBarItem => null; @override - Widget buildWidget({PluginContext? context, required bool shrinkWrap}) => + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }) => const TrashPage( key: ValueKey('TrashPage'), ); diff --git a/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart b/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart index fce937908a..fb9cd9f226 100644 --- a/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart +++ b/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart @@ -13,6 +13,20 @@ const _imgUrlPattern = r'(https?:\/\/)([^\s(["<,>/]*)(\/)[^\s[",><]*(.png|.jpg|.gif|.webm)(\?[^\s[",><]*)?'; final imgUrlRegex = RegExp(_imgUrlPattern); +/// This pattern allows for both HTTP and HTTPS Scheme +/// It allows for query parameters +/// It only allows the following video extensions: +/// .mp4, .mov, .avi, .webm, .flv, .m4v (mpeg), .mpeg, .h264, +/// +const _videoUrlPattern = + r'(https?:\/\/)([^\s(["<,>/]*)(\/)[^\s[",><]*(.mp4|.mov|.avi|.webm|.flv|.m4v|.mpeg|.h264)(\?[^\s[",><]*)?'; +final videoUrlRegex = RegExp(_videoUrlPattern); + +/// This pattern matches both youtube.com and shortened youtu.be urls. +/// +const _youtubeUrlPattern = r'^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/'; +final youtubeUrlRegex = RegExp(_youtubeUrlPattern); + const _appflowyCloudUrlPattern = r'^(https:\/\/)(.*)(\.appflowy\.cloud\/)(.*)'; final appflowyCloudUrlRegex = RegExp(_appflowyCloudUrlPattern); diff --git a/frontend/appflowy_flutter/lib/startup/plugin/plugin.dart b/frontend/appflowy_flutter/lib/startup/plugin/plugin.dart index e675cf1459..b81860cd99 100644 --- a/frontend/appflowy_flutter/lib/startup/plugin/plugin.dart +++ b/frontend/appflowy_flutter/lib/startup/plugin/plugin.dart @@ -1,5 +1,6 @@ library flowy_plugin; +import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:flutter/widgets.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; @@ -18,6 +19,7 @@ enum PluginType { board, calendar, databaseDocument, + chat, } typedef PluginId = String; @@ -57,7 +59,7 @@ abstract class PluginBuilder { /// The layoutType is used in the backend to determine the layout of the view. /// Currently, AppFlowy supports 4 layout types: Document, Grid, Board, Calendar. - ViewLayoutPB? get layoutType => ViewLayoutPB.Document; + ViewLayoutPB? get layoutType; } abstract class PluginConfig { @@ -71,14 +73,21 @@ abstract class PluginWidgetBuilder with NavigationItem { EdgeInsets get contentPadding => const EdgeInsets.symmetric(horizontal: 40, vertical: 28); - Widget buildWidget({PluginContext? context, required bool shrinkWrap}); + Widget buildWidget({ + required PluginContext context, + required bool shrinkWrap, + }); } class PluginContext { - PluginContext({required this.onDeleted}); + PluginContext({ + this.userProfile, + this.onDeleted, + }); // calls when widget of the plugin get deleted - final Function(ViewPB, int?) onDeleted; + final Function(ViewPB, int?)? onDeleted; + final UserProfilePB? userProfile; } void registerPlugin({required PluginBuilder builder, PluginConfig? config}) { diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart index 9e719d6ecc..f90685f030 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart @@ -253,9 +253,9 @@ class _ApplicationWidgetState extends State { } class AppGlobals { - // static GlobalKey scaffoldMessengerKey = GlobalKey(); static GlobalKey rootNavKey = GlobalKey(); static NavigatorState get nav => rootNavKey.currentState!; + static BuildContext get context => rootNavKey.currentContext!; } class ApplicationBlocObserver extends BlocObserver { diff --git a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart index 6f1a338c3f..65096984bd 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/generate_router.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:appflowy/mobile/presentation/chat/mobile_chat_screen.dart'; import 'package:appflowy/mobile/presentation/database/board/mobile_board_screen.dart'; import 'package:appflowy/mobile/presentation/database/card/card.dart'; import 'package:appflowy/mobile/presentation/database/date_picker/mobile_date_picker_screen.dart'; @@ -61,6 +62,7 @@ GoRouter generateRouter(Widget child) { _mobileGridScreenRoute(), _mobileBoardScreenRoute(), _mobileCalendarScreenRoute(), + _mobileChatScreenRoute(), // card detail page _mobileCardDetailScreenRoute(), _mobileDateCellEditScreenRoute(), @@ -488,6 +490,21 @@ GoRoute _mobileEditorScreenRoute() { ); } +GoRoute _mobileChatScreenRoute() { + return GoRoute( + path: MobileChatScreen.routeName, + parentNavigatorKey: AppGlobals.rootNavKey, + pageBuilder: (context, state) { + final id = state.uri.queryParameters[MobileChatScreen.viewId]!; + final title = state.uri.queryParameters[MobileChatScreen.viewTitle]; + + return MaterialExtendedPage( + child: MobileChatScreen(id: id, title: title), + ); + }, + ); +} + GoRoute _mobileGridScreenRoute() { return GoRoute( path: MobileGridScreen.routeName, diff --git a/frontend/appflowy_flutter/lib/startup/tasks/load_plugin.dart b/frontend/appflowy_flutter/lib/startup/tasks/load_plugin.dart index 3899959b02..9a75607d74 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/load_plugin.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/load_plugin.dart @@ -1,3 +1,4 @@ +import 'package:appflowy/plugins/ai_chat/chat.dart'; import 'package:appflowy/plugins/database/calendar/calendar.dart'; import 'package:appflowy/plugins/database/board/board.dart'; import 'package:appflowy/plugins/database/grid/grid.dart'; @@ -29,6 +30,14 @@ class PluginLoadTask extends LaunchTask { builder: DatabaseDocumentPluginBuilder(), config: DatabaseDocumentPluginConfig(), ); + registerPlugin( + builder: DatabaseDocumentPluginBuilder(), + config: DatabaseDocumentPluginConfig(), + ); + registerPlugin( + builder: AIChatPluginBuilder(), + config: AIChatPluginConfig(), + ); } @override diff --git a/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart index 6ce62acae8..8bc1e549ee 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/favorite/favorite_bloc.dart @@ -40,17 +40,20 @@ class FavoriteBloc extends Bloc { emit( result.fold( (favoriteViews) { - final views = favoriteViews.items.map((v) => v.item).toList(); - final pinnedViews = views.where((v) => v.isPinned).toList(); + final views = favoriteViews.items.toList(); + final pinnedViews = + views.where((v) => v.item.isPinned).toList(); final unpinnedViews = - views.where((v) => !v.isPinned).toList(); + views.where((v) => !v.item.isPinned).toList(); return state.copyWith( + isLoading: false, views: views, pinnedViews: pinnedViews, unpinnedViews: unpinnedViews, ); }, (error) => state.copyWith( + isLoading: false, views: [], ), ), @@ -105,12 +108,11 @@ class FavoriteEvent with _$FavoriteEvent { @freezed class FavoriteState with _$FavoriteState { const factory FavoriteState({ - required List views, - @Default([]) List pinnedViews, - @Default([]) List unpinnedViews, + @Default([]) List views, + @Default([]) List pinnedViews, + @Default([]) List unpinnedViews, + @Default(true) bool isLoading, }) = _FavoriteState; - factory FavoriteState.initial() => const FavoriteState( - views: [], - ); + factory FavoriteState.initial() => const FavoriteState(); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart b/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart index bfd4d654a3..f4245c3100 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart @@ -1,13 +1,12 @@ import 'dart:async'; -import 'package:flutter/foundation.dart'; - import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/recent/recent_listener.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; +import 'package:flutter/foundation.dart'; /// This is a lazy-singleton to share recent views across the application. /// @@ -23,21 +22,23 @@ class CachedRecentService { Completer _completer = Completer(); - ValueNotifier> notifier = ValueNotifier(const []); + ValueNotifier> notifier = ValueNotifier(const []); - List get _recentViews => notifier.value; - set _recentViews(List value) => notifier.value = value; + List get _recentViews => notifier.value; + set _recentViews(List value) => notifier.value = value; final _listener = RecentViewsListener(); - Future> recentViews() async { + Future> recentViews() async { if (_isInitialized) return _recentViews; _isInitialized = true; _listener.start(recentViewsUpdated: _recentViewsUpdated); - final result = await _readRecentViews(); - _recentViews = result.toNullable()?.items ?? const []; + _recentViews = await _readRecentViews().fold( + (s) => s.items, + (_) => [], + ); _completer.complete(); return _recentViews; @@ -47,15 +48,24 @@ class CachedRecentService { Future> updateRecentViews( List viewIds, bool addInRecent, - ) async => - FolderEventUpdateRecentViews( - UpdateRecentViewPayloadPB( - viewIds: viewIds, - addInRecent: addInRecent, - ), - ).send(); + ) async { + final List duplicatedViewIds = []; + for (final viewId in viewIds) { + for (final view in _recentViews) { + if (view.item.id == viewId) { + duplicatedViewIds.add(viewId); + } + } + } + return FolderEventUpdateRecentViews( + UpdateRecentViewPayloadPB( + viewIds: addInRecent ? viewIds : duplicatedViewIds, + addInRecent: addInRecent, + ), + ).send(); + } - Future> _readRecentViews() => + Future> _readRecentViews() => FolderEventReadRecentViews().send(); bool _isInitialized = false; @@ -74,11 +84,12 @@ class CachedRecentService { void _recentViewsUpdated( FlowyResult result, - ) { + ) async { final viewIds = result.toNullable(); if (viewIds != null) { - _readRecentViews().then( - (views) => _recentViews = views.toNullable()?.items ?? const [], + _recentViews = await _readRecentViews().fold( + (s) => s.items, + (_) => [], ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart index b43edfa2b1..d67c24e854 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart @@ -35,7 +35,12 @@ class RecentViewsBloc extends Bloc { await _service.updateRecentViews(e.viewIds, false); }, fetchRecentViews: (e) async { - emit(state.copyWith(views: await _service.recentViews())); + emit( + state.copyWith( + isLoading: false, + views: await _service.recentViews(), + ), + ); }, resetRecentViews: (e) async { await _service.reset(); @@ -63,8 +68,10 @@ class RecentViewsEvent with _$RecentViewsEvent { @freezed class RecentViewsState with _$RecentViewsState { - const factory RecentViewsState({required List views}) = - _RecentViewsState; + const factory RecentViewsState({ + required List views, + @Default(true) bool isLoading, + }) = _RecentViewsState; factory RecentViewsState.initial() => const RecentViewsState(views: []); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/notifications/notification_settings_cubit.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/notifications/notification_settings_cubit.dart index aae0a63609..ea6b3b6f01 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/notifications/notification_settings_cubit.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/notifications/notification_settings_cubit.dart @@ -1,5 +1,8 @@ import 'dart:async'; +import 'package:appflowy/core/config/kv.dart'; +import 'package:appflowy/core/config/kv_keys.dart'; +import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/user_settings_service.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart'; @@ -10,23 +13,30 @@ part 'notification_settings_cubit.freezed.dart'; class NotificationSettingsCubit extends Cubit { NotificationSettingsCubit() : super(NotificationSettingsState.initial()) { - UserSettingsBackendService() - .getNotificationSettings() - .then((notificationSettings) { - _notificationSettings = notificationSettings; - emit( - state.copyWith( - isNotificationsEnabled: _notificationSettings.notificationsEnabled, - ), - ); - _initCompleter.complete(); - }); + _initialize(); } final Completer _initCompleter = Completer(); late final NotificationSettingsPB _notificationSettings; + Future _initialize() async { + _notificationSettings = + await UserSettingsBackendService().getNotificationSettings(); + + final showNotificationSetting = await getIt() + .getWithFormat(KVKeys.showNotificationIcon, (v) => bool.parse(v)); + + emit( + state.copyWith( + isNotificationsEnabled: _notificationSettings.notificationsEnabled, + isShowNotificationsIconEnabled: showNotificationSetting ?? true, + ), + ); + + _initCompleter.complete(); + } + Future toggleNotificationsEnabled() async { await _initCompleter.future; @@ -41,9 +51,24 @@ class NotificationSettingsCubit extends Cubit { await _saveNotificationSettings(); } + Future toogleShowNotificationIconEnabled() async { + await _initCompleter.future; + + emit( + state.copyWith( + isShowNotificationsIconEnabled: !state.isShowNotificationsIconEnabled, + ), + ); + } + Future _saveNotificationSettings() async { await _initCompleter.future; + await getIt().set( + KVKeys.showNotificationIcon, + state.isShowNotificationsIconEnabled.toString(), + ); + final result = await UserSettingsBackendService() .setNotificationSettings(_notificationSettings); result.fold( @@ -59,8 +84,12 @@ class NotificationSettingsState with _$NotificationSettingsState { const factory NotificationSettingsState({ required bool isNotificationsEnabled, + required bool isShowNotificationsIconEnabled, }) = _NotificationSettingsState; factory NotificationSettingsState.initial() => - const NotificationSettingsState(isNotificationsEnabled: true); + const NotificationSettingsState( + isNotificationsEnabled: true, + isShowNotificationsIconEnabled: true, + ); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart index c0a885c19b..ec1a2c43d1 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/user/user_workspace_bloc.dart @@ -1,5 +1,3 @@ -import 'package:flutter/foundation.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/user/application/user_listener.dart'; @@ -12,6 +10,7 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:protobuf/protobuf.dart'; @@ -51,6 +50,7 @@ class UserWorkspaceBloc extends Bloc { 'init workspace, current workspace: ${currentWorkspace?.workspaceId}, ' 'workspaces: ${workspaces.map((e) => e.workspaceId)}, isCollabWorkspaceOn: $isCollabWorkspaceOn', ); + final members = await _fetchMembers(currentWorkspace?.workspaceId); if (currentWorkspace != null && result.$3 == true) { Log.info('init open workspace: ${currentWorkspace.workspaceId}'); await _userService.openWorkspace(currentWorkspace.workspaceId); @@ -61,6 +61,7 @@ class UserWorkspaceBloc extends Bloc { workspaces: workspaces, isCollabWorkspaceOn: isCollabWorkspaceOn, actionResult: null, + members: members, ), ); }, @@ -198,6 +199,7 @@ class UserWorkspaceBloc extends Bloc { ), (e) => state.currentWorkspace, ); + final members = await _fetchMembers(currentWorkspace?.workspaceId); result ..onSuccess((s) { @@ -212,6 +214,7 @@ class UserWorkspaceBloc extends Bloc { emit( state.copyWith( currentWorkspace: currentWorkspace, + members: members, actionResult: UserWorkspaceActionResult( actionType: UserWorkspaceActionType.open, isLoading: false, @@ -415,6 +418,17 @@ class UserWorkspaceBloc extends Bloc { ..name = workspace.name ..createdAtTimestamp = workspace.createTime; } + + Future> _fetchMembers( + String? workspaceId, + ) async { + if (workspaceId == null) { + return []; + } + return _userService + .getWorkspaceMembers(workspaceId) + .fold((s) => s.items, (_) => []); + } } @freezed @@ -477,6 +491,7 @@ class UserWorkspaceState with _$UserWorkspaceState { @Default([]) List workspaces, @Default(null) UserWorkspaceActionResult? actionResult, @Default(false) bool isCollabWorkspaceOn, + @Default([]) List members, }) = _UserWorkspaceState; factory UserWorkspaceState.initial() => const UserWorkspaceState(); diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart index ebf1cf2b3f..bf243f8a1c 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart @@ -19,7 +19,7 @@ import 'package:protobuf/protobuf.dart'; part 'view_bloc.freezed.dart'; class ViewBloc extends Bloc { - ViewBloc({required this.view}) + ViewBloc({required this.view, this.shouldLoadChildViews = true}) : viewBackendSvc = ViewBackendService(), listener = ViewListener(viewId: view.id), favoriteListener = FavoriteListener(), @@ -31,6 +31,7 @@ class ViewBloc extends Bloc { final ViewBackendService viewBackendSvc; final ViewListener listener; final FavoriteListener favoriteListener; + final bool shouldLoadChildViews; @override Future close() async { @@ -74,8 +75,10 @@ class ViewBloc extends Bloc { }, ); final isExpanded = await _getViewIsExpanded(view); - emit(state.copyWith(isExpanded: isExpanded)); - await _loadChildViews(emit); + emit(state.copyWith(isExpanded: isExpanded, view: view)); + if (shouldLoadChildViews) { + await _loadChildViews(emit); + } }, setIsEditing: (e) { emit(state.copyWith(isEditing: e.isEditing)); diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart index c3b17cb742..4835c795ba 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart'; +import 'package:appflowy/plugins/ai_chat/chat.dart'; import 'package:appflowy/plugins/database/board/presentation/board_page.dart'; import 'package:appflowy/plugins/database/calendar/presentation/calendar_page.dart'; import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart'; @@ -41,9 +42,10 @@ extension ViewExtension on ViewPB { Widget defaultIcon() => FlowySvg( switch (layout) { ViewLayoutPB.Board => FlowySvgs.board_s, - ViewLayoutPB.Calendar => FlowySvgs.date_s, + ViewLayoutPB.Calendar => FlowySvgs.calendar_s, ViewLayoutPB.Grid => FlowySvgs.grid_s, ViewLayoutPB.Document => FlowySvgs.document_s, + ViewLayoutPB.Chat => FlowySvgs.chat_ai_page_s, _ => FlowySvgs.document_s, }, ); @@ -53,6 +55,7 @@ extension ViewExtension on ViewPB { ViewLayoutPB.Calendar => PluginType.calendar, ViewLayoutPB.Document => PluginType.document, ViewLayoutPB.Grid => PluginType.grid, + ViewLayoutPB.Chat => PluginType.chat, _ => throw UnimplementedError(), }; @@ -79,6 +82,8 @@ extension ViewExtension on ViewPB { pluginType: pluginType, initialSelection: initialSelection, ); + case ViewLayoutPB.Chat: + return AIChatPagePlugin(view: this); } throw UnimplementedError; } @@ -161,11 +166,13 @@ extension ViewLayoutExtension on ViewLayoutPB { ViewLayoutPB.Board => FlowySvgs.board_s, ViewLayoutPB.Calendar => FlowySvgs.date_s, ViewLayoutPB.Document => FlowySvgs.document_s, + ViewLayoutPB.Chat => FlowySvgs.chat_ai_page_s, _ => throw Exception('Unknown layout type'), }; bool get isDocumentView => switch (this) { ViewLayoutPB.Document => true, + ViewLayoutPB.Chat || ViewLayoutPB.Grid || ViewLayoutPB.Board || ViewLayoutPB.Calendar => @@ -178,7 +185,7 @@ extension ViewLayoutExtension on ViewLayoutPB { ViewLayoutPB.Board || ViewLayoutPB.Calendar => true, - ViewLayoutPB.Document => false, + ViewLayoutPB.Document || ViewLayoutPB.Chat => false, _ => throw Exception('Unknown layout type'), }; } diff --git a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart index 55d6a479e1..d95f90b362 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart @@ -16,12 +16,12 @@ class WorkspaceService { required ViewSectionPB viewSection, String? desc, int? index, + ViewLayoutPB? layout, }) { final payload = CreateViewPayloadPB.create() ..parentViewId = workspaceId ..name = name - // only allow document layout for the top-level views - ..layout = ViewLayoutPB.Document + ..layout = layout ?? ViewLayoutPB.Document ..section = viewSection; if (desc != null) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart index 2087d1e476..d8c257e897 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/command_palette/widgets/recent_views_list.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/recent/recent_views_bloc.dart'; @@ -8,6 +6,7 @@ import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_v import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class RecentViewsList extends StatelessWidget { @@ -24,7 +23,7 @@ class RecentViewsList extends StatelessWidget { builder: (context, state) { // We remove duplicates by converting the list to a set first final List recentViews = - state.views.reversed.toSet().toList(); + state.views.reversed.map((e) => e.item).toSet().toList(); return ListView.separated( shrinkWrap: true, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/af_focus_manager.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/af_focus_manager.dart new file mode 100644 index 0000000000..17d09b6821 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/af_focus_manager.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +/// Simple ChangeNotifier that can be listened to, notifies the +/// application on events that should trigger focus loss. +/// +/// Eg. lose focus in AppFlowyEditor +/// +abstract class ShouldLoseFocus with ChangeNotifier {} + +/// Private implementation to allow the [AFFocusManager] to +/// call [notifyListeners] without being directly invokable. +/// +class _ShouldLoseFocusImpl extends ShouldLoseFocus { + void notify() => notifyListeners(); +} + +class AFFocusManager extends InheritedWidget { + AFFocusManager({super.key, required super.child}); + + final ShouldLoseFocus loseFocusNotifier = _ShouldLoseFocusImpl(); + + void notifyLoseFocus() { + (loseFocusNotifier as _ShouldLoseFocusImpl).notify(); + } + + @override + bool updateShouldNotify(covariant InheritedWidget oldWidget) => false; + + static AFFocusManager of(BuildContext context) { + final AFFocusManager? result = + context.dependOnInheritedWidgetOfExactType(); + + assert(result != null, "AFFocusManager could not be found"); + return result!; + } + + static AFFocusManager? maybeOf(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart index e7b74ef4e9..5db9efb251 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart @@ -15,6 +15,7 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/application/view/view_service.dart'; +import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar.dart'; @@ -67,62 +68,68 @@ class DesktopHomeScreen extends StatelessWidget { return const WorkspaceFailedScreen(); } - return MultiBlocProvider( - key: ValueKey(userProfile.id), - providers: [ - BlocProvider.value(value: getIt()), - BlocProvider.value(value: getIt()), - BlocProvider( - create: (_) => - HomeBloc(workspaceSetting)..add(const HomeEvent.initial()), - ), - BlocProvider( - create: (_) => HomeSettingBloc( - workspaceSetting, - context.read(), - context.widthPx, - )..add(const HomeSettingEvent.initial()), - ), - BlocProvider( - create: (context) => - FavoriteBloc()..add(const FavoriteEvent.initial()), - ), - ], - child: Scaffold( - floatingActionButton: enableMemoryLeakDetect - ? const FloatingActionButton( - onPressed: dumpMemoryLeak, - child: Icon(Icons.memory), - ) - : null, - body: BlocListener( - listenWhen: (p, c) => p.latestView != c.latestView, - listener: (context, state) { - final view = state.latestView; - if (view != null) { - // Only open the last opened view if the [TabsState.currentPageManager] current opened plugin is blank and the last opened view is not null. - // All opened widgets that display on the home screen are in the form of plugins. There is a list of built-in plugins defined in the [PluginType] enum, including board, grid and trash. - final currentPageManager = - context.read().state.currentPageManager; + return AFFocusManager( + child: MultiBlocProvider( + key: ValueKey(userProfile.id), + providers: [ + BlocProvider.value(value: getIt()), + BlocProvider.value(value: getIt()), + BlocProvider( + create: (_) => + HomeBloc(workspaceSetting)..add(const HomeEvent.initial()), + ), + BlocProvider( + create: (_) => HomeSettingBloc( + workspaceSetting, + context.read(), + context.widthPx, + )..add(const HomeSettingEvent.initial()), + ), + BlocProvider( + create: (context) => + FavoriteBloc()..add(const FavoriteEvent.initial()), + ), + ], + child: Scaffold( + floatingActionButton: enableMemoryLeakDetect + ? const FloatingActionButton( + onPressed: dumpMemoryLeak, + child: Icon(Icons.memory), + ) + : null, + body: BlocListener( + listenWhen: (p, c) => p.latestView != c.latestView, + listener: (context, state) { + final view = state.latestView; + if (view != null) { + // Only open the last opened view if the [TabsState.currentPageManager] current opened plugin is blank and the last opened view is not null. + // All opened widgets that display on the home screen are in the form of plugins. There is a list of built-in plugins defined in the [PluginType] enum, including board, grid and trash. + final currentPageManager = + context.read().state.currentPageManager; - if (currentPageManager.plugin.pluginType == - PluginType.blank) { - getIt().add( - TabsEvent.openPlugin(plugin: view.plugin()), - ); + if (currentPageManager.plugin.pluginType == + PluginType.blank) { + getIt().add( + TabsEvent.openPlugin(plugin: view.plugin()), + ); + } } - } - }, - child: BlocBuilder( - buildWhen: (previous, current) => previous != current, - builder: (context, state) => BlocProvider( - create: (_) => UserWorkspaceBloc(userProfile: userProfile) - ..add(const UserWorkspaceEvent.initial()), - child: HomeHotKeys( - userProfile: userProfile, - child: FlowyContainer( - Theme.of(context).colorScheme.surface, - child: _buildBody(context, userProfile, workspaceSetting), + }, + child: BlocBuilder( + buildWhen: (previous, current) => previous != current, + builder: (context, state) => BlocProvider( + create: (_) => UserWorkspaceBloc(userProfile: userProfile) + ..add(const UserWorkspaceEvent.initial()), + child: HomeHotKeys( + userProfile: userProfile, + child: FlowyContainer( + Theme.of(context).colorScheme.surface, + child: _buildBody( + context, + userProfile, + workspaceSetting, + ), + ), ), ), ), @@ -146,6 +153,7 @@ class DesktopHomeScreen extends StatelessWidget { final homeStack = HomeStack( layout: layout, delegate: DesktopHomeScreenStackAdaptor(context), + userProfile: userProfile, ); final menu = _buildHomeSidebar( context, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_sizes.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_sizes.dart index bb7eb3600b..b35ae64ac5 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_sizes.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_sizes.dart @@ -18,4 +18,10 @@ class HomeInsets { class HomeSpaceViewSizes { static const double leftPadding = 16.0; static const double viewHeight = 30.0; + + // mobile, m represents mobile + static const double mViewHeight = 48.0; + static const double mViewButtonDimension = 34.0; + static const double mHorizontalPadding = 20.0; + static const double mVerticalPadding = 12.0; } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart index 8fdfb9bb44..405360f55b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart @@ -1,3 +1,4 @@ +import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:appflowy/core/frameless_window.dart'; import 'package:appflowy/plugins/blank/blank.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; @@ -29,10 +30,12 @@ class HomeStack extends StatelessWidget { super.key, required this.delegate, required this.layout, + required this.userProfile, }); final HomeStackDelegate delegate; final HomeLayout layout; + final UserProfilePB userProfile; @override Widget build(BuildContext context) { @@ -55,7 +58,11 @@ class HomeStack extends StatelessWidget { controller: pageController, children: state.pageManagers .map( - (pm) => PageStack(pageManager: pm, delegate: delegate), + (pm) => PageStack( + pageManager: pm, + delegate: delegate, + userProfile: userProfile, + ), ) .toList(), ), @@ -73,11 +80,13 @@ class PageStack extends StatefulWidget { super.key, required this.pageManager, required this.delegate, + required this.userProfile, }); final PageManager pageManager; final HomeStackDelegate delegate; + final UserProfilePB userProfile; @override State createState() => _PageStackState(); @@ -93,6 +102,7 @@ class _PageStackState extends State color: Theme.of(context).colorScheme.surface, child: FocusTraversalGroup( child: widget.pageManager.stackWidget( + userProfile: widget.userProfile, onDeleted: (view, index) { widget.delegate.didDeleteStackWidget(view, index); }, @@ -227,7 +237,10 @@ class PageManager { ); } - Widget stackWidget({required Function(ViewPB, int?) onDeleted}) { + Widget stackWidget({ + required UserProfilePB userProfile, + required Function(ViewPB, int?) onDeleted, + }) { return MultiProvider( providers: [ChangeNotifierProvider.value(value: _notifier)], child: Consumer( @@ -239,7 +252,10 @@ class PageManager { if (pluginType == notifier.plugin.pluginType) { final builder = notifier.plugin.widgetBuilder; final pluginWidget = builder.buildWidget( - context: PluginContext(onDeleted: onDeleted), + context: PluginContext( + onDeleted: onDeleted, + userProfile: userProfile, + ), shrinkWrap: false, ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart index e979f102e3..3ac4274fb7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:flutter/material.dart'; + import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/tasks/app_window_size_manager.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; @@ -9,7 +11,6 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; -import 'package:flutter/material.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:provider/provider.dart'; import 'package:scaled_app/scaled_app.dart'; @@ -54,13 +55,24 @@ class _HomeHotKeysState extends State { final windowSizeManager = WindowSizeManager(); late final items = [ - // Collapse sidebar menu + // Collapse sidebar menu (using slash) HotKeyItem( hotKey: HotKey( - Platform.isMacOS ? KeyCode.period : KeyCode.backslash, + KeyCode.backslash, modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control], - // Set hotkey scope (default is HotKeyScope.system) - scope: HotKeyScope.inapp, // Set as inapp-wide hotkey. + scope: HotKeyScope.inapp, + ), + keyDownHandler: (_) => context + .read() + .add(const HomeSettingEvent.collapseMenu()), + ), + + // Collapse sidebar menu (using .) + HotKeyItem( + hotKey: HotKey( + KeyCode.period, + modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control], + scope: HotKeyScope.inapp, ), keyDownHandler: (_) => context .read() @@ -141,6 +153,16 @@ class _HomeHotKeysState extends State { keyDownHandler: (_) => _scaleWithStep(-0.1), ), + // Reset app scaling + HotKeyItem( + hotKey: HotKey( + KeyCode.digit0, + modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control], + scope: HotKeyScope.inapp, + ), + keyDownHandler: (_) => _scaleToSize(1), + ), + // Open settings dialog openSettingsHotKey(context, widget.userProfile), ]; @@ -182,7 +204,11 @@ class _HomeHotKeysState extends State { Log.info('scale the app from $currentScaleFactor to $textScale'); - ScaledWidgetsFlutterBinding.instance.scaleFactor = (_) => textScale; - await windowSizeManager.setScaleFactor(textScale); + await _scaleToSize(textScale); + } + + Future _scaleToSize(double size) async { + ScaledWidgetsFlutterBinding.instance.scaleFactor = (_) => size; + await windowSizeManager.setScaleFactor(size); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart index 535c89be4e..8c9d800470 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart @@ -2,7 +2,9 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:flutter/material.dart'; class MenuSharedState { - MenuSharedState({ViewPB? view}) { + MenuSharedState({ + ViewPB? view, + }) { _latestOpenView.value = view; } @@ -17,13 +19,8 @@ class MenuSharedState { } } - VoidCallback addLatestViewListener(void Function(ViewPB?) callback) { - void listener() { - callback(_latestOpenView.value); - } - + void addLatestViewListener(VoidCallback listener) { _latestOpenView.addListener(listener); - return listener; } void removeLatestViewListener(VoidCallback listener) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart index 16415e5e93..1e6279f304 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart @@ -82,7 +82,12 @@ class _FavoriteFolderState extends State { return []; } - return context.read().state.pinnedViews.map( + return context + .read() + .state + .pinnedViews + .map((e) => e.item) + .map( (view) => ViewItem( key: ValueKey( '${FolderSpaceType.favorite.name} ${view.id}', @@ -104,6 +109,7 @@ class _FavoriteFolderState extends State { const HSpace(4.0), ], shouldRenderChildren: false, + shouldLoadChildViews: false, onTertiarySelected: (_, view) => context.read().openTab(view), onSelected: (_, view) { @@ -147,6 +153,7 @@ class FavoriteMoreButton extends StatelessWidget { @override Widget build(BuildContext context) { final favoriteBloc = context.watch(); + final tabsBloc = context.read(); final unpinnedViews = favoriteBloc.state.unpinnedViews; // only show the more button if there are unpinned views if (unpinnedViews.isEmpty) { @@ -164,8 +171,11 @@ class FavoriteMoreButton extends StatelessWidget { borderRadius: 10.0, ), popupBuilder: (_) { - return BlocProvider.value( - value: favoriteBloc, + return MultiBlocProvider( + providers: [ + BlocProvider.value(value: favoriteBloc), + BlocProvider.value(value: tabsBloc), + ], child: const FavoriteMenu(minWidth: minWidth), ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu.dart index 4ec75da1d2..91f178af60 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu.dart @@ -1,11 +1,13 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; +import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_menu_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; +import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/cupertino.dart'; @@ -125,7 +127,10 @@ class FavoriteMenu extends StatelessWidget { view: e, spaceType: FolderSpaceType.favorite, level: 0, - onSelected: (view, _) {}, + onSelected: (_, view) { + context.read().openPlugin(view); + PopoverContainer.maybeOf(context)?.close(); + }, isFeedback: false, isDraggable: false, shouldRenderChildren: false, @@ -143,7 +148,7 @@ class FavoriteMenu extends StatelessWidget { } } -class _FavoriteSearchField extends StatelessWidget { +class _FavoriteSearchField extends StatefulWidget { const _FavoriteSearchField({ required this.width, required this.onSearch, @@ -152,11 +157,30 @@ class _FavoriteSearchField extends StatelessWidget { final double width; final void Function(BuildContext context, String text) onSearch; + @override + State<_FavoriteSearchField> createState() => _FavoriteSearchFieldState(); +} + +class _FavoriteSearchFieldState extends State<_FavoriteSearchField> { + final focusNode = FocusNode(); + + @override + void initState() { + super.initState(); + focusNode.requestFocus(); + } + + @override + void dispose() { + focusNode.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Container( height: 30, - width: width, + width: widget.width, clipBehavior: Clip.antiAlias, decoration: ShapeDecoration( shape: RoundedRectangleBorder( @@ -169,8 +193,9 @@ class _FavoriteSearchField extends StatelessWidget { ), ), child: CupertinoSearchTextField( - onChanged: (text) => onSearch(context, text), + onChanged: (text) => widget.onSearch(context, text), padding: EdgeInsets.zero, + focusNode: focusNode, placeholder: LocaleKeys.search_label.tr(), prefixIcon: const FlowySvg(FlowySvgs.m_search_m), prefixInsets: const EdgeInsets.only(left: 12.0, right: 8.0), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu_bloc.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu_bloc.dart index 4ad963f50d..eb5d271836 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_menu_bloc.dart @@ -1,5 +1,4 @@ import 'package:appflowy/workspace/application/favorite/favorite_service.dart'; -import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -43,9 +42,9 @@ class FavoriteMenuBloc extends Bloc { if (query.isNotEmpty) { queriedViews = _filter(views, query); - todayViews = _filter(state.todayViews, query); - thisWeekViews = _filter(state.thisWeekViews, query); - otherViews = _filter(state.otherViews, query); + todayViews = _filter(todayViews, query); + thisWeekViews = _filter(thisWeekViews, query); + otherViews = _filter(otherViews, query); } emit( @@ -66,28 +65,20 @@ class FavoriteMenuBloc extends Bloc { final FavoriteService _service = FavoriteService(); RepeatedFavoriteViewPB? _source; - List _filter(List views, String query) { - return views - .where( - (view) => view.name.toLowerCase().contains(query.toLowerCase()), - ) - .toList(); - } + List _filter(List views, String query) => views + .where((view) => view.name.toLowerCase().contains(query.toLowerCase())) + .toList(); // all, today, last week, other (List, List, List, List) _getViews( RepeatedFavoriteViewPB source, ) { - final List views = - source.items.map((v) => v.item).where((e) => !e.isPinned).toList(); + final List views = source.items.map((v) => v.item).toList(); final List todayViews = []; final List thisWeekViews = []; final List otherViews = []; for (final favoriteView in source.items) { final view = favoriteView.item; - if (view.isPinned) { - continue; - } final date = DateTime.fromMillisecondsSinceEpoch( favoriteView.timestamp.toInt() * 1000, ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart index 40c2167626..2fc1b311ad 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart @@ -1,4 +1,7 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; @@ -11,7 +14,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class FavoriteMoreActions extends StatelessWidget { @@ -53,7 +55,7 @@ class FavoriteMoreActions extends StatelessWidget { break; case ViewMoreActionType.openInNewTab: - context.read().openTab(view); + getIt().openTab(view); break; case ViewMoreActionType.delete: case ViewMoreActionType.duplicate: diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart index 53a53e5ae9..2a849b7e8d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart @@ -3,7 +3,6 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; @@ -31,8 +30,6 @@ class FavoritePinAction extends StatelessWidget { width: 24, icon: icon, onPressed: () { - PopoverContainer.maybeOf(context)?.closeAll(); - view.isPinned ? context.read().add(FavoriteEvent.unpin(view)) : context.read().add(FavoriteEvent.pin(view)); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart index c10d14105a..6c16609a33 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart @@ -13,11 +13,12 @@ class SidebarFooter extends StatelessWidget { return const Row( children: [ Expanded(child: SidebarTrashButton()), - SizedBox( - height: 16, - child: VerticalDivider(width: 1, color: Color(0x141F2329)), - ), - Expanded(child: SidebarWidgetButton()), + // Enable it when the widget button is ready + // SizedBox( + // height: 16, + // child: VerticalDivider(width: 1, color: Color(0x141F2329)), + // ), + // Expanded(child: SidebarWidgetButton()), ], ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart index 051386b7b2..c7dc54126e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart @@ -3,6 +3,7 @@ import 'dart:io' show Platform; import 'package:appflowy/core/frameless_window.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; @@ -51,22 +52,23 @@ class SidebarTopMenu extends StatelessWidget { ? FlowySvgs.flowy_logo_dark_mode_xl : FlowySvgs.flowy_logo_text_xl; - return FlowySvg( - svgData, - size: const Size(92, 17), - blendMode: null, + return Padding( + padding: const EdgeInsets.only(top: 12.0, left: 4), + child: FlowySvg( + svgData, + size: const Size(92, 17), + blendMode: null, + ), ); } Widget _buildCollapseMenuButton(BuildContext context) { + final color = Theme.of(context).isLightMode ? Colors.white : Colors.black; final textSpan = TextSpan( children: [ TextSpan( text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n', - style: Theme.of(context) - .textTheme - .bodyMedium! - .copyWith(color: Colors.white), + style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: color), ), TextSpan( text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\', diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart index 8d7b0efd50..20465d0faa 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart @@ -38,7 +38,6 @@ class SidebarUser extends StatelessWidget { const HSpace(10), Expanded(child: _buildUserName(context, state)), UserSettingButton(userProfile: state.userProfile), - const HSpace(4), const NotificationButton(), ], ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart index 93bcccdf06..0e49c2acd6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart @@ -38,7 +38,9 @@ class SidebarFolder extends StatelessWidget { } return Padding( padding: const EdgeInsets.only(top: 16.0, bottom: 10), - child: FavoriteFolder(views: state.views), + child: FavoriteFolder( + views: state.views.map((e) => e.item).toList(), + ), ); }, ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart index 209e40de3a..e8a50c8088 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart @@ -1,8 +1,11 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart'; @@ -13,7 +16,6 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; @@ -63,40 +65,42 @@ class UserSettingButton extends StatelessWidget { } } -void showSettingsDialog(BuildContext context, UserProfilePB userProfile) => - showDialog( - context: context, - builder: (dialogContext) => MultiBlocProvider( - key: _settingsDialogKey, - providers: [ - BlocProvider.value( - value: BlocProvider.of(dialogContext), - ), - BlocProvider.value(value: context.read()), - ], - child: SettingsDialog( - userProfile, - workspaceId: context - .read() - .state - .currentWorkspace! - .workspaceId, - didLogout: () async { - // Pop the dialog using the dialog context - Navigator.of(dialogContext).pop(); - await runAppFlowy(); - }, - dismissDialog: () { - if (Navigator.of(dialogContext).canPop()) { - return Navigator.of(dialogContext).pop(); - } - Log.warn("Can't pop dialog context"); - }, - restartApp: () async { - // Pop the dialog using the dialog context - Navigator.of(dialogContext).pop(); - await runAppFlowy(); - }, +void showSettingsDialog(BuildContext context, UserProfilePB userProfile) { + AFFocusManager.of(context).notifyLoseFocus(); + showDialog( + context: context, + builder: (dialogContext) => MultiBlocProvider( + key: _settingsDialogKey, + providers: [ + BlocProvider.value( + value: BlocProvider.of(dialogContext), ), + BlocProvider.value(value: context.read()), + ], + child: SettingsDialog( + userProfile, + workspaceId: context + .read() + .state + .currentWorkspace! + .workspaceId, + didLogout: () async { + // Pop the dialog using the dialog context + Navigator.of(dialogContext).pop(); + await runAppFlowy(); + }, + dismissDialog: () { + if (Navigator.of(dialogContext).canPop()) { + return Navigator.of(dialogContext).pop(); + } + Log.warn("Can't pop dialog context"); + }, + restartApp: () async { + // Pop the dialog using the dialog context + Navigator.of(dialogContext).pop(); + await runAppFlowy(); + }, ), - ); + ), + ); +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 323ec1428c..31cdf73685 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -224,7 +224,7 @@ class _SidebarState extends State<_Sidebar> { // user or workspace, setting Container( height: HomeSizes.workspaceSectionHeight, - padding: menuHorizontalInset, + padding: menuHorizontalInset - const EdgeInsets.only(right: 6), child: // if the workspaces are empty, show the user profile instead userState.isCollabWorkspaceOn && userState.workspaces.isNotEmpty diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index ea0826e82a..d179c4ce0f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -44,7 +44,7 @@ class _WorkspaceIconState extends State { : Container( alignment: Alignment.center, width: widget.iconSize, - height: max(widget.iconSize, 26), + height: min(widget.iconSize, 26), decoration: BoxDecoration( color: ColorGenerator(widget.workspace.name).toColor(), borderRadius: BorderRadius.circular(4), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index 0572ae107c..8a1b172aff 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; @@ -128,7 +130,7 @@ class _WorkspaceMenuItemState extends State { // cause the popover dismiss intermediately when click the right icon. // so using the stack to put the right icon on the flowy button. return SizedBox( - height: 40, + height: 44, child: MouseRegion( onEnter: (_) => isHovered.value = true, onExit: (_) => isHovered.value = false, @@ -242,6 +244,7 @@ class _WorkspaceInfo extends StatelessWidget { rightIcon: const HSpace(32.0), text: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ // workspace name FlowyText.medium( @@ -250,7 +253,7 @@ class _WorkspaceInfo extends StatelessWidget { overflow: TextOverflow.ellipsis, withTooltip: true, ), - const VSpace(2.0), + if (Platform.isMacOS) const VSpace(2.0), // workspace members count FlowyText.regular( state.isLoading diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart index bb4d18ab46..d1a09afc28 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart @@ -49,9 +49,7 @@ class _SidebarWorkspaceState extends State { ), ), UserSettingButton(userProfile: widget.userProfile), - const HSpace(8), const NotificationButton(), - const HSpace(4), ], ); }, @@ -201,12 +199,12 @@ class _SidebarSwitchWorkspaceButtonState }, child: FlowyButton( margin: EdgeInsets.zero, - text: Row( - children: [ - const HSpace(6.0), - SizedBox( - width: 16.0, - child: WorkspaceIcon( + text: SizedBox( + height: 30, + child: Row( + children: [ + const HSpace(6.0), + WorkspaceIcon( workspace: widget.currentWorkspace, iconSize: 16, fontSize: 10, @@ -218,25 +216,25 @@ class _SidebarSwitchWorkspaceButtonState ), ), ), - ), - const HSpace(10), - Flexible( - child: FlowyText.medium( - widget.currentWorkspace.name, - overflow: TextOverflow.ellipsis, - withTooltip: true, + const HSpace(10), + Flexible( + child: FlowyText.medium( + widget.currentWorkspace.name, + overflow: TextOverflow.ellipsis, + withTooltip: true, + ), ), - ), - const HSpace(4), - ValueListenableBuilder( - valueListenable: _isWorkSpaceMenuExpanded, - builder: (context, value, _) => FlowySvg( - value - ? FlowySvgs.workspace_drop_down_menu_hide_s - : FlowySvgs.workspace_drop_down_menu_show_s, + const HSpace(4), + ValueListenableBuilder( + valueListenable: _isWorkSpaceMenuExpanded, + builder: (context, value, _) => FlowySvg( + value + ? FlowySvgs.workspace_drop_down_menu_hide_s + : FlowySvgs.workspace_drop_down_menu_show_s, + ), ), - ), - ], + ], + ), ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index 0ebb919318..1e58b7703f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -57,6 +57,7 @@ class ViewItem extends StatelessWidget { this.shouldRenderChildren = true, this.leftIconBuilder, this.rightIconsBuilder, + this.shouldLoadChildViews = true, }); final ViewPB view; @@ -107,10 +108,14 @@ class ViewItem extends StatelessWidget { // custom the right icon widget, if it's null, the default ... and + button will be used final ViewItemRightIconsBuilder? rightIconsBuilder; + final bool shouldLoadChildViews; + @override Widget build(BuildContext context) { return BlocProvider( - create: (_) => ViewBloc(view: view)..add(const ViewEvent.initial()), + create: (_) => + ViewBloc(view: view, shouldLoadChildViews: shouldLoadChildViews) + ..add(const ViewEvent.initial()), child: BlocConsumer( listenWhen: (p, c) => c.lastCreatedView != null && @@ -422,6 +427,10 @@ class _SingleInnerViewItemState extends State { // icon _buildViewIconButton(), const HSpace(6), + // const SizedBox( + // width: 6.0, + // height: 1, + // ), // title Expanded( child: FlowyText.regular( @@ -672,6 +681,8 @@ class _SingleInnerViewItemState extends State { return LocaleKeys.newBoardText.tr(); case ViewLayoutPB.Calendar: return LocaleKeys.newCalendarText.tr(); + case ViewLayoutPB.Chat: + return LocaleKeys.chat_newChat.tr(); } return LocaleKeys.newPageText.tr(); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart index 68d179da50..57730ada05 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart @@ -63,31 +63,48 @@ class ViewMoreActionButton extends StatelessWidget { List _buildActionTypes() { final List actionTypes = []; - switch (spaceType) { - case FolderSpaceType.favorite: + + if (spaceType == FolderSpaceType.favorite) { + actionTypes.addAll([ + ViewMoreActionType.unFavorite, + ViewMoreActionType.divider, + ViewMoreActionType.rename, + ViewMoreActionType.openInNewTab, + ]); + } else { + actionTypes.add( + view.isFavorite + ? ViewMoreActionType.unFavorite + : ViewMoreActionType.favorite, + ); + + actionTypes.addAll([ + ViewMoreActionType.divider, + ViewMoreActionType.rename, + ]); + + // Chat doesn't change icon and duplicate + if (view.layout != ViewLayoutPB.Chat) { actionTypes.addAll([ - ViewMoreActionType.unFavorite, - ViewMoreActionType.divider, - ViewMoreActionType.rename, - ViewMoreActionType.openInNewTab, - ]); - break; - default: - actionTypes.addAll([ - view.isFavorite - ? ViewMoreActionType.unFavorite - : ViewMoreActionType.favorite, - ViewMoreActionType.divider, - ViewMoreActionType.rename, ViewMoreActionType.changeIcon, ViewMoreActionType.duplicate, - ViewMoreActionType.delete, - ViewMoreActionType.divider, - ViewMoreActionType.collapseAllPages, - ViewMoreActionType.divider, - ViewMoreActionType.openInNewTab, ]); + } + + actionTypes.addAll([ + ViewMoreActionType.delete, + ViewMoreActionType.divider, + ]); + + // Chat doesn't change collapse + if (view.layout != ViewLayoutPB.Chat) { + actionTypes.add(ViewMoreActionType.collapseAllPages); + actionTypes.add(ViewMoreActionType.divider); + } + + actionTypes.add(ViewMoreActionType.openInNewTab); } + return actionTypes; } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart index c046c8379f..4201ec5396 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart @@ -1,17 +1,17 @@ import 'dart:io'; -import 'package:appflowy_editor/appflowy_editor.dart'; -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_stack.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; @@ -65,23 +65,39 @@ class FlowyNavigation extends StatelessWidget { buildWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed, builder: (context, state) { if (!PlatformExtension.isWindows && state.isMenuCollapsed) { - return RotationTransition( - turns: const AlwaysStoppedAnimation(180 / 360), - child: FlowyTooltip( - richMessage: sidebarTooltipTextSpan( - context, - LocaleKeys.sideBar_openSidebar.tr(), + final color = + Theme.of(context).isLightMode ? Colors.white : Colors.black; + final textSpan = TextSpan( + children: [ + TextSpan( + text: '${LocaleKeys.sideBar_openSidebar.tr()}\n', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: color), ), - child: FlowyIconButton( - width: 24, - hoverColor: Colors.transparent, - onPressed: () => context - .read() - .add(const HomeSettingEvent.collapseMenu()), - iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), - icon: FlowySvg( - FlowySvgs.hide_menu_m, - color: Theme.of(context).iconTheme.color, + TextSpan( + text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Theme.of(context).hintColor), + ), + ], + ); + return Padding( + padding: const EdgeInsets.only(right: 8.0), + child: RotationTransition( + turns: const AlwaysStoppedAnimation(180 / 360), + child: FlowyTooltip( + richMessage: textSpan, + child: FlowyIconButton( + width: 24, + onPressed: () => context + .read() + .add(const HomeSettingEvent.collapseMenu()), + iconPadding: const EdgeInsets.all(2), + icon: const FlowySvg(FlowySvgs.hide_menu_s), ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart index 049ee6481b..08f421951b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart @@ -3,6 +3,8 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; +import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/notifications/notification_dialog.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -24,23 +26,35 @@ class NotificationButton extends StatelessWidget { return BlocProvider.value( value: getIt(), - child: BlocBuilder( - builder: (context, state) => FlowyTooltip( - message: LocaleKeys.notificationHub_title.tr(), - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: AppFlowyPopover( - mutex: mutex, - direction: PopoverDirection.bottomWithLeftAligned, - constraints: const BoxConstraints(maxHeight: 500, maxWidth: 425), - windowPadding: EdgeInsets.zero, - margin: EdgeInsets.zero, - popupBuilder: (_) => - NotificationDialog(views: views, mutex: mutex), - child: _buildNotificationIcon(context, state.hasUnreads), - ), - ), - ), + child: BlocBuilder( + builder: (notificationSettingsContext, notificationSettingsState) { + return BlocBuilder( + builder: (context, state) => notificationSettingsState + .isShowNotificationsIconEnabled + ? FlowyTooltip( + message: LocaleKeys.notificationHub_title.tr(), + child: AppFlowyPopover( + mutex: mutex, + direction: PopoverDirection.bottomWithLeftAligned, + constraints: + const BoxConstraints(maxHeight: 500, maxWidth: 425), + windowPadding: EdgeInsets.zero, + margin: EdgeInsets.zero, + popupBuilder: (_) => + NotificationDialog(views: views, mutex: mutex), + child: SizedBox.square( + dimension: HomeSizes.workspaceSectionHeight, + child: FlowyButton( + useIntrinsicWidth: true, + text: + _buildNotificationIcon(context, state.hasUnreads), + ), + ), + ), + ) + : const SizedBox.shrink(), + ); + }, ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart index 1b3250ee55..f7dcb63507 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_notifications_view.dart @@ -33,6 +33,23 @@ class SettingsNotificationsView extends StatelessWidget { ), ], ), + SettingListTile( + label: LocaleKeys + .settings_notifications_showNotificationsIcon_label + .tr(), + hint: LocaleKeys.settings_notifications_showNotificationsIcon_hint + .tr(), + trailing: [ + Switch( + value: state.isShowNotificationsIconEnabled, + splashRadius: 0, + activeColor: Theme.of(context).colorScheme.primary, + onChanged: (_) => context + .read() + .toogleShowNotificationIconEnabled(), + ), + ], + ), ], ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart index e25c81b182..970ee82631 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart @@ -20,7 +20,7 @@ class ViewFavoriteButton extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - final isFavorite = state.views.any((v) => v.id == view.id); + final isFavorite = state.views.any((v) => v.item.id == view.id); return Listener( onPointerDown: (_) => context.read().add(FavoriteEvent.toggle(view)), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart index 5ad85efe31..357e565559 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart @@ -6,6 +6,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; +import 'package:string_validator/string_validator.dart'; class UserAvatar extends StatelessWidget { const UserAvatar({ @@ -28,40 +29,79 @@ class UserAvatar extends StatelessWidget { @override Widget build(BuildContext context) { if (iconUrl.isEmpty) { - final String nameOrDefault = _userName(name); - final Color color = ColorGenerator(name).toColor(); - const initialsCount = 2; + return _buildEmptyAvatar(context); + } else if (isURL(iconUrl)) { + return _buildUrlAvatar(context); + } else { + return _buildEmojiAvatar(context); + } + } - // Taking the first letters of the name components and limiting to 2 elements - final nameInitials = nameOrDefault - .split(' ') - .where((element) => element.isNotEmpty) - .take(initialsCount) - .map((element) => element[0].toUpperCase()) - .join(); + Widget _buildEmptyAvatar(BuildContext context) { + final String nameOrDefault = _userName(name); + final Color color = ColorGenerator(name).toColor(); + const initialsCount = 2; - return Container( - width: size, - height: size, - alignment: Alignment.center, + // Taking the first letters of the name components and limiting to 2 elements + final nameInitials = nameOrDefault + .split(' ') + .where((element) => element.isNotEmpty) + .take(initialsCount) + .map((element) => element[0].toUpperCase()) + .join(); + + return Container( + width: size, + height: size, + alignment: Alignment.center, + decoration: BoxDecoration( + color: color, + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: _darken(color), + width: 4, + ) + : null, + ), + child: FlowyText.regular( + nameInitials, + color: Colors.black, + fontSize: fontSize, + ), + ); + } + + Widget _buildUrlAvatar(BuildContext context) { + return SizedBox.square( + dimension: size, + child: DecoratedBox( decoration: BoxDecoration( - color: color, shape: BoxShape.circle, border: isHovering ? Border.all( - color: _darken(color), + color: Theme.of(context).colorScheme.primary, width: 4, ) : null, ), - child: FlowyText.regular( - nameInitials, - color: Colors.black, - fontSize: fontSize, + child: ClipRRect( + borderRadius: Corners.s5Border, + child: CircleAvatar( + backgroundColor: Colors.transparent, + child: Image.network( + iconUrl, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) => + _buildEmptyAvatar(context), + ), + ), ), - ); - } + ), + ); + } + Widget _buildEmojiAvatar(BuildContext context) { return SizedBox.square( dimension: size, child: DecoratedBox( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart index 18b206bd9e..b3eddfb52b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart @@ -167,6 +167,7 @@ class _ViewTitleState extends State<_ViewTitle> { onPointerDown: (_) => context.read().openPlugin(widget.view), child: FlowyButton( useIntrinsicWidth: true, + margin: const EdgeInsets.symmetric(horizontal: 6.0), onTap: () {}, text: _buildIconAndName(state), ), diff --git a/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h b/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h index 9d9128671c..78992141ca 100644 --- a/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h +++ b/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h @@ -3,7 +3,7 @@ #include #include -int64_t init_sdk(char *data); +int64_t init_sdk(int64_t port, char *data); void async_event(int64_t port, const uint8_t *input, uintptr_t len); @@ -11,6 +11,8 @@ const uint8_t *sync_event(const uint8_t *input, uintptr_t len); int32_t set_stream_port(int64_t port); +int32_t set_log_stream_port(int64_t port); + void link_me_please(void); void rust_log(int64_t level, const char *data); diff --git a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart index 21ace45b28..cd95941a15 100644 --- a/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart +++ b/frontend/appflowy_flutter/packages/appflowy_backend/lib/dispatch/dispatch.dart @@ -16,6 +16,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-search/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-chat/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:ffi/ffi.dart'; import 'package:isolates/isolates.dart'; @@ -36,6 +37,7 @@ part 'dart_event/flowy-document/dart_event.dart'; part 'dart_event/flowy-config/dart_event.dart'; part 'dart_event/flowy-date/dart_event.dart'; part 'dart_event/flowy-search/dart_event.dart'; +part 'dart_event/flowy-chat/dart_event.dart'; enum FFIException { RequestIsEmpty, diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart index b1c80fab64..8f7120fa84 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart @@ -19,6 +19,7 @@ const _darkShader3 = Color(0xFF363D49); const _darkShader5 = Color(0xFFBBC3CD); const _darkShader6 = Color(0xFFF2F2F2); const _darkMain1 = Color(0x19FFFFFF); +const _darkMain2 = Color(0xFF00BCF0); const _darkInput = Color(0xFF282E3A); class DefaultColorScheme extends FlowyColorScheme { @@ -103,7 +104,7 @@ class DefaultColorScheme extends FlowyColorScheme { tint7: const Color(0x5900BD2A), tint8: const Color(0x80008890), tint9: const Color(0x4d0029FF), - main1: _darkMain1, + main1: _darkMain2, main2: const Color(0xFF00B7EA), shadow: const Color(0xFF0F131C), sidebarBg: const Color(0xFF232B38), @@ -114,7 +115,7 @@ class DefaultColorScheme extends FlowyColorScheme { secondaryText: _darkShader5, input: _darkInput, hint: const Color(0xFF59647a), - primary: _darkMain1, + primary: _darkMain2, onPrimary: _darkShader1, hoverBG1: _darkMain1, hoverBG2: _darkMain1, diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart index acd628a222..e99ee90f56 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -106,7 +106,7 @@ class FlowyButton extends StatelessWidget { } if (rightIcon != null) { - children.add(const HSpace(6)); + children.add(HSpace(iconPadding)); // No need to define the size of rightIcon. Just use its intrinsic width children.add(rightIcon!); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart index 88ebc735b7..10065b3dc7 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart @@ -1,6 +1,9 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +const String _emojiFontFamily = 'noto color emoji'; class FlowyText extends StatelessWidget { final String text; @@ -17,6 +20,7 @@ class FlowyText extends StatelessWidget { final double? lineHeight; final bool withTooltip; final StrutStyle? strutStyle; + final bool isEmoji; const FlowyText( this.text, { @@ -33,6 +37,7 @@ class FlowyText extends StatelessWidget { this.fallbackFontFamily, this.lineHeight, this.withTooltip = false, + this.isEmoji = false, this.strutStyle, }); @@ -49,6 +54,7 @@ class FlowyText extends StatelessWidget { this.fallbackFontFamily, this.lineHeight, this.withTooltip = false, + this.isEmoji = false, this.strutStyle, }) : fontWeight = FontWeight.w400, fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12; @@ -67,6 +73,7 @@ class FlowyText extends StatelessWidget { this.fallbackFontFamily, this.lineHeight, this.withTooltip = false, + this.isEmoji = false, this.strutStyle, }) : fontWeight = FontWeight.w400; @@ -84,6 +91,7 @@ class FlowyText extends StatelessWidget { this.fallbackFontFamily, this.lineHeight, this.withTooltip = false, + this.isEmoji = false, this.strutStyle, }) : fontWeight = FontWeight.w500; @@ -101,6 +109,7 @@ class FlowyText extends StatelessWidget { this.fallbackFontFamily, this.lineHeight, this.withTooltip = false, + this.isEmoji = false, this.strutStyle, }) : fontWeight = FontWeight.w600; @@ -118,14 +127,30 @@ class FlowyText extends StatelessWidget { this.lineHeight, this.withTooltip = false, this.strutStyle = const StrutStyle(forceStrutHeight: true), + this.isEmoji = true, + this.fontFamily, }) : fontWeight = FontWeight.w400, - fontFamily = 'noto color emoji', fallbackFontFamily = null; @override Widget build(BuildContext context) { Widget child; + var fontFamily = this.fontFamily; + var fallbackFontFamily = this.fallbackFontFamily; + if (isEmoji && (Platform.isLinux || Platform.isAndroid)) { + fontFamily = _loadEmojiFontFamilyIfNeeded(); + if (fontFamily != null && fallbackFontFamily == null) { + fallbackFontFamily = [fontFamily]; + } + } + + var fontSize = + this.fontSize ?? Theme.of(context).textTheme.bodyMedium!.fontSize!; + if (Platform.isLinux && fontFamily == _emojiFontFamily) { + fontSize = fontSize * 0.8; + } + final textStyle = Theme.of(context).textTheme.bodyMedium!.copyWith( fontSize: fontSize, fontWeight: fontWeight, @@ -163,4 +188,12 @@ class FlowyText extends StatelessWidget { return child; } + + String? _loadEmojiFontFamilyIfNeeded() { + if (Platform.isLinux || Platform.isAndroid) { + return GoogleFonts.notoColorEmoji().fontFamily; + } + + return null; + } } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart index 47a684cf01..57874fad64 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart @@ -22,8 +22,13 @@ class FlowyTooltip extends StatelessWidget { @override Widget build(BuildContext context) { + final isLightMode = Theme.of(context).brightness == Brightness.light; return Tooltip( margin: margin, + decoration: BoxDecoration( + color: isLightMode ? const Color(0xE5171717) : const Color(0xE5E5E5E5), + borderRadius: BorderRadius.circular(8.0), + ), waitDuration: _tooltipWaitDuration, message: message, richMessage: richMessage, diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/pubspec.yaml b/frontend/appflowy_flutter/packages/flowy_infra_ui/pubspec.yaml index 3d73a51d7b..5eb1ba066e 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/pubspec.yaml +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: loading_indicator: ^3.1.0 async: url_launcher: ^6.1.11 + google_fonts: ^6.1.0 # Federated Platform Interface flowy_infra_ui_platform_interface: diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index dab9ec0475..2ee1b5eb06 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -62,10 +62,10 @@ packages: dependency: "direct main" description: name: appflowy_editor_plugins - sha256: "9d91f65e564f85ffc98a407524371beeb1fd40aabd621b00ba8a722058636094" + sha256: "46c899acc22245798e5beed255852455d9d85c3fae8b275ef4db257810b1c59d" url: "https://pub.dev" source: hosted - version: "0.0.2" + version: "0.0.6" appflowy_popover: dependency: "direct main" description: @@ -104,6 +104,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + auto_size_text_field: + dependency: "direct main" + description: + name: auto_size_text_field + sha256: c4ba8714ba4216ca122acac1573581dac499f3162c9218a28b573dca73721b3f + url: "https://pub.dev" + source: hosted + version: "2.2.3" avatar_stack: dependency: "direct main" description: @@ -385,6 +393,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.1" + diffutil_dart: + dependency: transitive + description: + name: diffutil_dart + sha256: "5e74883aedf87f3b703cb85e815bdc1ed9208b33501556e4a8a5572af9845c81" + url: "https://pub.dev" + source: hosted + version: "4.0.1" dotted_border: dependency: "direct main" description: @@ -587,13 +603,21 @@ packages: source: git version: "3.3.1" flutter_chat_types: - dependency: transitive + dependency: "direct main" description: name: flutter_chat_types sha256: e285b588f6d19d907feb1f6d912deaf22e223656769c34093b64e1c59b094fb9 url: "https://pub.dev" source: hosted version: "3.6.2" + flutter_chat_ui: + dependency: "direct main" + description: + name: flutter_chat_ui + sha256: "40fb37acc328dd179eadc3d67bf8bd2d950dc0da34464aa8d48e8707e0234c09" + url: "https://pub.dev" + source: hosted + version: "1.6.13" flutter_colorpicker: dependency: "direct main" description: @@ -653,6 +677,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.2" + flutter_parsed_text: + dependency: transitive + description: + name: flutter_parsed_text + sha256: "529cf5793b7acdf16ee0f97b158d0d4ba0bf06e7121ef180abe1a5b59e32c1e2" + url: "https://pub.dev" + source: hosted + version: "2.2.1" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -868,6 +900,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" + url: "https://pub.dev" + source: hosted + version: "4.1.7" image_gallery_saver: dependency: "direct main" description: @@ -1145,6 +1185,78 @@ packages: url: "https://pub.dev" source: hosted version: "0.8.0" + media_kit: + dependency: transitive + description: + name: media_kit + sha256: "3289062540e3b8b9746e5c50d95bd78a9289826b7227e253dff806d002b9e67a" + url: "https://pub.dev" + source: hosted + version: "1.1.10+1" + media_kit_libs_android_video: + dependency: transitive + description: + name: media_kit_libs_android_video + sha256: "9dd8012572e4aff47516e55f2597998f0a378e3d588d0fad0ca1f11a53ae090c" + url: "https://pub.dev" + source: hosted + version: "1.3.6" + media_kit_libs_ios_video: + dependency: transitive + description: + name: media_kit_libs_ios_video + sha256: b5382994eb37a4564c368386c154ad70ba0cc78dacdd3fb0cd9f30db6d837991 + url: "https://pub.dev" + source: hosted + version: "1.1.4" + media_kit_libs_linux: + dependency: transitive + description: + name: media_kit_libs_linux + sha256: e186891c31daa6bedab4d74dcdb4e8adfccc7d786bfed6ad81fe24a3b3010310 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + media_kit_libs_macos_video: + dependency: transitive + description: + name: media_kit_libs_macos_video + sha256: f26aa1452b665df288e360393758f84b911f70ffb3878032e1aabba23aa1032d + url: "https://pub.dev" + source: hosted + version: "1.1.4" + media_kit_libs_video: + dependency: transitive + description: + name: media_kit_libs_video + sha256: "3688e0c31482074578652bf038ce6301a5d21e1eda6b54fc3117ffeb4bdba067" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + media_kit_libs_windows_video: + dependency: transitive + description: + name: media_kit_libs_windows_video + sha256: "7bace5f35d9afcc7f9b5cdadb7541d2191a66bb3fc71bfa11c1395b3360f6122" + url: "https://pub.dev" + source: hosted + version: "1.0.9" + media_kit_native_event_loop: + dependency: transitive + description: + name: media_kit_native_event_loop + sha256: a605cf185499d14d58935b8784955a92a4bf0ff4e19a23de3d17a9106303930e + url: "https://pub.dev" + source: hosted + version: "1.0.8" + media_kit_video: + dependency: transitive + description: + name: media_kit_video + sha256: c048d11a19e379aebbe810647636e3fc6d18374637e2ae12def4ff8a4b99a882 + url: "https://pub.dev" + source: hosted + version: "1.2.4" meta: dependency: transitive description: @@ -1385,6 +1497,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + photo_view: + dependency: transitive + description: + name: photo_view + sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e" + url: "https://pub.dev" + source: hosted + version: "0.15.0" pixel_snap: dependency: transitive description: @@ -1489,6 +1609,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" + reorderable_tabbar: + dependency: "direct main" + description: + name: reorderable_tabbar + sha256: dd19d7b6f60f0dec4be02ba0a2c860f9acbe5a392cb8b5b8c1417cbfcbfe923f + url: "https://pub.dev" + source: hosted + version: "1.0.6" reorderables: dependency: "direct main" description: @@ -1521,6 +1649,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.27.7" + safe_local_storage: + dependency: transitive + description: + name: safe_local_storage + sha256: ede4eb6cb7d88a116b3d3bf1df70790b9e2038bc37cb19112e381217c74d9440 + url: "https://pub.dev" + source: hosted + version: "1.0.2" scaled_app: dependency: "direct main" description: @@ -1529,6 +1665,54 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + screen_brightness: + dependency: transitive + description: + name: screen_brightness + sha256: ed8da4a4511e79422fc1aa88138e920e4008cd312b72cdaa15ccb426c0faaedd + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" + screen_brightness_android: + dependency: transitive + description: + name: screen_brightness_android + sha256: "3df10961e3a9e968a5e076fe27e7f4741fa8a1d3950bdeb48cf121ed529d0caf" + url: "https://pub.dev" + source: hosted + version: "0.1.0+2" + screen_brightness_ios: + dependency: transitive + description: + name: screen_brightness_ios + sha256: "99adc3ca5490b8294284aad5fcc87f061ad685050e03cf45d3d018fe398fd9a2" + url: "https://pub.dev" + source: hosted + version: "0.1.0" + screen_brightness_macos: + dependency: transitive + description: + name: screen_brightness_macos + sha256: "64b34e7e3f4900d7687c8e8fb514246845a73ecec05ab53483ed025bd4a899fd" + url: "https://pub.dev" + source: hosted + version: "0.1.0+1" + screen_brightness_platform_interface: + dependency: transitive + description: + name: screen_brightness_platform_interface + sha256: b211d07f0c96637a15fb06f6168617e18030d5d74ad03795dd8547a52717c171 + url: "https://pub.dev" + source: hosted + version: "0.1.0" + screen_brightness_windows: + dependency: transitive + description: + name: screen_brightness_windows + sha256: "9261bf33d0fc2707d8cf16339ce25768100a65e70af0fcabaf032fc12408ba86" + url: "https://pub.dev" + source: hosted + version: "0.1.3" screen_retriever: dependency: transitive description: @@ -1537,6 +1721,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.9" + scroll_to_index: + dependency: transitive + description: + name: scroll_to_index + sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176 + url: "https://pub.dev" + source: hosted + version: "3.0.1" scrollable_positioned_list: dependency: "direct main" description: @@ -1658,6 +1850,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + shimmer: + dependency: "direct main" + description: + name: shimmer + sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9" + url: "https://pub.dev" + source: hosted + version: "3.0.0" simple_gesture_detector: dependency: transitive description: @@ -1856,6 +2056,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0+1" + tab_indicator_styler: + dependency: transitive + description: + name: tab_indicator_styler + sha256: "9e7e90367e20f71f3882fc6578fdcced35ab1c66ab20fcb623cdcc20d2796c76" + url: "https://pub.dev" + source: hosted + version: "2.0.0" table_calendar: dependency: "direct main" description: @@ -1968,6 +2176,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + uri_parser: + dependency: transitive + description: + name: uri_parser + sha256: "6543c9fd86d2862fac55d800a43e67c0dcd1a41677cb69c2f8edfe73bbcf1835" + url: "https://pub.dev" + source: hosted + version: "2.0.2" url_launcher: dependency: "direct main" description: @@ -2105,6 +2321,30 @@ packages: url: "https://pub.dev" source: hosted version: "14.2.1" + volume_controller: + dependency: transitive + description: + name: volume_controller + sha256: "189bdc7a554f476b412e4c8b2f474562b09d74bc458c23667356bce3ca1d48c9" + url: "https://pub.dev" + source: hosted + version: "2.0.7" + wakelock_plus: + dependency: transitive + description: + name: wakelock_plus + sha256: "104d94837bb28c735894dcd592877e990149c380e6358b00c04398ca1426eed4" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + wakelock_plus_platform_interface: + dependency: transitive + description: + name: wakelock_plus_platform_interface + sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16" + url: "https://pub.dev" + source: hosted + version: "1.2.1" watcher: dependency: transitive description: diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 35050161f7..92e82d0c19 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.5.8 +version: 0.5.9 environment: flutter: ">=3.22.0" @@ -47,7 +47,7 @@ dependencies: ref: 8a6434ae3d02624b614a010af80f775db11bf22e appflowy_result: path: packages/appflowy_result - appflowy_editor_plugins: ^0.0.2 + appflowy_editor_plugins: ^0.0.6 appflowy_editor: @@ -135,7 +135,12 @@ dependencies: numerus: ^2.1.2 flutter_animate: ^4.5.0 permission_handler: ^11.3.1 + flutter_chat_ui: ^1.6.13 + flutter_chat_types: ^3.6.2 scaled_app: ^2.3.0 + auto_size_text_field: ^2.2.3 + reorderable_tabbar: ^1.0.6 + shimmer: ^3.0.0 dev_dependencies: flutter_lints: ^3.0.1 diff --git a/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart b/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart index abff7256b2..e29c6a4a73 100644 --- a/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart +++ b/frontend/appflowy_flutter/test/bloc_test/board_test/util.dart @@ -29,7 +29,7 @@ class AppFlowyBoardTest { return ViewBackendService.createView( parentViewId: app.id, name: "Test Board", - layoutType: builder.layoutType!, + layoutType: builder.layoutType, openAfterCreate: true, ).then((result) { return result.fold( diff --git a/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart b/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart index b816a8b68e..d6d0351414 100644 --- a/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart @@ -213,6 +213,9 @@ void main() { const layouts = ViewLayoutPB.values; for (var i = 0; i < layouts.length; i++) { final layout = layouts[i]; + if (layout == ViewLayoutPB.Chat) { + continue; + } viewBloc.add( ViewEvent.createView( 'Test $layout', diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 2a1c42eaa1..d02983e577 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -155,14 +155,14 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "bincode", @@ -179,12 +179,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "appflowy-ai-client" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "bytes", + "futures", + "serde", + "serde_json", + "serde_repr", + "thiserror", +] + [[package]] name = "appflowy_tauri" version = "0.0.0" dependencies = [ "bytes", "dotenv", + "flowy-chat", "flowy-config", "flowy-core", "flowy-date", @@ -194,6 +209,7 @@ dependencies = [ "flowy-search", "flowy-user", "lib-dispatch", + "semver", "serde", "serde_json", "tauri", @@ -529,9 +545,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] @@ -740,7 +756,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "again", "anyhow", @@ -770,6 +786,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", + "serde_urlencoded", "shared-entity", "thiserror", "tokio", @@ -786,7 +803,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "futures-channel", "futures-util", @@ -860,7 +877,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -884,7 +901,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -914,7 +931,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -933,7 +950,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "bytes", @@ -948,7 +965,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "chrono", @@ -986,7 +1003,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-stream", @@ -1025,7 +1042,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "bincode", @@ -1050,7 +1067,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "async-trait", @@ -1067,7 +1084,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -1296,7 +1313,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1407,7 +1424,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", @@ -1485,6 +1502,7 @@ dependencies = [ "diesel_derives", "libsqlite3-sys", "r2d2", + "serde_json", "time", ] @@ -1794,6 +1812,39 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "flowy-chat" +version = "0.1.0" +dependencies = [ + "bytes", + "dashmap", + "flowy-chat-pub", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-notification", + "flowy-sqlite", + "futures", + "lib-dispatch", + "lib-infra", + "protobuf", + "strum_macros 0.21.1", + "tokio", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "flowy-chat-pub" +version = "0.1.0" +dependencies = [ + "client-api", + "flowy-error", + "futures", + "lib-infra", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -1845,6 +1896,8 @@ dependencies = [ "collab-integrate", "collab-plugins", "diesel", + "flowy-chat", + "flowy-chat-pub", "flowy-config", "flowy-database-pub", "flowy-database2", @@ -2175,6 +2228,7 @@ dependencies = [ "collab-entity", "collab-folder", "collab-plugins", + "flowy-chat-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -2195,6 +2249,7 @@ dependencies = [ "postgrest", "rand 0.8.5", "reqwest", + "semver", "serde", "serde_json", "thiserror", @@ -2777,7 +2832,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "futures-util", @@ -2794,7 +2849,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", @@ -3226,7 +3281,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "reqwest", @@ -4729,7 +4784,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.11.0", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -4750,7 +4805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.47", @@ -5524,27 +5579,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.195" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -5714,13 +5769,15 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", + "appflowy-ai-client", "chrono", "collab-entity", "database-entity", + "futures", "gotrue-entity", "reqwest", "serde", @@ -6566,18 +6623,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 6b3a671077..9cfcf94740 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -20,7 +20,7 @@ bytes = "1.5.0" serde = "1.0" serde_json = "1.0.108" protobuf = { version = "2.28.0" } -diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } +diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2", "serde_json"] } uuid = { version = "1.5.0", features = ["serde", "v4"] } serde_repr = "0.1" parking_lot = "0.12" @@ -52,7 +52,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ef96b42e43c7b929a928f6c334967c7edffc1319" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } [dependencies] serde_json.workspace = true @@ -75,6 +75,7 @@ flowy-core = { path = "../../rust-lib/flowy-core", features = [ flowy-user = { path = "../../rust-lib/flowy-user", features = ["tauri_ts"] } flowy-config = { path = "../../rust-lib/flowy-config", features = ["tauri_ts"] } flowy-date = { path = "../../rust-lib/flowy-date", features = ["tauri_ts"] } +flowy-chat = { path = "../../rust-lib/flowy-chat", features = ["tauri_ts"] } flowy-error = { path = "../../rust-lib/flowy-error", features = [ "impl_from_sqlite", "impl_from_dispatch_error", @@ -105,10 +106,10 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } \ No newline at end of file +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } \ No newline at end of file diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 8024a9ba1f..0ed8840871 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -209,14 +209,14 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "bincode", @@ -233,6 +233,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "appflowy-ai-client" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "bytes", + "futures", + "serde", + "serde_json", + "serde_repr", + "thiserror", +] + [[package]] name = "arc-swap" version = "1.7.1" @@ -428,9 +442,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] @@ -548,7 +562,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "again", "anyhow", @@ -578,6 +592,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", + "serde_urlencoded", "shared-entity", "thiserror", "tokio", @@ -594,7 +609,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "futures-channel", "futures-util", @@ -638,7 +653,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -662,7 +677,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -681,7 +696,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "bytes", @@ -696,7 +711,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "chrono", @@ -734,7 +749,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-stream", @@ -772,7 +787,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "bincode", @@ -797,7 +812,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "async-trait", @@ -814,7 +829,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -1011,7 +1026,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", @@ -1241,6 +1256,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "flowy-chat-pub" +version = "0.1.0" +dependencies = [ + "client-api", + "flowy-error", + "futures", + "lib-infra", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -1463,6 +1488,7 @@ dependencies = [ "collab-entity", "collab-folder", "collab-plugins", + "flowy-chat-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -1483,6 +1509,7 @@ dependencies = [ "postgrest", "rand 0.8.5", "reqwest", + "semver", "serde", "serde_json", "thiserror", @@ -1788,7 +1815,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "futures-util", @@ -1805,7 +1832,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", @@ -2106,7 +2133,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "reqwest", @@ -3617,15 +3644,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] @@ -3643,9 +3670,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", @@ -3746,13 +3773,15 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", + "appflowy-ai-client", "chrono", "collab-entity", "database-entity", + "futures", "gotrue-entity", "reqwest", "serde", @@ -4033,18 +4062,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -4235,6 +4264,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -5009,4 +5039,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2c430e0#2c430e05fff6ca541cfef9836dc72e66a7847b6e" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index e6637b4d31..01fc3fad33 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ yrs = "0.18.8" # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ef96b42e43c7b929a928f6c334967c7edffc1319" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } @@ -70,10 +70,10 @@ opt-level = 3 codegen-units = 1 [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } \ No newline at end of file +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } \ No newline at end of file diff --git a/frontend/appflowy_web_app/.eslintignore b/frontend/appflowy_web_app/.eslintignore index 8b900e497c..b921919753 100644 --- a/frontend/appflowy_web_app/.eslintignore +++ b/frontend/appflowy_web_app/.eslintignore @@ -6,4 +6,5 @@ tsconfig.json **/backend/** vite.config.ts **/*.cy.tsx -*.config.ts \ No newline at end of file +*.config.ts +coverage/ \ No newline at end of file diff --git a/frontend/appflowy_web_app/.eslintignore.web b/frontend/appflowy_web_app/.eslintignore.web index 4cee523276..44dcf6dda2 100644 --- a/frontend/appflowy_web_app/.eslintignore.web +++ b/frontend/appflowy_web_app/.eslintignore.web @@ -4,4 +4,5 @@ src-tauri/ .eslintrc.cjs tsconfig.json src/application/services/tauri-services/ -vite.config.ts \ No newline at end of file +vite.config.ts +coverage/ \ No newline at end of file diff --git a/frontend/appflowy_web_app/.gitignore b/frontend/appflowy_web_app/.gitignore index 474a3a975e..5ae4f07836 100644 --- a/frontend/appflowy_web_app/.gitignore +++ b/frontend/appflowy_web_app/.gitignore @@ -29,4 +29,7 @@ src/@types/translations/*.json src/application/services/tauri-services/backend/models/ src/application/services/tauri-services/backend/events/ -.env \ No newline at end of file +.env + +coverage +.nyc_output \ No newline at end of file diff --git a/frontend/appflowy_web_app/.nycrc b/frontend/appflowy_web_app/.nycrc new file mode 100644 index 0000000000..9d69b3c074 --- /dev/null +++ b/frontend/appflowy_web_app/.nycrc @@ -0,0 +1,22 @@ +{ + "all": true, + "extends": "@istanbuljs/nyc-config-typescript", + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "exclude": [ + "cypress/**/*.*", + "**/*.d.ts", + "**/*.cy.tsx", + "**/*.cy.ts" + ], + "reporter": [ + "text", + "html", + "text-summary", + "json" + ], + "temp-dir": "coverage/.nyc_output", + "report-dir": "coverage/cypress" +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress.config.ts b/frontend/appflowy_web_app/cypress.config.ts index c8f9f6972f..df9da9b91d 100644 --- a/frontend/appflowy_web_app/cypress.config.ts +++ b/frontend/appflowy_web_app/cypress.config.ts @@ -1,11 +1,22 @@ import { defineConfig } from 'cypress'; +import registerCodeCoverageTasks from '@cypress/code-coverage/task'; export default defineConfig({ + env: { + codeCoverage: { + exclude: ['cypress/**/*.*', '**/__tests__/**/*.*', '**/*.test.*'], + }, + }, component: { devServer: { framework: 'react', bundler: 'vite', }, + setupNodeEvents(on, config) { + registerCodeCoverageTasks(on, config); + return config; + }, + supportFile: 'cypress/support/component.ts', }, retries: { // Configure retry attempts for `cypress run` diff --git a/frontend/appflowy_web_app/cypress/fixtures/current_workspace.json b/frontend/appflowy_web_app/cypress/fixtures/current_workspace.json new file mode 100644 index 0000000000..cef4bad369 --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/current_workspace.json @@ -0,0 +1,11 @@ +{ + "id": "9eebea03-3ed5-4298-86b2-a7f77856d48b", + "name": "workspace", + "icon": "", + "owner": { + "id": 0, + "name": "system" + }, + "type": 0, + "workspaceDatabaseId": "375874be-7a4f-4b7c-8b89-1dc9a39838f4" +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/4c658817-20db-4f56-b7f9-0637a22dfeb6.json b/frontend/appflowy_web_app/cypress/fixtures/database/4c658817-20db-4f56-b7f9-0637a22dfeb6.json new file mode 100644 index 0000000000..f2dc3ef4fb --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/4c658817-20db-4f56-b7f9-0637a22dfeb6.json @@ -0,0 +1 @@ +{"data":{"state_vector":[65,128,137,148,150,4,39,132,238,182,192,14,5,134,200,133,143,5,2,135,173,169,205,15,4,137,227,133,241,2,170,1,140,242,215,248,4,35,141,132,223,206,14,5,142,215,187,158,14,10,146,198,138,224,6,18,149,154,146,112,20,150,194,135,131,8,12,154,253,168,186,13,6,157,197,217,249,6,3,158,173,179,170,6,81,160,159,229,236,10,34,162,129,240,225,15,19,165,237,195,173,1,8,168,211,203,155,8,88,171,216,132,162,10,97,174,158,229,225,9,2,175,150,167,163,14,4,174,182,200,164,11,2,177,178,255,174,1,38,178,161,242,226,13,154,1,174,250,146,158,5,2,180,149,168,150,13,10,180,132,165,192,8,1,182,201,218,189,1,12,182,139,168,140,5,36,183,238,200,180,5,6,185,145,225,175,8,157,3,186,204,138,236,4,118,187,163,190,240,15,89,187,159,219,213,8,2,188,252,160,180,14,5,191,215,204,166,13,12,192,183,207,147,14,43,193,174,143,180,7,18,193,140,213,146,2,134,1,200,168,240,223,7,2,201,191,253,157,12,2,200,156,140,203,9,2,202,170,215,178,7,24,203,248,208,163,4,4,206,242,242,141,13,95,209,142,245,200,15,183,5,210,221,238,195,8,20,211,189,178,91,80,211,235,145,81,16,216,247,253,206,7,2,219,179,165,244,8,4,224,218,133,236,10,13,227,170,238,211,14,16,227,250,198,245,13,5,229,168,135,118,243,4,234,232,155,212,3,4,246,154,200,238,10,11,247,149,251,192,4,4,248,220,249,231,6,29,247,187,192,242,6,6,250,147,239,143,1,2,252,220,241,227,14,60,253,149,229,85,14,253,223,254,206,11,2,252,240,184,224,14,24],"doc_state":[65,79,187,163,190,240,15,0,39,0,137,227,133,241,2,3,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,1,40,0,187,163,190,240,15,0,2,105,100,1,119,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,40,0,187,163,190,240,15,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,187,163,190,240,15,0,4,110,97,109,101,1,119,5,66,111,97,114,100,40,0,187,163,190,240,15,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,33,0,187,163,190,240,15,0,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,187,163,190,240,15,0,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,187,163,190,240,15,6,1,49,1,40,0,187,163,190,240,15,7,21,104,105,100,101,95,117,110,103,114,111,117,112,101,100,95,99,111,108,117,109,110,1,121,40,0,187,163,190,240,15,7,22,99,111,108,108,97,112,115,101,95,104,105,100,100,101,110,95,103,114,111,117,112,115,1,121,40,0,187,163,190,240,15,0,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,39,0,187,163,190,240,15,0,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,187,163,190,240,15,0,7,102,105,108,116,101,114,115,0,39,0,187,163,190,240,15,0,6,103,114,111,117,112,115,0,39,0,187,163,190,240,15,0,5,115,111,114,116,115,0,39,0,187,163,190,240,15,0,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,187,163,190,240,15,15,4,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,39,0,187,163,190,240,15,0,10,114,111,119,95,111,114,100,101,114,115,0,8,0,187,163,190,240,15,20,3,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,118,2,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,6,104,101,105,103,104,116,125,60,161,187,163,190,240,15,5,1,7,0,187,163,190,240,15,13,1,33,0,187,163,190,240,15,25,8,102,105,101,108,100,95,105,100,1,33,0,187,163,190,240,15,25,2,116,121,1,33,0,187,163,190,240,15,25,7,99,111,110,116,101,110,116,1,33,0,187,163,190,240,15,25,2,105,100,1,33,0,187,163,190,240,15,25,6,103,114,111,117,112,115,1,161,187,163,190,240,15,24,1,161,187,163,190,240,15,30,1,0,1,161,187,163,190,240,15,26,1,161,187,163,190,240,15,29,1,161,187,163,190,240,15,27,1,161,187,163,190,240,15,28,1,39,0,137,227,133,241,2,3,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,1,40,0,187,163,190,240,15,38,2,105,100,1,119,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,40,0,187,163,190,240,15,38,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,187,163,190,240,15,38,4,110,97,109,101,1,119,8,67,97,108,101,110,100,97,114,40,0,187,163,190,240,15,38,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,33,0,187,163,190,240,15,38,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,187,163,190,240,15,38,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,187,163,190,240,15,44,1,50,1,40,0,187,163,190,240,15,45,8,102,105,101,108,100,95,105,100,1,119,6,106,87,101,95,116,54,40,0,187,163,190,240,15,45,13,115,104,111,119,95,119,101,101,107,101,110,100,115,1,120,40,0,187,163,190,240,15,45,17,115,104,111,119,95,119,101,101,107,95,110,117,109,98,101,114,115,1,120,40,0,187,163,190,240,15,45,17,102,105,114,115,116,95,100,97,121,95,111,102,95,119,101,101,107,1,122,0,0,0,0,0,0,0,0,40,0,187,163,190,240,15,45,9,108,97,121,111,117,116,95,116,121,1,122,0,0,0,0,0,0,0,0,40,0,187,163,190,240,15,38,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,39,0,187,163,190,240,15,38,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,187,163,190,240,15,38,7,102,105,108,116,101,114,115,0,39,0,187,163,190,240,15,38,6,103,114,111,117,112,115,0,39,0,187,163,190,240,15,38,5,115,111,114,116,115,0,39,0,187,163,190,240,15,38,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,187,163,190,240,15,56,4,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,39,0,187,163,190,240,15,38,10,114,111,119,95,111,114,100,101,114,115,0,8,0,187,163,190,240,15,61,3,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,161,187,163,190,240,15,31,1,136,187,163,190,240,15,19,1,118,1,2,105,100,119,6,106,87,101,95,116,54,39,0,187,163,190,240,15,11,6,106,87,101,95,116,54,1,40,0,187,163,190,240,15,67,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,137,227,133,241,2,67,1,136,137,227,133,241,2,68,1,118,1,2,105,100,119,6,106,87,101,95,116,54,39,0,137,227,133,241,2,43,6,106,87,101,95,116,54,1,40,0,187,163,190,240,15,71,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,187,163,190,240,15,43,1,136,187,163,190,240,15,60,1,118,1,2,105,100,119,6,106,87,101,95,116,54,39,0,187,163,190,240,15,52,6,106,87,101,95,116,54,1,40,0,187,163,190,240,15,75,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,137,227,133,241,2,2,6,106,87,101,95,116,54,1,40,0,187,163,190,240,15,77,2,105,100,1,119,6,106,87,101,95,116,54,40,0,187,163,190,240,15,77,4,110,97,109,101,1,119,4,68,97,116,101,40,0,187,163,190,240,15,77,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,178,115,33,0,187,163,190,240,15,77,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,187,163,190,240,15,77,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,187,163,190,240,15,77,2,116,121,1,39,0,187,163,190,240,15,77,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,187,163,190,240,15,84,1,50,1,40,0,187,163,190,240,15,85,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,187,163,190,240,15,85,11,116,105,109,101,122,111,110,101,95,105,100,1,119,0,40,0,187,163,190,240,15,85,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,1,162,129,240,225,15,0,161,219,179,165,244,8,3,19,1,135,173,169,205,15,0,161,175,150,167,163,14,3,4,155,5,209,142,245,200,15,0,161,229,168,135,118,214,4,1,161,229,168,135,118,202,4,1,161,209,142,245,200,15,0,1,161,229,168,135,118,204,4,1,161,229,168,135,118,216,4,1,161,229,168,135,118,218,4,1,161,229,168,135,118,217,4,1,161,229,168,135,118,215,4,1,161,209,142,245,200,15,2,1,161,209,142,245,200,15,4,1,161,209,142,245,200,15,7,1,161,209,142,245,200,15,5,1,161,209,142,245,200,15,6,1,161,209,142,245,200,15,8,1,161,209,142,245,200,15,9,1,161,209,142,245,200,15,11,1,161,209,142,245,200,15,12,1,161,209,142,245,200,15,10,1,161,209,142,245,200,15,13,1,161,209,142,245,200,15,1,1,161,209,142,245,200,15,18,1,161,209,142,245,200,15,3,1,161,209,142,245,200,15,15,1,161,209,142,245,200,15,17,1,161,209,142,245,200,15,14,1,161,209,142,245,200,15,16,1,161,209,142,245,200,15,20,1,161,209,142,245,200,15,24,1,161,209,142,245,200,15,25,1,161,209,142,245,200,15,22,1,161,209,142,245,200,15,23,1,161,209,142,245,200,15,26,1,161,209,142,245,200,15,29,1,161,209,142,245,200,15,28,1,161,209,142,245,200,15,27,1,161,209,142,245,200,15,30,1,161,209,142,245,200,15,31,1,161,209,142,245,200,15,19,1,161,209,142,245,200,15,36,1,161,209,142,245,200,15,21,1,161,209,142,245,200,15,32,1,161,209,142,245,200,15,33,1,161,209,142,245,200,15,34,1,161,209,142,245,200,15,35,1,161,209,142,245,200,15,38,1,161,209,142,245,200,15,43,1,161,209,142,245,200,15,42,1,161,209,142,245,200,15,41,1,161,209,142,245,200,15,40,1,161,209,142,245,200,15,44,1,161,209,142,245,200,15,47,1,161,209,142,245,200,15,48,1,161,209,142,245,200,15,45,1,161,209,142,245,200,15,46,1,161,209,142,245,200,15,49,1,168,209,142,245,200,15,37,1,119,4,84,101,120,116,161,209,142,245,200,15,54,1,168,209,142,245,200,15,39,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,53,1,161,209,142,245,200,15,52,1,161,209,142,245,200,15,50,1,161,209,142,245,200,15,51,1,161,209,142,245,200,15,56,1,161,209,142,245,200,15,60,1,161,209,142,245,200,15,58,1,161,209,142,245,200,15,61,1,161,209,142,245,200,15,59,1,168,209,142,245,200,15,62,1,122,0,0,0,0,102,65,132,91,168,209,142,245,200,15,65,1,122,0,0,0,0,0,0,0,36,168,209,142,245,200,15,64,1,122,0,0,0,0,0,0,0,0,168,209,142,245,200,15,63,1,119,0,168,209,142,245,200,15,66,1,119,0,161,168,211,203,155,8,0,1,161,137,227,133,241,2,18,1,161,209,142,245,200,15,72,1,161,137,227,133,241,2,22,1,161,168,211,203,155,8,1,1,161,209,142,245,200,15,74,1,161,209,142,245,200,15,76,1,161,209,142,245,200,15,77,1,161,209,142,245,200,15,78,1,161,182,201,218,189,1,4,1,161,177,178,255,174,1,2,1,0,3,161,177,178,255,174,1,7,1,161,177,178,255,174,1,6,1,161,177,178,255,174,1,1,1,161,177,178,255,174,1,5,1,161,209,142,245,200,15,79,1,161,209,142,245,200,15,73,1,161,209,142,245,200,15,90,1,161,209,142,245,200,15,75,1,161,209,142,245,200,15,80,1,161,209,142,245,200,15,92,1,161,209,142,245,200,15,94,1,161,209,142,245,200,15,95,1,161,209,142,245,200,15,96,1,161,209,142,245,200,15,97,1,161,209,142,245,200,15,91,1,161,209,142,245,200,15,99,1,161,209,142,245,200,15,93,1,161,209,142,245,200,15,98,1,161,209,142,245,200,15,101,1,161,209,142,245,200,15,103,1,161,209,142,245,200,15,104,1,161,209,142,245,200,15,105,1,161,209,142,245,200,15,106,1,161,209,142,245,200,15,100,1,161,209,142,245,200,15,108,1,161,209,142,245,200,15,102,1,161,209,142,245,200,15,107,1,161,209,142,245,200,15,110,1,161,209,142,245,200,15,112,1,161,209,142,245,200,15,113,1,161,209,142,245,200,15,114,1,161,209,142,245,200,15,115,1,161,209,142,245,200,15,109,1,161,209,142,245,200,15,117,1,161,209,142,245,200,15,111,1,161,209,142,245,200,15,116,1,161,209,142,245,200,15,119,1,161,209,142,245,200,15,121,1,161,209,142,245,200,15,122,1,161,209,142,245,200,15,123,1,161,209,142,245,200,15,81,1,168,209,142,245,200,15,89,1,119,6,70,114,115,115,74,100,168,209,142,245,200,15,87,1,119,0,168,209,142,245,200,15,88,1,119,8,103,58,95,51,55,82,110,115,168,209,142,245,200,15,86,1,122,0,0,0,0,0,0,0,3,167,209,142,245,200,15,82,0,8,0,209,142,245,200,15,131,1,4,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,6,70,114,115,115,74,100,118,2,2,105,100,119,4,120,90,48,51,7,118,105,115,105,98,108,101,120,118,2,2,105,100,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,7,118,105,115,105,98,108,101,120,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,36,54,49,50,100,50,99,51,98,45,56,50,98,99,45,52,55,51,98,45,98,49,52,53,45,55,102,53,55,49,56,54,101,51,102,55,101,161,209,142,245,200,15,124,1,161,209,142,245,200,15,118,1,161,209,142,245,200,15,136,1,1,161,209,142,245,200,15,120,1,161,209,142,245,200,15,125,1,161,209,142,245,200,15,138,1,1,161,209,142,245,200,15,140,1,1,161,209,142,245,200,15,141,1,1,161,209,142,245,200,15,142,1,1,161,209,142,245,200,15,143,1,1,161,209,142,245,200,15,137,1,1,161,209,142,245,200,15,145,1,1,161,209,142,245,200,15,139,1,1,161,209,142,245,200,15,144,1,1,161,209,142,245,200,15,147,1,1,161,209,142,245,200,15,149,1,1,161,209,142,245,200,15,150,1,1,161,209,142,245,200,15,151,1,1,161,209,142,245,200,15,152,1,1,161,209,142,245,200,15,146,1,1,161,209,142,245,200,15,154,1,1,161,209,142,245,200,15,148,1,1,161,209,142,245,200,15,153,1,1,161,209,142,245,200,15,156,1,1,161,209,142,245,200,15,158,1,1,161,209,142,245,200,15,159,1,1,161,209,142,245,200,15,160,1,1,161,209,142,245,200,15,161,1,1,168,209,142,245,200,15,155,1,1,119,4,84,121,112,101,161,209,142,245,200,15,163,1,1,168,209,142,245,200,15,157,1,1,122,0,0,0,0,0,0,0,3,161,209,142,245,200,15,162,1,1,161,209,142,245,200,15,165,1,1,161,209,142,245,200,15,167,1,1,168,209,142,245,200,15,168,1,1,122,0,0,0,0,102,65,140,43,168,209,142,245,200,15,169,1,1,119,227,1,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,120,90,48,51,34,44,34,110,97,109,101,34,58,34,55,55,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,44,123,34,105,100,34,58,34,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,34,44,34,110,97,109,101,34,58,34,57,57,57,34,44,34,99,111,108,111,114,34,58,34,80,105,110,107,34,125,44,123,34,105,100,34,58,34,54,49,50,100,50,99,51,98,45,56,50,98,99,45,52,55,51,98,45,98,49,52,53,45,55,102,53,55,49,56,54,101,51,102,55,101,34,44,34,110,97,109,101,34,58,34,49,48,48,48,34,44,34,99,111,108,111,114,34,58,34,80,105,110,107,34,125,93,44,34,100,105,115,97,98,108,101,95,99,111,108,111,114,34,58,102,97,108,115,101,125,161,137,227,133,241,2,162,1,1,161,137,227,133,241,2,160,1,1,161,209,142,245,200,15,172,1,1,161,137,227,133,241,2,164,1,1,39,0,137,227,133,241,2,165,1,1,52,1,33,0,209,142,245,200,15,176,1,7,99,111,110,116,101,110,116,1,161,209,142,245,200,15,174,1,1,40,0,137,227,133,241,2,166,1,7,99,111,110,116,101,110,116,1,119,36,123,34,111,112,116,105,111,110,115,34,58,91,93,44,34,100,105,115,97,98,108,101,95,99,111,108,111,114,34,58,102,97,108,115,101,125,161,182,201,218,189,1,6,1,161,209,142,245,200,15,126,1,161,209,142,245,200,15,178,1,1,161,209,142,245,200,15,177,1,1,161,209,142,245,200,15,182,1,1,161,209,142,245,200,15,173,1,1,161,209,142,245,200,15,184,1,1,161,209,142,245,200,15,175,1,1,161,209,142,245,200,15,183,1,1,161,209,142,245,200,15,186,1,1,161,209,142,245,200,15,188,1,1,161,209,142,245,200,15,189,1,1,161,209,142,245,200,15,190,1,1,161,209,142,245,200,15,191,1,1,161,209,142,245,200,15,185,1,1,161,209,142,245,200,15,193,1,1,161,209,142,245,200,15,187,1,1,161,209,142,245,200,15,192,1,1,161,209,142,245,200,15,195,1,1,161,209,142,245,200,15,197,1,1,161,209,142,245,200,15,198,1,1,161,209,142,245,200,15,199,1,1,161,209,142,245,200,15,200,1,1,161,209,142,245,200,15,194,1,1,161,209,142,245,200,15,202,1,1,161,209,142,245,200,15,196,1,1,161,209,142,245,200,15,201,1,1,161,209,142,245,200,15,204,1,1,161,209,142,245,200,15,206,1,1,161,209,142,245,200,15,207,1,1,161,209,142,245,200,15,208,1,1,161,209,142,245,200,15,209,1,1,161,209,142,245,200,15,203,1,1,161,209,142,245,200,15,211,1,1,161,209,142,245,200,15,205,1,1,161,209,142,245,200,15,210,1,1,161,209,142,245,200,15,213,1,1,161,209,142,245,200,15,215,1,1,161,209,142,245,200,15,216,1,1,161,209,142,245,200,15,217,1,1,161,209,142,245,200,15,218,1,1,161,209,142,245,200,15,212,1,1,161,209,142,245,200,15,220,1,1,161,209,142,245,200,15,214,1,1,161,209,142,245,200,15,219,1,1,161,209,142,245,200,15,222,1,1,161,209,142,245,200,15,224,1,1,161,209,142,245,200,15,225,1,1,161,209,142,245,200,15,226,1,1,161,209,142,245,200,15,227,1,1,161,209,142,245,200,15,221,1,1,161,209,142,245,200,15,229,1,1,161,209,142,245,200,15,223,1,1,161,209,142,245,200,15,228,1,1,161,209,142,245,200,15,231,1,1,161,209,142,245,200,15,233,1,1,161,209,142,245,200,15,234,1,1,161,209,142,245,200,15,235,1,1,161,209,142,245,200,15,236,1,1,161,209,142,245,200,15,230,1,1,161,209,142,245,200,15,238,1,1,161,209,142,245,200,15,232,1,1,161,209,142,245,200,15,237,1,1,161,209,142,245,200,15,240,1,1,161,209,142,245,200,15,242,1,1,161,209,142,245,200,15,243,1,1,161,209,142,245,200,15,244,1,1,161,209,142,245,200,15,245,1,1,161,209,142,245,200,15,239,1,1,161,209,142,245,200,15,247,1,1,161,209,142,245,200,15,241,1,1,161,209,142,245,200,15,246,1,1,161,209,142,245,200,15,249,1,1,161,209,142,245,200,15,251,1,1,161,209,142,245,200,15,252,1,1,161,209,142,245,200,15,253,1,1,161,209,142,245,200,15,254,1,1,161,209,142,245,200,15,248,1,1,161,209,142,245,200,15,128,2,1,161,209,142,245,200,15,250,1,1,161,209,142,245,200,15,255,1,1,161,209,142,245,200,15,130,2,1,161,209,142,245,200,15,132,2,1,161,209,142,245,200,15,133,2,1,161,209,142,245,200,15,134,2,1,161,209,142,245,200,15,135,2,1,161,209,142,245,200,15,129,2,1,161,209,142,245,200,15,137,2,1,161,209,142,245,200,15,131,2,1,161,209,142,245,200,15,136,2,1,161,209,142,245,200,15,139,2,1,161,209,142,245,200,15,141,2,1,161,209,142,245,200,15,142,2,1,161,209,142,245,200,15,143,2,1,161,209,142,245,200,15,144,2,1,161,209,142,245,200,15,138,2,1,161,209,142,245,200,15,146,2,1,161,209,142,245,200,15,140,2,1,161,209,142,245,200,15,145,2,1,161,209,142,245,200,15,148,2,1,161,209,142,245,200,15,150,2,1,161,209,142,245,200,15,151,2,1,161,209,142,245,200,15,152,2,1,161,209,142,245,200,15,153,2,1,161,209,142,245,200,15,147,2,1,161,209,142,245,200,15,155,2,1,161,209,142,245,200,15,149,2,1,161,209,142,245,200,15,154,2,1,161,209,142,245,200,15,157,2,1,161,209,142,245,200,15,159,2,1,161,209,142,245,200,15,160,2,1,161,209,142,245,200,15,161,2,1,161,209,142,245,200,15,162,2,1,161,209,142,245,200,15,156,2,1,161,209,142,245,200,15,164,2,1,161,209,142,245,200,15,158,2,1,161,209,142,245,200,15,163,2,1,161,209,142,245,200,15,166,2,1,161,209,142,245,200,15,168,2,1,161,209,142,245,200,15,169,2,1,161,209,142,245,200,15,170,2,1,161,209,142,245,200,15,171,2,1,161,209,142,245,200,15,165,2,1,161,209,142,245,200,15,173,2,1,161,209,142,245,200,15,167,2,1,161,209,142,245,200,15,172,2,1,161,209,142,245,200,15,175,2,1,161,209,142,245,200,15,177,2,1,161,209,142,245,200,15,178,2,1,161,209,142,245,200,15,179,2,1,161,209,142,245,200,15,180,2,1,161,209,142,245,200,15,174,2,1,161,209,142,245,200,15,182,2,1,161,209,142,245,200,15,176,2,1,161,209,142,245,200,15,181,2,1,161,209,142,245,200,15,184,2,1,161,209,142,245,200,15,186,2,1,161,209,142,245,200,15,187,2,1,161,209,142,245,200,15,188,2,1,161,209,142,245,200,15,189,2,1,161,209,142,245,200,15,183,2,1,161,209,142,245,200,15,191,2,1,161,209,142,245,200,15,185,2,1,161,209,142,245,200,15,190,2,1,161,209,142,245,200,15,193,2,1,161,209,142,245,200,15,195,2,1,161,209,142,245,200,15,196,2,1,161,209,142,245,200,15,197,2,1,161,209,142,245,200,15,198,2,1,161,209,142,245,200,15,192,2,1,161,209,142,245,200,15,200,2,1,161,209,142,245,200,15,194,2,1,161,209,142,245,200,15,199,2,1,161,209,142,245,200,15,202,2,1,161,209,142,245,200,15,204,2,1,161,209,142,245,200,15,205,2,1,161,209,142,245,200,15,206,2,1,161,209,142,245,200,15,207,2,1,161,209,142,245,200,15,201,2,1,161,209,142,245,200,15,209,2,1,161,209,142,245,200,15,203,2,1,161,209,142,245,200,15,208,2,1,161,209,142,245,200,15,211,2,1,161,209,142,245,200,15,213,2,1,161,209,142,245,200,15,214,2,1,161,209,142,245,200,15,215,2,1,161,209,142,245,200,15,216,2,1,161,209,142,245,200,15,210,2,1,161,209,142,245,200,15,218,2,1,161,209,142,245,200,15,212,2,1,161,209,142,245,200,15,217,2,1,161,209,142,245,200,15,220,2,1,161,209,142,245,200,15,222,2,1,161,209,142,245,200,15,223,2,1,161,209,142,245,200,15,224,2,1,161,209,142,245,200,15,225,2,1,161,209,142,245,200,15,219,2,1,161,209,142,245,200,15,227,2,1,161,209,142,245,200,15,221,2,1,161,209,142,245,200,15,226,2,1,161,209,142,245,200,15,229,2,1,161,209,142,245,200,15,231,2,1,161,209,142,245,200,15,232,2,1,161,209,142,245,200,15,233,2,1,161,209,142,245,200,15,234,2,1,161,209,142,245,200,15,228,2,1,161,209,142,245,200,15,236,2,1,161,209,142,245,200,15,230,2,1,161,209,142,245,200,15,235,2,1,161,209,142,245,200,15,238,2,1,161,209,142,245,200,15,240,2,1,161,209,142,245,200,15,241,2,1,161,209,142,245,200,15,242,2,1,161,209,142,245,200,15,243,2,1,161,209,142,245,200,15,237,2,1,161,209,142,245,200,15,245,2,1,161,209,142,245,200,15,239,2,1,161,209,142,245,200,15,244,2,1,161,209,142,245,200,15,247,2,1,161,209,142,245,200,15,249,2,1,161,209,142,245,200,15,250,2,1,161,209,142,245,200,15,251,2,1,161,209,142,245,200,15,252,2,1,161,209,142,245,200,15,246,2,1,161,209,142,245,200,15,254,2,1,161,209,142,245,200,15,248,2,1,161,209,142,245,200,15,253,2,1,161,209,142,245,200,15,128,3,1,161,209,142,245,200,15,130,3,1,161,209,142,245,200,15,131,3,1,161,209,142,245,200,15,132,3,1,161,209,142,245,200,15,133,3,1,161,209,142,245,200,15,255,2,1,161,209,142,245,200,15,135,3,1,161,209,142,245,200,15,129,3,1,161,209,142,245,200,15,134,3,1,161,209,142,245,200,15,137,3,1,161,209,142,245,200,15,139,3,1,161,209,142,245,200,15,140,3,1,161,209,142,245,200,15,141,3,1,161,209,142,245,200,15,142,3,1,161,209,142,245,200,15,136,3,1,161,209,142,245,200,15,144,3,1,161,209,142,245,200,15,138,3,1,161,209,142,245,200,15,143,3,1,161,209,142,245,200,15,146,3,1,161,209,142,245,200,15,148,3,1,161,209,142,245,200,15,149,3,1,161,209,142,245,200,15,150,3,1,161,209,142,245,200,15,151,3,1,161,209,142,245,200,15,145,3,1,161,209,142,245,200,15,153,3,1,168,209,142,245,200,15,147,3,1,122,0,0,0,0,0,0,0,4,161,209,142,245,200,15,152,3,1,161,209,142,245,200,15,155,3,1,161,209,142,245,200,15,157,3,1,161,209,142,245,200,15,158,3,1,168,209,142,245,200,15,159,3,1,119,205,5,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,50,100,54,48,51,48,99,51,45,57,55,49,101,45,52,100,52,53,45,98,53,55,48,45,100,101,57,50,102,100,101,97,100,97,101,54,34,44,34,110,97,109,101,34,58,34,103,104,106,116,117,105,107,34,44,34,99,111,108,111,114,34,58,34,71,114,101,101,110,34,125,44,123,34,105,100,34,58,34,102,99,100,54,101,102,56,99,45,56,99,100,54,45,52,49,98,51,45,57,50,52,53,45,57,57,56,57,51,49,100,52,57,97,49,54,34,44,34,110,97,109,101,34,58,34,103,104,106,34,44,34,99,111,108,111,114,34,58,34,80,105,110,107,34,125,44,123,34,105,100,34,58,34,49,99,52,102,53,52,54,57,45,54,101,49,49,45,52,55,48,51,45,57,48,56,54,45,101,98,98,50,51,57,49,53,100,53,100,56,34,44,34,110,97,109,101,34,58,34,111,111,111,34,44,34,99,111,108,111,114,34,58,34,76,105,109,101,34,125,44,123,34,105,100,34,58,34,57,100,48,48,56,50,51,97,45,100,57,101,50,45,52,102,98,55,45,98,100,98,54,45,99,97,102,54,101,98,99,54,99,49,50,51,34,44,34,110,97,109,101,34,58,34,104,106,107,34,44,34,99,111,108,111,114,34,58,34,76,105,103,104,116,80,105,110,107,34,125,44,123,34,105,100,34,58,34,48,52,48,102,98,48,98,102,45,50,101,100,97,45,52,99,97,51,45,56,54,99,97,45,53,98,57,49,98,55,48,50,102,101,49,54,34,44,34,110,97,109,101,34,58,34,110,106,107,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,44,123,34,105,100,34,58,34,52,49,57,50,51,51,57,51,45,102,55,99,51,45,52,50,51,53,45,98,54,49,51,45,102,57,97,101,56,52,102,102,53,56,56,57,34,44,34,110,97,109,101,34,58,34,107,107,107,34,44,34,99,111,108,111,114,34,58,34,66,108,117,101,34,125,44,123,34,105,100,34,58,34,56,51,51,50,99,52,56,51,45,102,56,57,99,45,52,48,53,55,45,57,101,99,57,45,101,50,53,53,56,54,53,48,52,52,51,56,34,44,34,110,97,109,101,34,58,34,98,110,109,34,44,34,99,111,108,111,114,34,58,34,89,101,108,108,111,119,34,125,44,123,34,105,100,34,58,34,52,53,53,98,100,49,56,51,45,54,54,57,102,45,52,98,49,55,45,56,99,56,57,45,56,102,56,53,48,102,102,50,48,51,54,52,34,44,34,110,97,109,101,34,58,34,118,110,109,34,44,34,99,111,108,111,114,34,58,34,79,114,97,110,103,101,34,125,44,123,34,105,100,34,58,34,57,97,102,51,49,102,100,53,45,98,54,53,52,45,52,54,54,54,45,98,101,101,57,45,101,50,52,55,49,51,55,50,53,49,102,53,34,44,34,110,97,109,101,34,58,34,106,106,109,34,44,34,99,111,108,111,114,34,58,34,65,113,117,97,34,125,93,44,34,100,105,115,97,98,108,101,95,99,111,108,111,114,34,58,102,97,108,115,101,125,161,209,142,245,200,15,160,3,1,161,209,142,245,200,15,154,3,1,161,209,142,245,200,15,162,3,1,161,209,142,245,200,15,163,3,1,161,209,142,245,200,15,164,3,1,161,209,142,245,200,15,165,3,1,161,209,142,245,200,15,166,3,1,161,209,142,245,200,15,167,3,1,161,209,142,245,200,15,168,3,1,161,209,142,245,200,15,169,3,1,161,209,142,245,200,15,170,3,1,161,209,142,245,200,15,171,3,1,161,209,142,245,200,15,172,3,1,161,209,142,245,200,15,173,3,1,161,209,142,245,200,15,174,3,1,161,209,142,245,200,15,175,3,1,161,209,142,245,200,15,176,3,1,161,209,142,245,200,15,177,3,1,168,209,142,245,200,15,178,3,1,122,0,0,0,0,102,65,147,48,168,209,142,245,200,15,179,3,1,119,12,109,117,108,116,105,32,115,101,108,101,99,116,161,209,142,245,200,15,181,1,1,136,187,163,190,240,15,66,1,118,1,2,105,100,119,6,55,75,88,95,99,120,39,0,187,163,190,240,15,11,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,184,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,182,201,218,189,1,10,1,136,168,211,203,155,8,63,1,118,1,2,105,100,119,6,55,75,88,95,99,120,39,0,137,227,133,241,2,92,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,188,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,182,201,218,189,1,8,1,136,168,211,203,155,8,71,1,118,1,2,105,100,119,6,55,75,88,95,99,120,39,0,168,211,203,155,8,18,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,192,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,180,1,1,136,187,163,190,240,15,70,1,118,1,2,105,100,119,6,55,75,88,95,99,120,39,0,137,227,133,241,2,43,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,196,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,182,201,218,189,1,2,1,136,168,211,203,155,8,67,1,118,1,2,105,100,119,6,55,75,88,95,99,120,39,0,137,227,133,241,2,133,1,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,200,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,182,201,218,189,1,0,1,136,187,163,190,240,15,74,1,118,1,2,105,100,119,6,55,75,88,95,99,120,39,0,187,163,190,240,15,52,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,204,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,137,227,133,241,2,2,6,55,75,88,95,99,120,1,40,0,209,142,245,200,15,206,3,2,105,100,1,119,6,55,75,88,95,99,120,33,0,209,142,245,200,15,206,3,4,110,97,109,101,1,40,0,209,142,245,200,15,206,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,23,60,33,0,209,142,245,200,15,206,3,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,209,142,245,200,15,206,3,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,209,142,245,200,15,206,3,2,116,121,1,39,0,209,142,245,200,15,206,3,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,209,142,245,200,15,213,3,1,57,1,33,0,209,142,245,200,15,214,3,11,100,97,116,101,95,102,111,114,109,97,116,1,33,0,209,142,245,200,15,214,3,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,209,142,245,200,15,214,3,10,102,105,101,108,100,95,116,121,112,101,1,33,0,209,142,245,200,15,214,3,11,116,105,109,101,95,102,111,114,109,97,116,1,161,209,142,245,200,15,182,3,1,136,209,142,245,200,15,183,3,1,118,1,2,105,100,119,6,76,99,121,68,75,106,39,0,187,163,190,240,15,11,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,221,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,186,3,1,136,209,142,245,200,15,187,3,1,118,1,2,105,100,119,6,76,99,121,68,75,106,39,0,137,227,133,241,2,92,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,225,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,190,3,1,136,209,142,245,200,15,191,3,1,118,1,2,105,100,119,6,76,99,121,68,75,106,39,0,168,211,203,155,8,18,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,229,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,194,3,1,136,209,142,245,200,15,195,3,1,118,1,2,105,100,119,6,76,99,121,68,75,106,39,0,137,227,133,241,2,43,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,233,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,198,3,1,136,209,142,245,200,15,199,3,1,118,1,2,105,100,119,6,76,99,121,68,75,106,39,0,137,227,133,241,2,133,1,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,237,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,202,3,1,136,209,142,245,200,15,203,3,1,118,1,2,105,100,119,6,76,99,121,68,75,106,39,0,187,163,190,240,15,52,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,241,3,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,137,227,133,241,2,2,6,76,99,121,68,75,106,1,40,0,209,142,245,200,15,243,3,2,105,100,1,119,6,76,99,121,68,75,106,40,0,209,142,245,200,15,243,3,4,110,97,109,101,1,119,13,76,97,115,116,32,109,111,100,105,102,105,101,100,40,0,209,142,245,200,15,243,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,23,66,40,0,209,142,245,200,15,243,3,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,67,23,66,40,0,209,142,245,200,15,243,3,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,209,142,245,200,15,243,3,2,116,121,1,122,0,0,0,0,0,0,0,8,39,0,209,142,245,200,15,243,3,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,209,142,245,200,15,250,3,1,56,1,40,0,209,142,245,200,15,251,3,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,0,40,0,209,142,245,200,15,251,3,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,0,40,0,209,142,245,200,15,251,3,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,209,142,245,200,15,251,3,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,161,209,142,245,200,15,210,3,1,161,209,142,245,200,15,208,3,1,161,209,142,245,200,15,128,4,1,161,209,142,245,200,15,212,3,1,161,209,142,245,200,15,217,3,1,161,209,142,245,200,15,215,3,1,161,209,142,245,200,15,216,3,1,161,209,142,245,200,15,218,3,1,161,209,142,245,200,15,130,4,1,161,209,142,245,200,15,132,4,1,161,209,142,245,200,15,134,4,1,161,209,142,245,200,15,135,4,1,161,209,142,245,200,15,133,4,1,161,209,142,245,200,15,136,4,1,161,209,142,245,200,15,140,4,1,161,209,142,245,200,15,138,4,1,161,209,142,245,200,15,139,4,1,161,209,142,245,200,15,137,4,1,161,209,142,245,200,15,141,4,1,161,209,142,245,200,15,129,4,1,161,209,142,245,200,15,146,4,1,161,209,142,245,200,15,131,4,1,161,209,142,245,200,15,143,4,1,161,209,142,245,200,15,145,4,1,161,209,142,245,200,15,144,4,1,161,209,142,245,200,15,142,4,1,161,209,142,245,200,15,148,4,1,161,209,142,245,200,15,153,4,1,161,209,142,245,200,15,152,4,1,161,209,142,245,200,15,150,4,1,161,209,142,245,200,15,151,4,1,161,209,142,245,200,15,154,4,1,161,209,142,245,200,15,155,4,1,161,209,142,245,200,15,157,4,1,161,209,142,245,200,15,156,4,1,161,209,142,245,200,15,158,4,1,161,209,142,245,200,15,159,4,1,161,209,142,245,200,15,147,4,1,161,209,142,245,200,15,164,4,1,161,209,142,245,200,15,149,4,1,161,209,142,245,200,15,163,4,1,161,209,142,245,200,15,162,4,1,161,209,142,245,200,15,160,4,1,161,209,142,245,200,15,161,4,1,161,209,142,245,200,15,166,4,1,161,209,142,245,200,15,171,4,1,161,209,142,245,200,15,170,4,1,161,209,142,245,200,15,168,4,1,161,209,142,245,200,15,169,4,1,161,209,142,245,200,15,172,4,1,161,209,142,245,200,15,176,4,1,161,209,142,245,200,15,174,4,1,161,209,142,245,200,15,175,4,1,161,209,142,245,200,15,173,4,1,161,209,142,245,200,15,177,4,1,168,209,142,245,200,15,165,4,1,119,10,67,114,101,97,116,101,100,32,97,116,161,209,142,245,200,15,182,4,1,168,209,142,245,200,15,167,4,1,122,0,0,0,0,0,0,0,9,161,209,142,245,200,15,181,4,1,161,209,142,245,200,15,180,4,1,161,209,142,245,200,15,178,4,1,161,209,142,245,200,15,179,4,1,161,209,142,245,200,15,184,4,1,161,209,142,245,200,15,186,4,1,161,209,142,245,200,15,189,4,1,161,209,142,245,200,15,188,4,1,161,209,142,245,200,15,187,4,1,168,209,142,245,200,15,190,4,1,122,0,0,0,0,102,67,41,222,168,209,142,245,200,15,192,4,1,122,0,0,0,0,0,0,0,4,168,209,142,245,200,15,191,4,1,121,168,209,142,245,200,15,194,4,1,122,0,0,0,0,0,0,0,0,168,209,142,245,200,15,193,4,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,219,3,1,136,209,142,245,200,15,220,3,1,118,1,2,105,100,119,6,120,69,81,65,111,75,39,0,187,163,190,240,15,11,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,202,4,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,223,3,1,136,209,142,245,200,15,224,3,1,118,1,2,105,100,119,6,120,69,81,65,111,75,39,0,137,227,133,241,2,92,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,206,4,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,227,3,1,136,209,142,245,200,15,228,3,1,118,1,2,105,100,119,6,120,69,81,65,111,75,39,0,168,211,203,155,8,18,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,210,4,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,231,3,1,136,209,142,245,200,15,232,3,1,118,1,2,105,100,119,6,120,69,81,65,111,75,39,0,137,227,133,241,2,43,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,214,4,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,235,3,1,136,209,142,245,200,15,236,3,1,118,1,2,105,100,119,6,120,69,81,65,111,75,39,0,137,227,133,241,2,133,1,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,218,4,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,239,3,1,136,209,142,245,200,15,240,3,1,118,1,2,105,100,119,6,120,69,81,65,111,75,39,0,187,163,190,240,15,52,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,222,4,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,137,227,133,241,2,2,6,120,69,81,65,111,75,1,40,0,209,142,245,200,15,224,4,2,105,100,1,119,6,120,69,81,65,111,75,40,0,209,142,245,200,15,224,4,4,110,97,109,101,1,119,9,67,104,101,99,107,108,105,115,116,40,0,209,142,245,200,15,224,4,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,49,249,40,0,209,142,245,200,15,224,4,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,67,49,249,40,0,209,142,245,200,15,224,4,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,209,142,245,200,15,224,4,2,116,121,1,122,0,0,0,0,0,0,0,7,39,0,209,142,245,200,15,224,4,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,209,142,245,200,15,231,4,1,55,1,161,227,250,198,245,13,0,1,1,0,137,227,133,241,2,58,1,0,3,161,209,142,245,200,15,233,4,1,129,209,142,245,200,15,234,4,1,0,3,161,209,142,245,200,15,238,4,1,0,3,161,209,142,245,200,15,243,4,1,0,3,161,209,142,245,200,15,247,4,3,129,209,142,245,200,15,239,4,1,0,3,161,209,142,245,200,15,253,4,1,129,209,142,245,200,15,254,4,1,0,3,161,209,142,245,200,15,130,5,1,129,209,142,245,200,15,131,5,1,0,3,161,209,142,245,200,15,135,5,4,129,209,142,245,200,15,136,5,1,0,3,161,146,198,138,224,6,15,1,136,182,201,218,189,1,5,1,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,161,209,142,245,200,15,204,4,1,136,182,201,218,189,1,11,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,161,209,142,245,200,15,208,4,1,136,182,201,218,189,1,9,1,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,161,209,142,245,200,15,143,5,1,136,182,201,218,189,1,7,1,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,161,209,142,245,200,15,216,4,1,136,182,201,218,189,1,3,1,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,161,209,142,245,200,15,220,4,1,136,182,201,218,189,1,1,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,161,209,142,245,200,15,154,5,1,161,177,178,255,174,1,12,1,161,177,178,255,174,1,11,1,161,177,178,255,174,1,14,1,161,177,178,255,174,1,13,1,161,209,142,245,200,15,160,5,1,161,177,178,255,174,1,24,1,161,177,178,255,174,1,23,1,161,177,178,255,174,1,25,1,161,177,178,255,174,1,22,1,161,209,142,245,200,15,165,5,1,168,227,250,198,245,13,2,1,119,6,89,80,102,105,50,109,168,227,250,198,245,13,3,1,119,1,56,168,227,250,198,245,13,4,1,119,6,80,78,49,51,122,82,168,227,250,198,245,13,1,1,122,0,0,0,0,0,0,0,5,161,209,142,245,200,15,170,5,1,168,177,178,255,174,1,34,1,119,6,117,106,117,122,75,103,168,177,178,255,174,1,37,1,119,1,54,168,177,178,255,174,1,35,1,122,0,0,0,0,0,0,0,7,168,177,178,255,174,1,36,1,119,6,115,111,118,85,116,69,161,209,142,245,200,15,175,5,3,25,252,220,241,227,14,0,161,227,250,198,245,13,0,1,1,0,137,227,133,241,2,58,1,0,3,161,252,220,241,227,14,0,1,129,252,220,241,227,14,1,1,0,3,161,252,220,241,227,14,5,3,129,252,220,241,227,14,6,1,0,3,161,252,220,241,227,14,12,1,129,252,220,241,227,14,13,1,0,3,161,252,220,241,227,14,17,1,1,0,137,227,133,241,2,56,1,0,6,161,252,220,241,227,14,22,1,129,252,220,241,227,14,23,1,0,6,129,252,220,241,227,14,31,1,0,6,161,252,220,241,227,14,30,1,129,252,220,241,227,14,38,1,0,6,129,252,220,241,227,14,46,1,0,6,1,252,240,184,224,14,0,161,246,154,200,238,10,10,24,1,227,170,238,211,14,0,161,135,173,169,205,15,3,16,1,141,132,223,206,14,0,161,132,238,182,192,14,4,5,1,132,238,182,192,14,0,161,203,248,208,163,4,3,5,5,188,252,160,180,14,0,161,185,145,225,175,8,235,2,1,135,209,142,245,200,15,144,5,1,40,0,188,252,160,180,14,1,8,102,105,101,108,100,95,105,100,1,119,6,89,53,52,81,73,115,40,0,188,252,160,180,14,1,9,99,111,110,100,105,116,105,111,110,1,122,0,0,0,0,0,0,0,0,40,0,188,252,160,180,14,1,2,105,100,1,119,8,115,58,104,97,52,74,106,113,1,175,150,167,163,14,0,161,247,187,192,242,6,5,4,2,142,215,187,158,14,0,161,149,154,146,112,15,6,161,142,215,187,158,14,5,4,1,192,183,207,147,14,0,161,182,139,168,140,5,35,43,5,227,250,198,245,13,0,161,146,198,138,224,6,14,1,161,177,178,255,174,1,29,1,161,177,178,255,174,1,31,1,161,177,178,255,174,1,30,1,161,177,178,255,174,1,28,1,49,178,161,242,226,13,0,161,171,216,132,162,10,92,1,129,185,145,225,175,8,150,3,1,0,6,129,178,161,242,226,13,1,1,0,6,129,178,161,242,226,13,8,1,0,6,129,178,161,242,226,13,15,1,0,6,129,178,161,242,226,13,22,1,0,6,129,178,161,242,226,13,29,1,0,6,161,178,161,242,226,13,0,1,129,178,161,242,226,13,36,1,0,6,129,178,161,242,226,13,44,1,0,6,129,178,161,242,226,13,51,1,0,6,129,178,161,242,226,13,58,1,0,6,129,178,161,242,226,13,65,1,0,6,161,178,161,242,226,13,43,1,129,178,161,242,226,13,72,1,0,6,129,178,161,242,226,13,80,1,0,6,129,178,161,242,226,13,87,1,0,6,129,178,161,242,226,13,94,1,0,6,161,178,161,242,226,13,79,1,129,178,161,242,226,13,101,1,0,6,129,178,161,242,226,13,109,1,0,6,129,178,161,242,226,13,116,1,0,6,161,178,161,242,226,13,108,1,129,178,161,242,226,13,123,1,0,6,129,178,161,242,226,13,131,1,1,0,6,161,178,161,242,226,13,130,1,1,129,178,161,242,226,13,138,1,1,0,6,168,178,161,242,226,13,145,1,1,122,0,0,0,0,102,77,81,51,1,154,253,168,186,13,0,161,162,129,240,225,15,18,6,1,191,215,204,166,13,0,161,210,221,238,195,8,19,12,2,180,149,168,150,13,0,161,165,237,195,173,1,7,1,161,142,215,187,158,14,9,9,1,206,242,242,141,13,0,161,180,132,165,192,8,0,95,1,201,191,253,157,12,0,161,187,159,219,213,8,1,2,1,253,223,254,206,11,0,161,174,158,229,225,9,1,2,1,174,182,200,164,11,0,161,210,221,238,195,8,19,2,1,246,154,200,238,10,0,161,192,183,207,147,14,42,11,1,160,159,229,236,10,0,161,193,174,143,180,7,17,34,1,224,218,133,236,10,0,161,247,149,251,192,4,3,13,76,171,216,132,162,10,0,39,0,137,227,133,241,2,3,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,1,40,0,171,216,132,162,10,0,2,105,100,1,119,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,40,0,171,216,132,162,10,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,171,216,132,162,10,0,4,110,97,109,101,1,119,14,66,111,97,114,100,32,99,104,101,99,107,98,111,120,40,0,171,216,132,162,10,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,33,0,171,216,132,162,10,0,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,171,216,132,162,10,0,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,171,216,132,162,10,6,1,49,1,40,0,171,216,132,162,10,7,22,99,111,108,108,97,112,115,101,95,104,105,100,100,101,110,95,103,114,111,117,112,115,1,121,40,0,171,216,132,162,10,7,21,104,105,100,101,95,117,110,103,114,111,117,112,101,100,95,99,111,108,117,109,110,1,121,40,0,171,216,132,162,10,0,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,39,0,171,216,132,162,10,0,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,171,216,132,162,10,0,7,102,105,108,116,101,114,115,0,39,0,171,216,132,162,10,0,6,103,114,111,117,112,115,0,39,0,171,216,132,162,10,0,5,115,111,114,116,115,0,39,0,171,216,132,162,10,0,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,171,216,132,162,10,15,12,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,118,1,2,105,100,119,6,115,111,118,85,116,69,118,1,2,105,100,119,6,54,76,70,72,66,54,118,1,2,105,100,119,6,86,89,52,50,103,49,118,1,2,105,100,119,6,106,87,101,95,116,54,118,1,2,105,100,119,6,55,75,88,95,99,120,118,1,2,105,100,119,6,76,99,121,68,75,106,118,1,2,105,100,119,6,120,69,81,65,111,75,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,171,216,132,162,10,0,10,114,111,119,95,111,114,100,101,114,115,0,8,0,171,216,132,162,10,28,8,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,118,2,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,161,171,216,132,162,10,5,1,7,0,171,216,132,162,10,13,1,33,0,171,216,132,162,10,38,6,103,114,111,117,112,115,1,33,0,171,216,132,162,10,38,2,116,121,1,33,0,171,216,132,162,10,38,7,99,111,110,116,101,110,116,1,33,0,171,216,132,162,10,38,8,102,105,101,108,100,95,105,100,1,33,0,171,216,132,162,10,38,2,105,100,1,161,171,216,132,162,10,37,1,168,171,216,132,162,10,41,1,119,0,167,171,216,132,162,10,39,0,8,0,171,216,132,162,10,46,4,118,2,2,105,100,119,6,70,114,115,115,74,100,7,118,105,115,105,98,108,101,120,118,2,2,105,100,119,4,120,90,48,51,7,118,105,115,105,98,108,101,120,118,2,2,105,100,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,7,118,105,115,105,98,108,101,120,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,36,54,49,50,100,50,99,51,98,45,56,50,98,99,45,52,55,51,98,45,98,49,52,53,45,55,102,53,55,49,56,54,101,51,102,55,101,168,171,216,132,162,10,40,1,122,0,0,0,0,0,0,0,3,168,171,216,132,162,10,42,1,119,6,70,114,115,115,74,100,168,171,216,132,162,10,43,1,119,8,103,58,102,104,55,54,48,95,161,185,145,225,175,8,189,2,1,136,209,142,245,200,15,151,5,1,118,2,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,6,104,101,105,103,104,116,125,60,161,185,145,225,175,8,233,2,1,136,209,142,245,200,15,149,5,1,118,2,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,6,104,101,105,103,104,116,125,60,161,171,216,132,162,10,44,1,136,171,216,132,162,10,36,1,118,2,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,6,104,101,105,103,104,116,125,60,161,188,252,160,180,14,0,1,136,209,142,245,200,15,155,5,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,161,185,145,225,175,8,234,2,1,136,209,142,245,200,15,159,5,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,161,185,145,225,175,8,197,2,1,136,209,142,245,200,15,157,5,1,118,2,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,6,104,101,105,103,104,116,125,60,161,185,145,225,175,8,181,2,1,136,209,142,245,200,15,153,5,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,161,171,216,132,162,10,60,1,161,209,142,245,200,15,167,5,1,161,209,142,245,200,15,169,5,1,161,209,142,245,200,15,166,5,1,161,209,142,245,200,15,168,5,1,168,171,216,132,162,10,54,1,122,0,0,0,0,102,75,60,209,136,171,216,132,162,10,55,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,168,171,216,132,162,10,56,1,122,0,0,0,0,102,75,60,209,136,171,216,132,162,10,57,1,118,2,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,6,104,101,105,103,104,116,125,60,168,171,216,132,162,10,58,1,122,0,0,0,0,102,75,60,209,136,171,216,132,162,10,59,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,161,171,216,132,162,10,68,1,136,171,216,132,162,10,61,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,168,171,216,132,162,10,62,1,122,0,0,0,0,102,75,60,209,136,171,216,132,162,10,63,1,118,2,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,6,104,101,105,103,104,116,125,60,168,171,216,132,162,10,64,1,122,0,0,0,0,102,75,60,209,136,171,216,132,162,10,65,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,168,171,216,132,162,10,66,1,122,0,0,0,0,102,75,60,209,136,171,216,132,162,10,67,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,161,171,216,132,162,10,79,1,168,171,216,132,162,10,70,1,119,1,57,168,171,216,132,162,10,72,1,119,6,70,114,115,115,74,100,168,171,216,132,162,10,71,1,122,0,0,0,0,0,0,0,7,168,171,216,132,162,10,69,1,119,6,67,101,97,68,98,122,161,171,216,132,162,10,87,1,168,209,142,245,200,15,161,5,1,119,6,121,81,77,51,67,56,168,209,142,245,200,15,164,5,1,119,6,89,53,52,81,73,115,168,209,142,245,200,15,163,5,1,119,2,49,48,168,209,142,245,200,15,162,5,1,122,0,0,0,0,0,0,0,5,1,174,158,229,225,9,0,161,227,170,238,211,14,15,2,1,200,156,140,203,9,0,161,250,147,239,143,1,1,2,1,219,179,165,244,8,0,161,140,242,215,248,4,34,4,1,187,159,219,213,8,0,161,200,168,240,223,7,1,2,1,210,221,238,195,8,0,161,211,235,145,81,15,20,1,180,132,165,192,8,0,161,211,189,178,91,79,1,163,1,185,145,225,175,8,0,161,252,220,241,227,14,45,1,129,252,220,241,227,14,53,1,0,6,129,185,145,225,175,8,1,1,0,6,129,185,145,225,175,8,8,1,0,6,161,185,145,225,175,8,0,1,129,185,145,225,175,8,15,1,0,6,129,185,145,225,175,8,23,1,0,6,129,185,145,225,175,8,30,1,0,6,129,185,145,225,175,8,37,1,0,6,161,185,145,225,175,8,22,1,129,185,145,225,175,8,44,1,0,6,129,185,145,225,175,8,52,1,0,6,129,185,145,225,175,8,59,1,0,6,129,185,145,225,175,8,66,1,0,6,129,185,145,225,175,8,73,1,0,6,161,185,145,225,175,8,51,1,129,185,145,225,175,8,80,1,0,6,129,185,145,225,175,8,88,1,0,6,129,185,145,225,175,8,95,1,0,6,129,185,145,225,175,8,102,1,0,6,129,185,145,225,175,8,109,1,0,6,129,185,145,225,175,8,116,1,0,6,161,209,142,245,200,15,182,5,1,129,185,145,225,175,8,123,1,0,6,129,185,145,225,175,8,131,1,1,0,6,129,185,145,225,175,8,138,1,1,0,6,129,185,145,225,175,8,145,1,1,0,6,129,185,145,225,175,8,152,1,1,0,6,129,185,145,225,175,8,159,1,1,0,6,161,185,145,225,175,8,130,1,1,129,185,145,225,175,8,166,1,1,0,6,129,185,145,225,175,8,174,1,1,0,6,129,185,145,225,175,8,181,1,1,0,6,129,185,145,225,175,8,188,1,1,0,6,129,185,145,225,175,8,195,1,1,0,6,129,185,145,225,175,8,202,1,1,0,6,161,185,145,225,175,8,173,1,1,129,185,145,225,175,8,209,1,1,0,6,129,185,145,225,175,8,217,1,1,0,6,129,185,145,225,175,8,224,1,1,0,6,129,185,145,225,175,8,231,1,1,0,6,129,185,145,225,175,8,238,1,1,0,6,129,185,145,225,175,8,245,1,1,0,6,161,185,145,225,175,8,216,1,1,129,185,145,225,175,8,252,1,1,0,6,129,185,145,225,175,8,132,2,1,0,6,129,185,145,225,175,8,139,2,1,0,6,129,185,145,225,175,8,146,2,1,0,6,129,185,145,225,175,8,153,2,1,0,6,129,185,145,225,175,8,160,2,1,0,6,129,185,145,225,175,8,167,2,1,0,6,161,209,142,245,200,15,152,5,1,136,209,142,245,200,15,209,4,1,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,168,211,203,155,8,18,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,183,2,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,185,145,225,175,8,131,2,1,136,209,142,245,200,15,213,4,1,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,137,227,133,241,2,43,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,187,2,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,209,142,245,200,15,150,5,1,136,209,142,245,200,15,205,4,1,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,137,227,133,241,2,92,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,191,2,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,148,5,1,136,209,142,245,200,15,201,4,1,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,187,163,190,240,15,11,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,195,2,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,156,5,1,136,209,142,245,200,15,217,4,1,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,137,227,133,241,2,133,1,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,199,2,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,209,142,245,200,15,158,5,1,136,209,142,245,200,15,221,4,1,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,187,163,190,240,15,52,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,203,2,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,137,227,133,241,2,2,6,52,57,85,69,86,53,1,40,0,185,145,225,175,8,205,2,2,105,100,1,119,6,52,57,85,69,86,53,33,0,185,145,225,175,8,205,2,4,110,97,109,101,1,40,0,185,145,225,175,8,205,2,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,69,129,177,33,0,185,145,225,175,8,205,2,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,185,145,225,175,8,205,2,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,185,145,225,175,8,205,2,2,116,121,1,39,0,185,145,225,175,8,205,2,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,185,145,225,175,8,212,2,1,48,1,40,0,185,145,225,175,8,213,2,4,100,97,116,97,1,119,0,161,185,145,225,175,8,209,2,1,161,185,145,225,175,8,207,2,1,161,185,145,225,175,8,215,2,1,161,185,145,225,175,8,216,2,1,161,185,145,225,175,8,217,2,1,161,185,145,225,175,8,218,2,1,161,185,145,225,175,8,219,2,1,168,185,145,225,175,8,220,2,1,119,4,116,105,109,101,161,185,145,225,175,8,221,2,1,168,185,145,225,175,8,211,2,1,122,0,0,0,0,0,0,0,2,39,0,185,145,225,175,8,212,2,1,50,1,40,0,185,145,225,175,8,225,2,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,185,145,225,175,8,225,2,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,40,0,185,145,225,175,8,225,2,11,116,105,109,101,122,111,110,101,95,105,100,1,119,0,168,185,145,225,175,8,223,2,1,122,0,0,0,0,102,69,129,187,40,0,185,145,225,175,8,213,2,11,116,105,109,101,122,111,110,101,95,105,100,1,119,0,40,0,185,145,225,175,8,213,2,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,40,0,185,145,225,175,8,213,2,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,161,185,145,225,175,8,193,2,1,161,185,145,225,175,8,201,2,1,161,185,145,225,175,8,185,2,1,129,185,145,225,175,8,174,2,1,0,6,129,185,145,225,175,8,236,2,1,0,6,129,185,145,225,175,8,243,2,1,0,6,129,185,145,225,175,8,250,2,1,0,6,129,185,145,225,175,8,129,3,1,0,6,129,185,145,225,175,8,136,3,1,0,6,129,185,145,225,175,8,143,3,1,0,6,81,168,211,203,155,8,0,161,137,227,133,241,2,20,1,161,137,227,133,241,2,25,1,161,137,227,133,241,2,150,1,1,168,137,227,133,241,2,115,1,119,6,70,114,115,115,74,100,168,137,227,133,241,2,113,1,119,8,103,58,107,56,113,69,117,118,168,137,227,133,241,2,116,1,122,0,0,0,0,0,0,0,3,168,137,227,133,241,2,114,1,119,0,167,137,227,133,241,2,117,0,8,0,168,211,203,155,8,7,2,118,2,2,105,100,119,6,70,114,115,115,74,100,7,118,105,115,105,98,108,101,120,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,4,120,90,48,51,39,0,137,227,133,241,2,3,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,1,40,0,168,211,203,155,8,10,2,105,100,1,119,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,40,0,168,211,203,155,8,10,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,168,211,203,155,8,10,4,110,97,109,101,1,119,4,71,114,105,100,40,0,168,211,203,155,8,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,178,5,33,0,168,211,203,155,8,10,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,168,211,203,155,8,10,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,40,0,168,211,203,155,8,10,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,39,0,168,211,203,155,8,10,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,168,211,203,155,8,10,7,102,105,108,116,101,114,115,0,39,0,168,211,203,155,8,10,6,103,114,111,117,112,115,0,39,0,168,211,203,155,8,10,5,115,111,114,116,115,0,39,0,168,211,203,155,8,10,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,168,211,203,155,8,22,5,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,118,1,2,105,100,119,6,115,111,118,85,116,69,39,0,168,211,203,155,8,10,10,114,111,119,95,111,114,100,101,114,115,0,8,0,168,211,203,155,8,28,3,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,161,137,227,133,241,2,154,1,1,40,0,137,227,133,241,2,69,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,40,0,137,227,133,241,2,69,4,119,114,97,112,1,121,168,137,227,133,241,2,70,1,122,0,0,0,0,0,0,0,2,161,168,211,203,155,8,2,1,136,137,227,133,241,2,151,1,1,118,1,2,105,100,119,6,54,76,70,72,66,54,39,0,137,227,133,241,2,92,6,54,76,70,72,66,54,1,40,0,168,211,203,155,8,38,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,137,227,133,241,2,146,1,1,136,137,227,133,241,2,147,1,1,118,1,2,105,100,119,6,54,76,70,72,66,54,39,0,137,227,133,241,2,133,1,6,54,76,70,72,66,54,1,40,0,168,211,203,155,8,42,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,168,211,203,155,8,15,1,136,168,211,203,155,8,27,1,118,1,2,105,100,119,6,54,76,70,72,66,54,39,0,168,211,203,155,8,18,6,54,76,70,72,66,54,1,40,0,168,211,203,155,8,46,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,168,211,203,155,8,32,1,136,137,227,133,241,2,155,1,1,118,1,2,105,100,119,6,54,76,70,72,66,54,39,0,137,227,133,241,2,43,6,54,76,70,72,66,54,1,40,0,168,211,203,155,8,50,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,2,6,54,76,70,72,66,54,1,40,0,168,211,203,155,8,52,2,105,100,1,119,6,54,76,70,72,66,54,33,0,168,211,203,155,8,52,4,110,97,109,101,1,40,0,168,211,203,155,8,52,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,230,211,33,0,168,211,203,155,8,52,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,168,211,203,155,8,52,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,168,211,203,155,8,52,2,116,121,1,39,0,168,211,203,155,8,52,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,168,211,203,155,8,59,1,48,1,40,0,168,211,203,155,8,60,4,100,97,116,97,1,119,0,161,168,211,203,155,8,36,1,136,168,211,203,155,8,37,1,118,1,2,105,100,119,6,86,89,52,50,103,49,39,0,137,227,133,241,2,92,6,86,89,52,50,103,49,1,40,0,168,211,203,155,8,64,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,168,211,203,155,8,40,1,136,168,211,203,155,8,41,1,118,1,2,105,100,119,6,86,89,52,50,103,49,39,0,137,227,133,241,2,133,1,6,86,89,52,50,103,49,1,40,0,168,211,203,155,8,68,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,168,211,203,155,8,44,1,136,168,211,203,155,8,45,1,118,1,2,105,100,119,6,86,89,52,50,103,49,39,0,168,211,203,155,8,18,6,86,89,52,50,103,49,1,40,0,168,211,203,155,8,72,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,168,211,203,155,8,48,1,136,168,211,203,155,8,49,1,118,1,2,105,100,119,6,86,89,52,50,103,49,39,0,137,227,133,241,2,43,6,86,89,52,50,103,49,1,40,0,168,211,203,155,8,76,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,2,6,86,89,52,50,103,49,1,40,0,168,211,203,155,8,78,2,105,100,1,119,6,86,89,52,50,103,49,33,0,168,211,203,155,8,78,4,110,97,109,101,1,40,0,168,211,203,155,8,78,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,230,213,33,0,168,211,203,155,8,78,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,168,211,203,155,8,78,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,168,211,203,155,8,78,2,116,121,1,39,0,168,211,203,155,8,78,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,168,211,203,155,8,85,1,48,1,40,0,168,211,203,155,8,86,4,100,97,116,97,1,119,0,1,150,194,135,131,8,0,161,206,242,242,141,13,94,12,1,200,168,240,223,7,0,161,180,149,168,150,13,9,2,1,216,247,253,206,7,0,161,141,132,223,206,14,4,2,1,193,174,143,180,7,0,161,150,194,135,131,8,11,18,1,202,170,215,178,7,0,161,191,215,204,166,13,11,24,1,157,197,217,249,6,0,161,224,218,133,236,10,12,3,1,247,187,192,242,6,0,161,134,200,133,143,5,1,6,1,248,220,249,231,6,0,161,200,156,140,203,9,1,29,18,146,198,138,224,6,0,161,137,227,133,241,2,162,1,1,161,137,227,133,241,2,169,1,1,161,137,227,133,241,2,168,1,1,161,137,227,133,241,2,167,1,1,161,146,198,138,224,6,0,1,168,146,198,138,224,6,2,1,122,0,0,0,0,0,0,0,1,168,146,198,138,224,6,1,1,122,0,0,0,0,0,0,0,3,168,146,198,138,224,6,3,1,119,0,161,187,163,190,240,15,81,1,168,187,163,190,240,15,83,1,122,0,0,0,0,0,0,0,10,39,0,187,163,190,240,15,84,2,49,48,1,33,0,146,198,138,224,6,10,11,100,97,116,97,98,97,115,101,95,105,100,1,161,146,198,138,224,6,8,1,40,0,187,163,190,240,15,85,11,100,97,116,97,98,97,115,101,95,105,100,1,119,0,161,234,232,155,212,3,0,1,161,177,178,255,174,1,0,1,168,146,198,138,224,6,12,1,122,0,0,0,0,102,67,52,219,168,146,198,138,224,6,11,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,1,158,173,179,170,6,0,161,183,238,200,180,5,5,81,1,183,238,200,180,5,0,161,160,159,229,236,10,33,6,2,174,250,146,158,5,0,161,216,247,253,206,7,1,1,168,174,250,146,158,5,0,1,122,0,0,0,0,102,88,107,140,1,134,200,133,143,5,0,161,201,191,253,157,12,1,2,1,182,139,168,140,5,0,161,253,223,254,206,11,1,36,1,140,242,215,248,4,0,161,157,197,217,249,6,2,35,2,186,204,138,236,4,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,112,161,186,204,138,236,4,111,6,1,247,149,251,192,4,0,161,248,220,249,231,6,28,4,1,203,248,208,163,4,0,161,202,170,215,178,7,23,4,1,128,137,148,150,4,0,161,154,253,168,186,13,5,39,4,234,232,155,212,3,0,161,177,178,255,174,1,32,1,168,137,227,133,241,2,54,1,122,0,0,0,0,0,0,0,150,168,137,227,133,241,2,55,1,120,168,137,227,133,241,2,53,1,122,0,0,0,0,0,0,0,0,156,1,137,227,133,241,2,0,39,1,4,100,97,116,97,8,100,97,116,97,98,97,115,101,1,40,0,137,227,133,241,2,0,2,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,39,0,137,227,133,241,2,0,6,102,105,101,108,100,115,1,39,0,137,227,133,241,2,0,5,118,105,101,119,115,1,39,0,137,227,133,241,2,0,5,109,101,116,97,115,1,40,0,137,227,133,241,2,4,3,105,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,39,0,137,227,133,241,2,2,6,89,53,52,81,73,115,1,40,0,137,227,133,241,2,6,2,105,100,1,119,6,89,53,52,81,73,115,40,0,137,227,133,241,2,6,4,110,97,109,101,1,119,4,78,97,109,101,40,0,137,227,133,241,2,6,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,40,0,137,227,133,241,2,6,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,48,108,138,40,0,137,227,133,241,2,6,10,105,115,95,112,114,105,109,97,114,121,1,120,40,0,137,227,133,241,2,6,2,116,121,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,6,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,137,227,133,241,2,13,1,48,1,40,0,137,227,133,241,2,14,4,100,97,116,97,1,119,0,39,0,137,227,133,241,2,2,6,70,114,115,115,74,100,1,40,0,137,227,133,241,2,16,2,105,100,1,119,6,70,114,115,115,74,100,33,0,137,227,133,241,2,16,4,110,97,109,101,1,40,0,137,227,133,241,2,16,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,33,0,137,227,133,241,2,16,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,137,227,133,241,2,16,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,137,227,133,241,2,16,2,116,121,1,39,0,137,227,133,241,2,16,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,137,227,133,241,2,23,1,51,1,33,0,137,227,133,241,2,24,7,99,111,110,116,101,110,116,1,39,0,137,227,133,241,2,2,6,89,80,102,105,50,109,1,40,0,137,227,133,241,2,26,2,105,100,1,119,6,89,80,102,105,50,109,40,0,137,227,133,241,2,26,4,110,97,109,101,1,119,4,68,111,110,101,40,0,137,227,133,241,2,26,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,40,0,137,227,133,241,2,26,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,48,108,138,40,0,137,227,133,241,2,26,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,137,227,133,241,2,26,2,116,121,1,122,0,0,0,0,0,0,0,5,39,0,137,227,133,241,2,26,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,137,227,133,241,2,33,1,53,1,39,0,137,227,133,241,2,3,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,1,40,0,137,227,133,241,2,35,2,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,137,227,133,241,2,35,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,137,227,133,241,2,35,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,137,227,133,241,2,35,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,33,0,137,227,133,241,2,35,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,137,227,133,241,2,35,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,40,0,137,227,133,241,2,35,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,35,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,137,227,133,241,2,43,6,70,114,115,115,74,100,1,40,0,137,227,133,241,2,44,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,40,0,137,227,133,241,2,44,4,119,114,97,112,1,121,40,0,137,227,133,241,2,44,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,39,0,137,227,133,241,2,43,6,89,80,102,105,50,109,1,40,0,137,227,133,241,2,48,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,40,0,137,227,133,241,2,48,4,119,114,97,112,1,121,40,0,137,227,133,241,2,48,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,43,6,89,53,52,81,73,115,1,33,0,137,227,133,241,2,52,10,118,105,115,105,98,105,108,105,116,121,1,33,0,137,227,133,241,2,52,5,119,105,100,116,104,1,33,0,137,227,133,241,2,52,4,119,114,97,112,1,39,0,137,227,133,241,2,35,7,102,105,108,116,101,114,115,0,39,0,137,227,133,241,2,35,6,103,114,111,117,112,115,0,39,0,137,227,133,241,2,35,5,115,111,114,116,115,0,39,0,137,227,133,241,2,35,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,137,227,133,241,2,59,3,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,39,0,137,227,133,241,2,35,10,114,111,119,95,111,114,100,101,114,115,0,8,0,137,227,133,241,2,63,3,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,118,2,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,161,137,227,133,241,2,40,1,136,137,227,133,241,2,62,1,118,1,2,105,100,119,6,84,102,117,121,104,84,39,0,137,227,133,241,2,43,6,84,102,117,121,104,84,1,33,0,137,227,133,241,2,69,10,118,105,115,105,98,105,108,105,116,121,1,39,0,137,227,133,241,2,2,6,84,102,117,121,104,84,1,40,0,137,227,133,241,2,71,2,105,100,1,119,6,84,102,117,121,104,84,40,0,137,227,133,241,2,71,4,110,97,109,101,1,119,4,84,101,120,116,40,0,137,227,133,241,2,71,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,111,178,40,0,137,227,133,241,2,71,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,48,111,178,40,0,137,227,133,241,2,71,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,137,227,133,241,2,71,2,116,121,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,71,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,137,227,133,241,2,78,1,48,1,40,0,137,227,133,241,2,79,4,100,97,116,97,1,119,0,39,0,137,227,133,241,2,3,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,1,40,0,137,227,133,241,2,81,2,105,100,1,119,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,40,0,137,227,133,241,2,81,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,137,227,133,241,2,81,4,110,97,109,101,1,119,5,66,111,97,114,100,40,0,137,227,133,241,2,81,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,177,159,33,0,137,227,133,241,2,81,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,137,227,133,241,2,81,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,137,227,133,241,2,87,1,49,1,40,0,137,227,133,241,2,88,21,104,105,100,101,95,117,110,103,114,111,117,112,101,100,95,99,111,108,117,109,110,1,121,40,0,137,227,133,241,2,88,22,99,111,108,108,97,112,115,101,95,104,105,100,100,101,110,95,103,114,111,117,112,115,1,121,40,0,137,227,133,241,2,81,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,39,0,137,227,133,241,2,81,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,137,227,133,241,2,81,7,102,105,108,116,101,114,115,0,39,0,137,227,133,241,2,81,6,103,114,111,117,112,115,0,39,0,137,227,133,241,2,81,5,115,111,114,116,115,0,39,0,137,227,133,241,2,81,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,137,227,133,241,2,96,4,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,39,0,137,227,133,241,2,81,10,114,111,119,95,111,114,100,101,114,115,0,8,0,137,227,133,241,2,101,3,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,161,137,227,133,241,2,86,1,7,0,137,227,133,241,2,94,1,33,0,137,227,133,241,2,106,2,105,100,1,33,0,137,227,133,241,2,106,6,103,114,111,117,112,115,1,33,0,137,227,133,241,2,106,7,99,111,110,116,101,110,116,1,33,0,137,227,133,241,2,106,8,102,105,101,108,100,95,105,100,1,33,0,137,227,133,241,2,106,2,116,121,1,161,137,227,133,241,2,105,1,161,137,227,133,241,2,107,1,161,137,227,133,241,2,109,1,161,137,227,133,241,2,110,1,161,137,227,133,241,2,111,1,161,137,227,133,241,2,108,1,0,1,39,0,137,227,133,241,2,3,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,1,40,0,137,227,133,241,2,119,2,105,100,1,119,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,40,0,137,227,133,241,2,119,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,137,227,133,241,2,119,4,110,97,109,101,1,119,8,67,97,108,101,110,100,97,114,40,0,137,227,133,241,2,119,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,177,162,33,0,137,227,133,241,2,119,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,137,227,133,241,2,119,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,137,227,133,241,2,125,1,50,1,40,0,137,227,133,241,2,126,9,108,97,121,111,117,116,95,116,121,1,122,0,0,0,0,0,0,0,0,40,0,137,227,133,241,2,126,17,102,105,114,115,116,95,100,97,121,95,111,102,95,119,101,101,107,1,122,0,0,0,0,0,0,0,0,40,0,137,227,133,241,2,126,8,102,105,101,108,100,95,105,100,1,119,6,115,111,118,85,116,69,40,0,137,227,133,241,2,126,13,115,104,111,119,95,119,101,101,107,101,110,100,115,1,120,40,0,137,227,133,241,2,126,17,115,104,111,119,95,119,101,101,107,95,110,117,109,98,101,114,115,1,120,40,0,137,227,133,241,2,119,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,39,0,137,227,133,241,2,119,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,137,227,133,241,2,119,7,102,105,108,116,101,114,115,0,39,0,137,227,133,241,2,119,6,103,114,111,117,112,115,0,39,0,137,227,133,241,2,119,5,115,111,114,116,115,0,39,0,137,227,133,241,2,119,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,137,227,133,241,2,137,1,4,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,39,0,137,227,133,241,2,119,10,114,111,119,95,111,114,100,101,114,115,0,8,0,137,227,133,241,2,142,1,3,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,161,137,227,133,241,2,124,1,136,137,227,133,241,2,141,1,1,118,1,2,105,100,119,6,115,111,118,85,116,69,39,0,137,227,133,241,2,133,1,6,115,111,118,85,116,69,1,40,0,137,227,133,241,2,148,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,137,227,133,241,2,112,1,136,137,227,133,241,2,100,1,118,1,2,105,100,119,6,115,111,118,85,116,69,39,0,137,227,133,241,2,92,6,115,111,118,85,116,69,1,40,0,137,227,133,241,2,152,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,137,227,133,241,2,67,1,136,137,227,133,241,2,68,1,118,1,2,105,100,119,6,115,111,118,85,116,69,39,0,137,227,133,241,2,43,6,115,111,118,85,116,69,1,40,0,137,227,133,241,2,156,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,137,227,133,241,2,2,6,115,111,118,85,116,69,1,40,0,137,227,133,241,2,158,1,2,105,100,1,119,6,115,111,118,85,116,69,33,0,137,227,133,241,2,158,1,4,110,97,109,101,1,40,0,137,227,133,241,2,158,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,177,162,33,0,137,227,133,241,2,158,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,137,227,133,241,2,158,1,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,137,227,133,241,2,158,1,2,116,121,1,39,0,137,227,133,241,2,158,1,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,137,227,133,241,2,165,1,1,50,1,33,0,137,227,133,241,2,166,1,11,116,105,109,101,122,111,110,101,95,105,100,1,33,0,137,227,133,241,2,166,1,11,116,105,109,101,95,102,111,114,109,97,116,1,33,0,137,227,133,241,2,166,1,11,100,97,116,101,95,102,111,114,109,97,116,1,71,193,140,213,146,2,0,39,0,137,227,133,241,2,3,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,1,40,0,193,140,213,146,2,0,2,105,100,1,119,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,40,0,193,140,213,146,2,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,193,140,213,146,2,0,4,110,97,109,101,1,119,12,86,105,101,119,32,111,102,32,71,114,105,100,40,0,193,140,213,146,2,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,40,0,193,140,213,146,2,0,11,109,111,100,105,102,105,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,39,0,193,140,213,146,2,0,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,40,0,193,140,213,146,2,0,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,39,0,193,140,213,146,2,0,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,193,140,213,146,2,0,7,102,105,108,116,101,114,115,0,39,0,193,140,213,146,2,0,6,103,114,111,117,112,115,0,39,0,193,140,213,146,2,0,5,115,111,114,116,115,0,39,0,193,140,213,146,2,0,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,193,140,213,146,2,12,12,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,118,1,2,105,100,119,6,115,111,118,85,116,69,118,1,2,105,100,119,6,54,76,70,72,66,54,118,1,2,105,100,119,6,86,89,52,50,103,49,118,1,2,105,100,119,6,106,87,101,95,116,54,118,1,2,105,100,119,6,55,75,88,95,99,120,118,1,2,105,100,119,6,76,99,121,68,75,106,118,1,2,105,100,119,6,120,69,81,65,111,75,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,193,140,213,146,2,0,10,114,111,119,95,111,114,100,101,114,115,0,8,0,193,140,213,146,2,25,10,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,118,2,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,118,2,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,6,104,101,105,103,104,116,125,60,39,0,137,227,133,241,2,3,36,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,1,40,0,193,140,213,146,2,36,2,105,100,1,119,36,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,40,0,193,140,213,146,2,36,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,193,140,213,146,2,36,4,110,97,109,101,1,119,22,86,105,101,119,32,111,102,32,66,111,97,114,100,32,99,104,101,99,107,98,111,120,40,0,193,140,213,146,2,36,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,33,0,193,140,213,146,2,36,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,193,140,213,146,2,36,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,193,140,213,146,2,42,1,49,1,40,0,193,140,213,146,2,43,21,104,105,100,101,95,117,110,103,114,111,117,112,101,100,95,99,111,108,117,109,110,1,121,40,0,193,140,213,146,2,43,22,99,111,108,108,97,112,115,101,95,104,105,100,100,101,110,95,103,114,111,117,112,115,1,121,40,0,193,140,213,146,2,36,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,39,0,193,140,213,146,2,36,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,193,140,213,146,2,36,7,102,105,108,116,101,114,115,0,39,0,193,140,213,146,2,36,6,103,114,111,117,112,115,0,39,0,193,140,213,146,2,36,5,115,111,114,116,115,0,39,0,193,140,213,146,2,36,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,193,140,213,146,2,51,12,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,118,1,2,105,100,119,6,115,111,118,85,116,69,118,1,2,105,100,119,6,54,76,70,72,66,54,118,1,2,105,100,119,6,86,89,52,50,103,49,118,1,2,105,100,119,6,106,87,101,95,116,54,118,1,2,105,100,119,6,55,75,88,95,99,120,118,1,2,105,100,119,6,76,99,121,68,75,106,118,1,2,105,100,119,6,120,69,81,65,111,75,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,193,140,213,146,2,36,10,114,111,119,95,111,114,100,101,114,115,0,8,0,193,140,213,146,2,64,10,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,118,2,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,161,193,140,213,146,2,41,1,7,0,193,140,213,146,2,49,1,33,0,193,140,213,146,2,76,6,103,114,111,117,112,115,1,33,0,193,140,213,146,2,76,2,116,121,1,33,0,193,140,213,146,2,76,8,102,105,101,108,100,95,105,100,1,33,0,193,140,213,146,2,76,2,105,100,1,33,0,193,140,213,146,2,76,7,99,111,110,116,101,110,116,1,168,193,140,213,146,2,75,1,122,0,0,0,0,102,79,7,25,168,193,140,213,146,2,79,1,119,6,70,114,115,115,74,100,168,193,140,213,146,2,78,1,122,0,0,0,0,0,0,0,3,168,193,140,213,146,2,80,1,119,8,103,58,105,88,95,87,48,73,167,193,140,213,146,2,77,0,8,0,193,140,213,146,2,86,4,118,2,2,105,100,119,6,70,114,115,115,74,100,7,118,105,115,105,98,108,101,120,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,4,120,90,48,51,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,36,54,49,50,100,50,99,51,98,45,56,50,98,99,45,52,55,51,98,45,98,49,52,53,45,55,102,53,55,49,56,54,101,51,102,55,101,168,193,140,213,146,2,81,1,119,0,39,0,137,227,133,241,2,3,36,97,54,97,102,51,49,49,102,45,99,98,99,56,45,52,50,99,50,45,98,56,48,49,45,55,49,49,53,54,49,57,99,51,55,55,54,1,40,0,193,140,213,146,2,92,2,105,100,1,119,36,97,54,97,102,51,49,49,102,45,99,98,99,56,45,52,50,99,50,45,98,56,48,49,45,55,49,49,53,54,49,57,99,51,55,55,54,40,0,193,140,213,146,2,92,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,193,140,213,146,2,92,4,110,97,109,101,1,119,16,86,105,101,119,32,111,102,32,67,97,108,101,110,100,97,114,40,0,193,140,213,146,2,92,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,40,0,193,140,213,146,2,92,11,109,111,100,105,102,105,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,39,0,193,140,213,146,2,92,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,193,140,213,146,2,98,1,50,1,40,0,193,140,213,146,2,99,17,102,105,114,115,116,95,100,97,121,95,111,102,95,119,101,101,107,1,122,0,0,0,0,0,0,0,0,40,0,193,140,213,146,2,99,8,102,105,101,108,100,95,105,100,1,119,6,52,57,85,69,86,53,40,0,193,140,213,146,2,99,9,108,97,121,111,117,116,95,116,121,1,122,0,0,0,0,0,0,0,0,40,0,193,140,213,146,2,99,13,115,104,111,119,95,119,101,101,107,101,110,100,115,1,120,40,0,193,140,213,146,2,99,17,115,104,111,119,95,119,101,101,107,95,110,117,109,98,101,114,115,1,120,40,0,193,140,213,146,2,92,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,39,0,193,140,213,146,2,92,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,193,140,213,146,2,92,7,102,105,108,116,101,114,115,0,39,0,193,140,213,146,2,92,6,103,114,111,117,112,115,0,39,0,193,140,213,146,2,92,5,115,111,114,116,115,0,39,0,193,140,213,146,2,92,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,193,140,213,146,2,110,12,118,1,2,105,100,119,6,89,53,52,81,73,115,118,1,2,105,100,119,6,70,114,115,115,74,100,118,1,2,105,100,119,6,89,80,102,105,50,109,118,1,2,105,100,119,6,84,102,117,121,104,84,118,1,2,105,100,119,6,115,111,118,85,116,69,118,1,2,105,100,119,6,54,76,70,72,66,54,118,1,2,105,100,119,6,86,89,52,50,103,49,118,1,2,105,100,119,6,106,87,101,95,116,54,118,1,2,105,100,119,6,55,75,88,95,99,120,118,1,2,105,100,119,6,76,99,121,68,75,106,118,1,2,105,100,119,6,120,69,81,65,111,75,118,1,2,105,100,119,6,52,57,85,69,86,53,39,0,193,140,213,146,2,92,10,114,111,119,95,111,114,100,101,114,115,0,8,0,193,140,213,146,2,123,10,118,2,2,105,100,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,118,2,2,105,100,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,118,2,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,12,182,201,218,189,1,0,161,229,168,135,118,231,4,1,136,229,168,135,118,232,4,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,161,229,168,135,118,237,4,1,136,229,168,135,118,238,4,1,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,161,229,168,135,118,235,4,1,136,229,168,135,118,236,4,1,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,161,229,168,135,118,233,4,1,136,229,168,135,118,234,4,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,161,229,168,135,118,241,4,1,136,229,168,135,118,242,4,1,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,161,229,168,135,118,239,4,1,136,229,168,135,118,240,4,1,118,2,2,105,100,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,6,104,101,105,103,104,116,125,60,37,177,178,255,174,1,0,161,187,163,190,240,15,65,1,161,187,163,190,240,15,35,1,161,187,163,190,240,15,32,1,0,2,161,187,163,190,240,15,34,1,161,187,163,190,240,15,37,1,161,187,163,190,240,15,36,1,161,187,163,190,240,15,69,1,39,0,137,227,133,241,2,35,12,99,97,108,99,117,108,97,116,105,111,110,115,0,7,0,177,178,255,174,1,9,1,33,0,177,178,255,174,1,10,2,116,121,1,33,0,177,178,255,174,1,10,2,105,100,1,33,0,177,178,255,174,1,10,8,102,105,101,108,100,95,105,100,1,33,0,177,178,255,174,1,10,17,99,97,108,99,117,108,97,116,105,111,110,95,118,97,108,117,101,1,161,177,178,255,174,1,8,1,135,177,178,255,174,1,10,1,33,0,177,178,255,174,1,16,8,102,105,101,108,100,95,105,100,1,33,0,177,178,255,174,1,16,2,105,100,1,33,0,177,178,255,174,1,16,2,116,121,1,33,0,177,178,255,174,1,16,17,99,97,108,99,117,108,97,116,105,111,110,95,118,97,108,117,101,1,161,177,178,255,174,1,15,1,161,177,178,255,174,1,20,1,161,177,178,255,174,1,18,1,161,177,178,255,174,1,19,1,161,177,178,255,174,1,17,1,161,177,178,255,174,1,21,1,135,177,178,255,174,1,16,1,33,0,177,178,255,174,1,27,2,105,100,1,33,0,177,178,255,174,1,27,2,116,121,1,33,0,177,178,255,174,1,27,17,99,97,108,99,117,108,97,116,105,111,110,95,118,97,108,117,101,1,33,0,177,178,255,174,1,27,8,102,105,101,108,100,95,105,100,1,161,177,178,255,174,1,26,1,135,177,178,255,174,1,27,1,33,0,177,178,255,174,1,33,2,105,100,1,33,0,177,178,255,174,1,33,2,116,121,1,33,0,177,178,255,174,1,33,8,102,105,101,108,100,95,105,100,1,33,0,177,178,255,174,1,33,17,99,97,108,99,117,108,97,116,105,111,110,95,118,97,108,117,101,1,1,165,237,195,173,1,0,161,253,149,229,85,13,8,1,250,147,239,143,1,0,161,158,173,179,170,6,80,2,243,4,229,168,135,118,0,161,168,211,203,155,8,56,1,168,168,211,203,155,8,54,1,119,4,84,101,120,116,161,229,168,135,118,0,1,168,168,211,203,155,8,58,1,122,0,0,0,0,0,0,0,6,39,0,168,211,203,155,8,59,1,54,1,40,0,229,168,135,118,4,3,117,114,108,1,119,0,40,0,229,168,135,118,4,7,99,111,110,116,101,110,116,1,119,0,168,229,168,135,118,2,1,122,0,0,0,0,102,60,204,0,40,0,168,211,203,155,8,60,7,99,111,110,116,101,110,116,1,119,0,40,0,168,211,203,155,8,60,3,117,114,108,1,119,0,161,177,178,255,174,1,0,1,161,187,163,190,240,15,69,1,161,168,211,203,155,8,82,1,161,168,211,203,155,8,80,1,161,229,168,135,118,12,1,161,168,211,203,155,8,84,1,39,0,168,211,203,155,8,85,1,49,1,33,0,229,168,135,118,16,5,115,99,97,108,101,1,33,0,229,168,135,118,16,4,110,97,109,101,1,33,0,229,168,135,118,16,6,102,111,114,109,97,116,1,33,0,229,168,135,118,16,6,115,121,109,98,111,108,1,161,229,168,135,118,14,1,40,0,168,211,203,155,8,86,4,110,97,109,101,1,119,6,78,117,109,98,101,114,40,0,168,211,203,155,8,86,6,115,121,109,98,111,108,1,119,3,82,85,66,40,0,168,211,203,155,8,86,6,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,0,40,0,168,211,203,155,8,86,5,115,99,97,108,101,1,122,0,0,0,0,0,0,0,0,161,229,168,135,118,10,1,161,229,168,135,118,11,1,161,229,168,135,118,21,1,161,229,168,135,118,17,1,161,229,168,135,118,19,1,161,229,168,135,118,20,1,161,229,168,135,118,18,1,161,229,168,135,118,28,1,161,229,168,135,118,13,1,161,229,168,135,118,33,1,161,229,168,135,118,15,1,161,229,168,135,118,32,1,161,229,168,135,118,30,1,161,229,168,135,118,31,1,161,229,168,135,118,29,1,161,229,168,135,118,35,1,161,229,168,135,118,37,1,161,229,168,135,118,39,1,161,229,168,135,118,38,1,161,229,168,135,118,40,1,161,229,168,135,118,41,1,161,229,168,135,118,44,1,161,229,168,135,118,45,1,161,229,168,135,118,42,1,161,229,168,135,118,43,1,161,187,163,190,240,15,73,1,136,187,163,190,240,15,64,1,118,2,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,6,104,101,105,103,104,116,125,60,161,229,168,135,118,27,1,136,137,227,133,241,2,66,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,161,229,168,135,118,26,1,136,187,163,190,240,15,23,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,161,168,211,203,155,8,66,1,136,137,227,133,241,2,145,1,1,118,2,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,6,104,101,105,103,104,116,125,60,161,168,211,203,155,8,62,1,136,137,227,133,241,2,104,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,161,168,211,203,155,8,70,1,136,168,211,203,155,8,31,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,161,229,168,135,118,46,1,161,229,168,135,118,34,1,161,229,168,135,118,63,1,161,229,168,135,118,36,1,161,229,168,135,118,50,1,161,229,168,135,118,47,1,161,229,168,135,118,49,1,161,229,168,135,118,48,1,161,229,168,135,118,65,1,161,229,168,135,118,69,1,161,229,168,135,118,68,1,161,229,168,135,118,67,1,161,229,168,135,118,70,1,161,229,168,135,118,71,1,161,229,168,135,118,74,1,161,229,168,135,118,73,1,161,229,168,135,118,72,1,161,229,168,135,118,75,1,161,229,168,135,118,76,1,161,229,168,135,118,64,1,161,229,168,135,118,81,1,161,229,168,135,118,66,1,161,229,168,135,118,79,1,161,229,168,135,118,80,1,161,229,168,135,118,78,1,161,229,168,135,118,77,1,161,229,168,135,118,83,1,161,229,168,135,118,88,1,161,229,168,135,118,86,1,161,229,168,135,118,87,1,161,229,168,135,118,85,1,161,229,168,135,118,89,1,161,229,168,135,118,91,1,161,229,168,135,118,93,1,161,229,168,135,118,92,1,161,229,168,135,118,90,1,161,229,168,135,118,94,1,161,229,168,135,118,82,1,161,229,168,135,118,99,1,161,229,168,135,118,84,1,161,229,168,135,118,97,1,161,229,168,135,118,95,1,161,229,168,135,118,96,1,161,229,168,135,118,98,1,161,229,168,135,118,101,1,161,229,168,135,118,104,1,161,229,168,135,118,106,1,161,229,168,135,118,105,1,161,229,168,135,118,103,1,161,229,168,135,118,107,1,161,229,168,135,118,111,1,161,229,168,135,118,109,1,161,229,168,135,118,110,1,161,229,168,135,118,108,1,161,229,168,135,118,112,1,161,229,168,135,118,100,1,161,229,168,135,118,117,1,161,229,168,135,118,102,1,161,229,168,135,118,113,1,161,229,168,135,118,115,1,161,229,168,135,118,116,1,161,229,168,135,118,114,1,161,229,168,135,118,119,1,161,229,168,135,118,122,1,161,229,168,135,118,123,1,161,229,168,135,118,121,1,161,229,168,135,118,124,1,161,229,168,135,118,125,1,161,229,168,135,118,128,1,1,161,229,168,135,118,126,1,161,229,168,135,118,129,1,1,161,229,168,135,118,127,1,161,229,168,135,118,130,1,1,161,229,168,135,118,118,1,161,229,168,135,118,135,1,1,161,229,168,135,118,120,1,161,229,168,135,118,131,1,1,161,229,168,135,118,133,1,1,161,229,168,135,118,132,1,1,161,229,168,135,118,134,1,1,161,229,168,135,118,137,1,1,161,229,168,135,118,140,1,1,161,229,168,135,118,139,1,1,161,229,168,135,118,142,1,1,161,229,168,135,118,141,1,1,161,229,168,135,118,143,1,1,161,229,168,135,118,145,1,1,161,229,168,135,118,146,1,1,161,229,168,135,118,147,1,1,161,229,168,135,118,144,1,1,161,229,168,135,118,148,1,1,161,229,168,135,118,136,1,1,161,229,168,135,118,153,1,1,161,229,168,135,118,138,1,1,161,229,168,135,118,149,1,1,161,229,168,135,118,151,1,1,161,229,168,135,118,150,1,1,161,229,168,135,118,152,1,1,161,229,168,135,118,155,1,1,161,229,168,135,118,160,1,1,161,229,168,135,118,159,1,1,161,229,168,135,118,158,1,1,161,229,168,135,118,157,1,1,161,229,168,135,118,161,1,1,161,229,168,135,118,165,1,1,161,229,168,135,118,162,1,1,161,229,168,135,118,164,1,1,161,229,168,135,118,163,1,1,161,229,168,135,118,166,1,1,161,229,168,135,118,154,1,1,161,229,168,135,118,171,1,1,161,229,168,135,118,156,1,1,161,229,168,135,118,170,1,1,161,229,168,135,118,168,1,1,161,229,168,135,118,167,1,1,161,229,168,135,118,169,1,1,161,229,168,135,118,173,1,1,161,229,168,135,118,175,1,1,161,229,168,135,118,176,1,1,161,229,168,135,118,177,1,1,161,229,168,135,118,178,1,1,161,229,168,135,118,179,1,1,161,229,168,135,118,182,1,1,161,229,168,135,118,180,1,1,161,229,168,135,118,183,1,1,161,229,168,135,118,181,1,1,161,229,168,135,118,184,1,1,161,229,168,135,118,172,1,1,161,229,168,135,118,189,1,1,161,229,168,135,118,174,1,1,161,229,168,135,118,185,1,1,161,229,168,135,118,186,1,1,161,229,168,135,118,188,1,1,161,229,168,135,118,187,1,1,161,229,168,135,118,191,1,1,161,229,168,135,118,194,1,1,161,229,168,135,118,195,1,1,161,229,168,135,118,196,1,1,161,229,168,135,118,193,1,1,161,229,168,135,118,197,1,1,161,229,168,135,118,198,1,1,161,229,168,135,118,200,1,1,161,229,168,135,118,201,1,1,161,229,168,135,118,199,1,1,161,229,168,135,118,202,1,1,161,229,168,135,118,190,1,1,161,229,168,135,118,207,1,1,161,229,168,135,118,192,1,1,161,229,168,135,118,204,1,1,161,229,168,135,118,203,1,1,161,229,168,135,118,205,1,1,161,229,168,135,118,206,1,1,161,229,168,135,118,209,1,1,161,229,168,135,118,212,1,1,161,229,168,135,118,213,1,1,161,229,168,135,118,214,1,1,161,229,168,135,118,211,1,1,161,229,168,135,118,215,1,1,161,229,168,135,118,217,1,1,161,229,168,135,118,218,1,1,161,229,168,135,118,219,1,1,161,229,168,135,118,216,1,1,161,229,168,135,118,220,1,1,161,229,168,135,118,208,1,1,161,229,168,135,118,225,1,1,161,229,168,135,118,210,1,1,161,229,168,135,118,223,1,1,161,229,168,135,118,222,1,1,161,229,168,135,118,221,1,1,161,229,168,135,118,224,1,1,161,229,168,135,118,227,1,1,161,229,168,135,118,229,1,1,161,229,168,135,118,231,1,1,161,229,168,135,118,230,1,1,161,229,168,135,118,232,1,1,161,229,168,135,118,233,1,1,161,229,168,135,118,234,1,1,161,229,168,135,118,237,1,1,161,229,168,135,118,235,1,1,161,229,168,135,118,236,1,1,161,229,168,135,118,238,1,1,161,229,168,135,118,226,1,1,161,229,168,135,118,243,1,1,161,229,168,135,118,228,1,1,161,229,168,135,118,242,1,1,161,229,168,135,118,241,1,1,161,229,168,135,118,239,1,1,161,229,168,135,118,240,1,1,161,229,168,135,118,245,1,1,161,229,168,135,118,249,1,1,161,229,168,135,118,247,1,1,161,229,168,135,118,248,1,1,161,229,168,135,118,250,1,1,161,229,168,135,118,251,1,1,161,229,168,135,118,252,1,1,161,229,168,135,118,253,1,1,161,229,168,135,118,254,1,1,161,229,168,135,118,255,1,1,161,229,168,135,118,128,2,1,161,229,168,135,118,244,1,1,161,229,168,135,118,133,2,1,161,229,168,135,118,246,1,1,161,229,168,135,118,129,2,1,161,229,168,135,118,130,2,1,161,229,168,135,118,132,2,1,161,229,168,135,118,131,2,1,161,229,168,135,118,135,2,1,161,229,168,135,118,138,2,1,161,229,168,135,118,137,2,1,161,229,168,135,118,140,2,1,161,229,168,135,118,139,2,1,161,229,168,135,118,141,2,1,161,229,168,135,118,142,2,1,161,229,168,135,118,143,2,1,161,229,168,135,118,145,2,1,161,229,168,135,118,144,2,1,161,229,168,135,118,146,2,1,161,229,168,135,118,134,2,1,161,229,168,135,118,151,2,1,161,229,168,135,118,136,2,1,161,229,168,135,118,150,2,1,161,229,168,135,118,147,2,1,161,229,168,135,118,148,2,1,161,229,168,135,118,149,2,1,161,229,168,135,118,153,2,1,161,229,168,135,118,157,2,1,161,229,168,135,118,156,2,1,161,229,168,135,118,158,2,1,161,229,168,135,118,155,2,1,161,229,168,135,118,159,2,1,161,229,168,135,118,161,2,1,161,229,168,135,118,163,2,1,161,229,168,135,118,160,2,1,161,229,168,135,118,162,2,1,161,229,168,135,118,164,2,1,161,229,168,135,118,152,2,1,161,229,168,135,118,169,2,1,161,229,168,135,118,154,2,1,161,229,168,135,118,166,2,1,161,229,168,135,118,165,2,1,161,229,168,135,118,168,2,1,161,229,168,135,118,167,2,1,161,229,168,135,118,171,2,1,161,229,168,135,118,173,2,1,161,229,168,135,118,174,2,1,161,229,168,135,118,176,2,1,161,229,168,135,118,175,2,1,161,229,168,135,118,177,2,1,161,229,168,135,118,179,2,1,161,229,168,135,118,178,2,1,161,229,168,135,118,181,2,1,161,229,168,135,118,180,2,1,161,229,168,135,118,182,2,1,161,229,168,135,118,170,2,1,161,229,168,135,118,187,2,1,161,229,168,135,118,172,2,1,161,229,168,135,118,186,2,1,161,229,168,135,118,185,2,1,161,229,168,135,118,184,2,1,161,229,168,135,118,183,2,1,161,229,168,135,118,189,2,1,161,229,168,135,118,194,2,1,161,229,168,135,118,193,2,1,161,229,168,135,118,192,2,1,161,229,168,135,118,191,2,1,161,229,168,135,118,195,2,1,161,229,168,135,118,197,2,1,161,229,168,135,118,196,2,1,161,229,168,135,118,198,2,1,161,229,168,135,118,199,2,1,161,229,168,135,118,200,2,1,161,229,168,135,118,188,2,1,161,229,168,135,118,205,2,1,161,229,168,135,118,190,2,1,161,229,168,135,118,203,2,1,161,229,168,135,118,204,2,1,161,229,168,135,118,202,2,1,161,229,168,135,118,201,2,1,161,229,168,135,118,207,2,1,161,229,168,135,118,210,2,1,161,229,168,135,118,209,2,1,161,229,168,135,118,211,2,1,161,229,168,135,118,212,2,1,161,229,168,135,118,213,2,1,161,229,168,135,118,216,2,1,161,229,168,135,118,217,2,1,161,229,168,135,118,215,2,1,161,229,168,135,118,214,2,1,161,229,168,135,118,218,2,1,161,229,168,135,118,206,2,1,161,229,168,135,118,223,2,1,161,229,168,135,118,208,2,1,161,229,168,135,118,219,2,1,161,229,168,135,118,221,2,1,161,229,168,135,118,220,2,1,161,229,168,135,118,222,2,1,161,229,168,135,118,225,2,1,161,229,168,135,118,229,2,1,161,229,168,135,118,230,2,1,161,229,168,135,118,227,2,1,161,229,168,135,118,228,2,1,161,229,168,135,118,231,2,1,161,229,168,135,118,232,2,1,161,229,168,135,118,235,2,1,161,229,168,135,118,233,2,1,161,229,168,135,118,234,2,1,161,229,168,135,118,236,2,1,161,229,168,135,118,224,2,1,161,229,168,135,118,241,2,1,161,229,168,135,118,226,2,1,161,229,168,135,118,239,2,1,161,229,168,135,118,240,2,1,161,229,168,135,118,238,2,1,161,229,168,135,118,237,2,1,161,229,168,135,118,243,2,1,161,229,168,135,118,246,2,1,161,229,168,135,118,247,2,1,161,229,168,135,118,245,2,1,161,229,168,135,118,248,2,1,161,229,168,135,118,249,2,1,161,229,168,135,118,251,2,1,161,229,168,135,118,252,2,1,161,229,168,135,118,253,2,1,161,229,168,135,118,250,2,1,161,229,168,135,118,254,2,1,161,229,168,135,118,242,2,1,161,229,168,135,118,131,3,1,161,229,168,135,118,244,2,1,161,229,168,135,118,255,2,1,161,229,168,135,118,129,3,1,161,229,168,135,118,130,3,1,161,229,168,135,118,128,3,1,161,229,168,135,118,133,3,1,161,229,168,135,118,135,3,1,161,229,168,135,118,138,3,1,161,229,168,135,118,137,3,1,161,229,168,135,118,136,3,1,161,229,168,135,118,139,3,1,161,229,168,135,118,143,3,1,161,229,168,135,118,140,3,1,161,229,168,135,118,141,3,1,161,229,168,135,118,142,3,1,161,229,168,135,118,144,3,1,161,229,168,135,118,132,3,1,161,229,168,135,118,149,3,1,161,229,168,135,118,134,3,1,161,229,168,135,118,147,3,1,161,229,168,135,118,145,3,1,161,229,168,135,118,148,3,1,161,229,168,135,118,146,3,1,161,229,168,135,118,151,3,1,161,229,168,135,118,155,3,1,161,229,168,135,118,153,3,1,161,229,168,135,118,154,3,1,161,229,168,135,118,156,3,1,161,229,168,135,118,157,3,1,161,229,168,135,118,159,3,1,161,229,168,135,118,160,3,1,161,229,168,135,118,158,3,1,161,229,168,135,118,161,3,1,161,229,168,135,118,162,3,1,161,229,168,135,118,150,3,1,161,229,168,135,118,167,3,1,161,229,168,135,118,152,3,1,161,229,168,135,118,163,3,1,161,229,168,135,118,164,3,1,161,229,168,135,118,166,3,1,161,229,168,135,118,165,3,1,161,229,168,135,118,169,3,1,161,229,168,135,118,173,3,1,161,229,168,135,118,171,3,1,161,229,168,135,118,174,3,1,161,229,168,135,118,172,3,1,161,229,168,135,118,175,3,1,161,229,168,135,118,179,3,1,161,229,168,135,118,177,3,1,161,229,168,135,118,176,3,1,161,229,168,135,118,178,3,1,161,229,168,135,118,180,3,1,161,229,168,135,118,168,3,1,161,229,168,135,118,185,3,1,161,229,168,135,118,170,3,1,161,229,168,135,118,181,3,1,161,229,168,135,118,183,3,1,161,229,168,135,118,184,3,1,161,229,168,135,118,182,3,1,161,229,168,135,118,187,3,1,161,229,168,135,118,191,3,1,161,229,168,135,118,189,3,1,161,229,168,135,118,190,3,1,161,229,168,135,118,192,3,1,161,229,168,135,118,193,3,1,161,229,168,135,118,194,3,1,161,229,168,135,118,197,3,1,161,229,168,135,118,196,3,1,161,229,168,135,118,195,3,1,161,229,168,135,118,198,3,1,161,229,168,135,118,186,3,1,161,229,168,135,118,203,3,1,161,229,168,135,118,188,3,1,161,229,168,135,118,202,3,1,161,229,168,135,118,199,3,1,161,229,168,135,118,200,3,1,161,229,168,135,118,201,3,1,161,229,168,135,118,205,3,1,161,229,168,135,118,208,3,1,161,229,168,135,118,209,3,1,161,229,168,135,118,210,3,1,161,229,168,135,118,207,3,1,161,229,168,135,118,211,3,1,161,229,168,135,118,212,3,1,161,229,168,135,118,215,3,1,161,229,168,135,118,213,3,1,161,229,168,135,118,214,3,1,161,229,168,135,118,216,3,1,161,229,168,135,118,204,3,1,161,229,168,135,118,221,3,1,161,229,168,135,118,206,3,1,161,229,168,135,118,218,3,1,161,229,168,135,118,219,3,1,161,229,168,135,118,217,3,1,161,229,168,135,118,220,3,1,161,229,168,135,118,223,3,1,161,229,168,135,118,225,3,1,161,229,168,135,118,227,3,1,161,229,168,135,118,228,3,1,161,229,168,135,118,226,3,1,161,229,168,135,118,229,3,1,161,229,168,135,118,230,3,1,161,229,168,135,118,233,3,1,161,229,168,135,118,231,3,1,161,229,168,135,118,232,3,1,161,229,168,135,118,234,3,1,161,229,168,135,118,222,3,1,161,229,168,135,118,239,3,1,161,229,168,135,118,224,3,1,161,229,168,135,118,238,3,1,161,229,168,135,118,236,3,1,161,229,168,135,118,235,3,1,161,229,168,135,118,237,3,1,161,229,168,135,118,241,3,1,161,229,168,135,118,244,3,1,161,229,168,135,118,243,3,1,161,229,168,135,118,245,3,1,161,229,168,135,118,246,3,1,161,229,168,135,118,247,3,1,161,229,168,135,118,250,3,1,161,229,168,135,118,249,3,1,161,229,168,135,118,248,3,1,161,229,168,135,118,251,3,1,161,229,168,135,118,252,3,1,161,229,168,135,118,240,3,1,161,229,168,135,118,129,4,1,161,229,168,135,118,242,3,1,161,229,168,135,118,254,3,1,161,229,168,135,118,255,3,1,161,229,168,135,118,128,4,1,161,229,168,135,118,253,3,1,161,229,168,135,118,131,4,1,161,229,168,135,118,134,4,1,161,229,168,135,118,136,4,1,161,229,168,135,118,135,4,1,161,229,168,135,118,133,4,1,161,229,168,135,118,137,4,1,161,229,168,135,118,139,4,1,161,229,168,135,118,140,4,1,161,229,168,135,118,141,4,1,161,229,168,135,118,138,4,1,161,229,168,135,118,142,4,1,161,229,168,135,118,130,4,1,161,229,168,135,118,147,4,1,161,229,168,135,118,132,4,1,161,229,168,135,118,143,4,1,161,229,168,135,118,145,4,1,161,229,168,135,118,146,4,1,161,229,168,135,118,144,4,1,161,229,168,135,118,149,4,1,161,229,168,135,118,151,4,1,161,229,168,135,118,152,4,1,161,229,168,135,118,153,4,1,161,229,168,135,118,154,4,1,161,229,168,135,118,155,4,1,161,229,168,135,118,158,4,1,161,229,168,135,118,157,4,1,161,229,168,135,118,156,4,1,161,229,168,135,118,159,4,1,161,229,168,135,118,160,4,1,161,229,168,135,118,148,4,1,161,229,168,135,118,165,4,1,161,229,168,135,118,150,4,1,161,229,168,135,118,162,4,1,161,229,168,135,118,164,4,1,161,229,168,135,118,163,4,1,161,229,168,135,118,161,4,1,161,229,168,135,118,167,4,1,161,229,168,135,118,169,4,1,161,229,168,135,118,171,4,1,161,229,168,135,118,170,4,1,161,229,168,135,118,172,4,1,161,229,168,135,118,173,4,1,161,229,168,135,118,176,4,1,161,229,168,135,118,177,4,1,161,229,168,135,118,174,4,1,161,229,168,135,118,175,4,1,161,229,168,135,118,178,4,1,161,229,168,135,118,166,4,1,161,229,168,135,118,183,4,1,161,229,168,135,118,168,4,1,161,229,168,135,118,181,4,1,161,229,168,135,118,180,4,1,161,229,168,135,118,182,4,1,161,229,168,135,118,179,4,1,161,229,168,135,118,185,4,1,161,229,168,135,118,188,4,1,161,229,168,135,118,189,4,1,161,229,168,135,118,187,4,1,161,229,168,135,118,190,4,1,161,229,168,135,118,191,4,1,161,229,168,135,118,194,4,1,161,229,168,135,118,192,4,1,161,229,168,135,118,193,4,1,161,229,168,135,118,195,4,1,161,229,168,135,118,196,4,1,161,229,168,135,118,184,4,1,161,229,168,135,118,201,4,1,161,229,168,135,118,186,4,1,161,229,168,135,118,199,4,1,161,229,168,135,118,200,4,1,161,229,168,135,118,198,4,1,161,229,168,135,118,197,4,1,161,229,168,135,118,203,4,1,161,229,168,135,118,207,4,1,161,229,168,135,118,205,4,1,161,229,168,135,118,208,4,1,161,229,168,135,118,206,4,1,161,229,168,135,118,209,4,1,161,229,168,135,118,213,4,1,161,229,168,135,118,212,4,1,161,229,168,135,118,210,4,1,161,229,168,135,118,211,4,1,161,229,168,135,118,51,1,136,229,168,135,118,52,1,118,2,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,6,104,101,105,103,104,116,125,60,161,229,168,135,118,53,1,136,229,168,135,118,54,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,161,229,168,135,118,55,1,136,229,168,135,118,56,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,161,229,168,135,118,57,1,136,229,168,135,118,58,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,161,229,168,135,118,59,1,136,229,168,135,118,60,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,161,229,168,135,118,61,1,136,229,168,135,118,62,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,161,229,168,135,118,219,4,1,136,229,168,135,118,220,4,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,161,229,168,135,118,221,4,1,136,229,168,135,118,222,4,1,118,2,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,6,104,101,105,103,104,116,125,60,161,229,168,135,118,223,4,1,136,229,168,135,118,224,4,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,161,229,168,135,118,225,4,1,136,229,168,135,118,226,4,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,161,229,168,135,118,227,4,1,136,229,168,135,118,228,4,1,118,2,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,6,104,101,105,103,104,116,125,60,161,229,168,135,118,229,4,1,136,229,168,135,118,230,4,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,2,149,154,146,112,0,161,186,204,138,236,4,111,1,161,186,204,138,236,4,117,19,1,211,189,178,91,0,161,252,240,184,224,14,23,80,1,253,149,229,85,0,161,142,215,187,158,14,5,14,1,211,235,145,81,0,161,128,137,148,150,4,38,16,65,128,137,148,150,4,1,0,39,132,238,182,192,14,1,0,5,134,200,133,143,5,1,0,2,135,173,169,205,15,1,0,4,137,227,133,241,2,19,18,1,20,1,22,1,25,1,40,1,53,3,67,1,70,1,86,1,105,1,107,12,124,1,146,1,1,150,1,1,154,1,1,160,1,1,162,1,1,164,1,1,167,1,3,140,242,215,248,4,1,0,35,141,132,223,206,14,1,0,5,142,215,187,158,14,1,0,10,146,198,138,224,6,4,0,5,8,1,11,2,14,2,149,154,146,112,1,0,20,150,194,135,131,8,1,0,12,154,253,168,186,13,1,0,6,157,197,217,249,6,1,0,3,158,173,179,170,6,1,0,81,160,159,229,236,10,1,0,34,162,129,240,225,15,1,0,19,165,237,195,173,1,1,0,8,168,211,203,155,8,17,0,3,15,1,32,1,36,1,40,1,44,1,48,1,54,1,56,1,58,1,62,1,66,1,70,1,74,1,80,1,82,1,84,1,171,216,132,162,10,14,5,1,37,1,39,6,54,1,56,1,58,1,60,1,62,1,64,1,66,1,68,5,79,1,87,1,92,1,174,158,229,225,9,1,0,2,175,150,167,163,14,1,0,4,174,182,200,164,11,1,0,2,177,178,255,174,1,5,0,9,11,5,17,10,28,5,34,4,178,161,242,226,13,1,0,153,1,174,250,146,158,5,1,0,1,180,149,168,150,13,1,0,10,180,132,165,192,8,1,0,1,182,201,218,189,1,6,0,1,2,1,4,1,6,1,8,1,10,1,182,139,168,140,5,1,0,36,183,238,200,180,5,1,0,6,185,145,225,175,8,12,0,182,2,185,2,1,189,2,1,193,2,1,197,2,1,201,2,1,207,2,1,209,2,1,211,2,1,215,2,7,223,2,1,233,2,52,186,204,138,236,4,1,0,118,187,163,190,240,15,9,5,1,24,1,26,12,43,1,65,1,69,1,73,1,81,1,83,1,187,159,219,213,8,1,0,2,188,252,160,180,14,1,0,1,191,215,204,166,13,1,0,12,192,183,207,147,14,1,0,43,193,174,143,180,7,1,0,18,193,140,213,146,2,3,41,1,75,1,77,5,200,168,240,223,7,1,0,2,201,191,253,157,12,1,0,2,200,156,140,203,9,1,0,2,202,170,215,178,7,1,0,24,203,248,208,163,4,1,0,4,206,242,242,141,13,1,0,95,209,142,245,200,15,45,0,55,56,1,58,9,72,55,136,1,28,165,1,1,167,1,3,172,1,4,177,1,2,180,1,232,1,157,3,4,162,3,18,182,3,1,186,3,1,190,3,1,194,3,1,198,3,1,202,3,1,208,3,1,210,3,1,212,3,1,215,3,5,223,3,1,227,3,1,231,3,1,235,3,1,239,3,1,128,4,55,184,4,1,186,4,9,200,4,1,204,4,1,208,4,1,212,4,1,216,4,1,220,4,1,233,4,44,150,5,1,152,5,1,154,5,1,156,5,1,158,5,1,160,5,11,175,5,1,180,5,3,210,221,238,195,8,1,0,20,211,189,178,91,1,0,80,211,235,145,81,1,0,16,216,247,253,206,7,1,0,2,219,179,165,244,8,1,0,4,224,218,133,236,10,1,0,13,227,170,238,211,14,1,0,16,227,250,198,245,13,1,0,5,229,168,135,118,22,0,1,2,1,10,6,17,5,26,26,53,1,55,1,57,1,59,1,61,1,63,157,4,221,4,1,223,4,1,225,4,1,227,4,1,229,4,1,231,4,1,233,4,1,235,4,1,237,4,1,239,4,1,241,4,1,234,232,155,212,3,1,0,1,246,154,200,238,10,1,0,11,247,149,251,192,4,1,0,4,248,220,249,231,6,1,0,29,247,187,192,242,6,1,0,6,250,147,239,143,1,1,0,2,252,220,241,227,14,1,0,60,253,149,229,85,1,0,14,253,223,254,206,11,1,0,2,252,240,184,224,14,1,0,24],"version":0,"object_id":"4c658817-20db-4f56-b7f9-0637a22dfeb6"},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d.json b/frontend/appflowy_web_app/cypress/fixtures/database/ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d.json new file mode 100644 index 0000000000..ceebd01573 --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d.json @@ -0,0 +1 @@ +{"data":{"state_vector":[16,225,154,253,156,5,2,195,240,220,252,7,5,230,172,170,202,7,8,135,161,218,171,7,6,139,153,229,238,6,2,237,201,168,43,16,238,188,221,160,14,2,244,240,200,227,1,33,181,255,217,196,15,125,212,226,138,162,13,39,151,225,131,140,9,2,248,251,128,198,10,7,149,205,253,206,14,12,251,237,143,129,13,7,158,192,169,36,18,190,203,155,67,2],"doc_state":[16,102,181,255,217,196,15,0,39,1,4,100,97,116,97,8,100,97,116,97,98,97,115,101,1,40,0,181,255,217,196,15,0,2,105,100,1,119,36,97,100,55,100,99,52,53,98,45,52,52,98,53,45,52,57,56,102,45,98,102,97,50,45,48,102,52,51,98,102,48,53,99,99,48,100,39,0,181,255,217,196,15,0,6,102,105,101,108,100,115,1,39,0,181,255,217,196,15,0,5,118,105,101,119,115,1,39,0,181,255,217,196,15,0,5,109,101,116,97,115,1,40,0,181,255,217,196,15,4,3,105,105,100,1,119,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,39,0,181,255,217,196,15,2,6,51,111,45,90,115,109,1,40,0,181,255,217,196,15,6,2,105,100,1,119,6,51,111,45,90,115,109,40,0,181,255,217,196,15,6,4,110,97,109,101,1,119,11,68,101,115,99,114,105,112,116,105,111,110,40,0,181,255,217,196,15,6,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,39,162,40,0,181,255,217,196,15,6,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,39,162,40,0,181,255,217,196,15,6,10,105,115,95,112,114,105,109,97,114,121,1,120,40,0,181,255,217,196,15,6,2,116,121,1,122,0,0,0,0,0,0,0,0,39,0,181,255,217,196,15,6,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,181,255,217,196,15,13,1,48,1,40,0,181,255,217,196,15,14,4,100,97,116,97,1,119,0,33,0,181,255,217,196,15,2,6,121,52,52,50,48,119,1,0,9,39,0,181,255,217,196,15,3,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,1,40,0,181,255,217,196,15,26,2,105,100,1,119,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,40,0,181,255,217,196,15,26,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,97,100,55,100,99,52,53,98,45,52,52,98,53,45,52,57,56,102,45,98,102,97,50,45,48,102,52,51,98,102,48,53,99,99,48,100,40,0,181,255,217,196,15,26,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,181,255,217,196,15,26,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,39,162,33,0,181,255,217,196,15,26,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,181,255,217,196,15,26,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,181,255,217,196,15,32,1,49,1,40,0,181,255,217,196,15,33,21,104,105,100,101,95,117,110,103,114,111,117,112,101,100,95,99,111,108,117,109,110,1,121,40,0,181,255,217,196,15,33,22,99,111,108,108,97,112,115,101,95,104,105,100,100,101,110,95,103,114,111,117,112,115,1,121,40,0,181,255,217,196,15,26,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,39,0,181,255,217,196,15,26,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,181,255,217,196,15,37,6,51,111,45,90,115,109,1,40,0,181,255,217,196,15,38,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,40,0,181,255,217,196,15,38,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,40,0,181,255,217,196,15,38,4,119,114,97,112,1,120,33,0,181,255,217,196,15,37,6,121,52,52,50,48,119,1,0,3,39,0,181,255,217,196,15,26,7,102,105,108,116,101,114,115,0,39,0,181,255,217,196,15,26,6,103,114,111,117,112,115,0,39,0,181,255,217,196,15,26,5,115,111,114,116,115,0,39,0,181,255,217,196,15,26,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,181,255,217,196,15,49,1,118,1,2,105,100,119,6,51,111,45,90,115,109,129,181,255,217,196,15,50,1,39,0,181,255,217,196,15,26,10,114,111,119,95,111,114,100,101,114,115,0,8,0,181,255,217,196,15,52,3,118,2,2,105,100,119,36,50,48,56,100,50,52,56,102,45,53,99,48,56,45,52,98,101,53,45,97,48,50,50,45,101,48,97,57,55,99,50,100,55,48,53,101,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,100,51,50,101,52,56,97,52,45,99,102,48,100,45,52,56,97,56,45,57,53,57,57,45,53,51,51,57,97,56,49,53,56,99,53,48,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,101,56,55,56,51,48,55,45,97,98,49,101,45,52,50,101,53,45,56,57,55,98,45,56,97,51,101,97,55,56,97,52,53,49,53,161,181,255,217,196,15,31,1,7,0,181,255,217,196,15,47,1,33,0,181,255,217,196,15,57,6,103,114,111,117,112,115,1,33,0,181,255,217,196,15,57,8,102,105,101,108,100,95,105,100,1,33,0,181,255,217,196,15,57,2,116,121,1,33,0,181,255,217,196,15,57,7,99,111,110,116,101,110,116,1,33,0,181,255,217,196,15,57,2,105,100,1,161,181,255,217,196,15,56,1,161,181,255,217,196,15,58,1,0,4,161,181,255,217,196,15,62,1,161,181,255,217,196,15,60,1,161,181,255,217,196,15,61,1,161,181,255,217,196,15,59,1,39,0,181,255,217,196,15,3,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,1,40,0,181,255,217,196,15,73,2,105,100,1,119,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,40,0,181,255,217,196,15,73,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,97,100,55,100,99,52,53,98,45,52,52,98,53,45,52,57,56,102,45,98,102,97,50,45,48,102,52,51,98,102,48,53,99,99,48,100,40,0,181,255,217,196,15,73,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,181,255,217,196,15,73,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,33,0,181,255,217,196,15,73,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,181,255,217,196,15,73,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,40,0,181,255,217,196,15,73,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,39,0,181,255,217,196,15,73,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,181,255,217,196,15,73,7,102,105,108,116,101,114,115,0,39,0,181,255,217,196,15,73,6,103,114,111,117,112,115,0,39,0,181,255,217,196,15,73,5,115,111,114,116,115,0,39,0,181,255,217,196,15,73,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,181,255,217,196,15,85,1,118,1,2,105,100,119,6,51,111,45,90,115,109,129,181,255,217,196,15,86,1,39,0,181,255,217,196,15,73,10,114,111,119,95,111,114,100,101,114,115,0,8,0,181,255,217,196,15,88,3,118,2,2,105,100,119,36,50,48,56,100,50,52,56,102,45,53,99,48,56,45,52,98,101,53,45,97,48,50,50,45,101,48,97,57,55,99,50,100,55,48,53,101,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,100,51,50,101,52,56,97,52,45,99,102,48,100,45,52,56,97,56,45,57,53,57,57,45,53,51,51,57,97,56,49,53,56,99,53,48,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,56,101,56,55,56,51,48,55,45,97,98,49,101,45,52,50,101,53,45,56,57,55,98,45,56,97,51,101,97,55,56,97,52,53,49,53,161,181,255,217,196,15,78,1,161,181,255,217,196,15,63,2,161,181,255,217,196,15,92,1,168,181,255,217,196,15,95,1,122,0,0,0,0,102,76,39,194,136,181,255,217,196,15,87,1,118,1,2,105,100,119,6,81,51,56,55,119,49,39,0,181,255,217,196,15,81,6,81,51,56,55,119,49,1,40,0,181,255,217,196,15,98,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,161,181,255,217,196,15,94,1,136,181,255,217,196,15,51,1,118,1,2,105,100,119,6,81,51,56,55,119,49,39,0,181,255,217,196,15,37,6,81,51,56,55,119,49,1,40,0,181,255,217,196,15,102,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,181,255,217,196,15,2,6,81,51,56,55,119,49,1,40,0,181,255,217,196,15,104,2,105,100,1,119,6,81,51,56,55,119,49,40,0,181,255,217,196,15,104,4,110,97,109,101,1,119,8,67,104,101,99,107,98,111,120,40,0,181,255,217,196,15,104,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,39,194,40,0,181,255,217,196,15,104,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,39,194,40,0,181,255,217,196,15,104,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,181,255,217,196,15,104,2,116,121,1,122,0,0,0,0,0,0,0,5,39,0,181,255,217,196,15,104,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,181,255,217,196,15,111,1,53,1,168,181,255,217,196,15,100,1,122,0,0,0,0,102,76,39,200,168,181,255,217,196,15,69,1,119,8,103,58,85,113,84,54,68,80,168,181,255,217,196,15,70,1,122,0,0,0,0,0,0,0,3,168,181,255,217,196,15,72,1,119,6,121,52,52,50,48,119,168,181,255,217,196,15,71,1,119,0,167,181,255,217,196,15,64,0,8,0,181,255,217,196,15,118,6,118,2,2,105,100,119,6,121,52,52,50,48,119,7,118,105,115,105,98,108,101,120,118,2,2,105,100,119,4,117,76,117,51,7,118,105,115,105,98,108,101,120,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,4,73,113,105,73,118,2,2,105,100,119,4,82,69,88,119,7,118,105,115,105,98,108,101,120,118,2,7,118,105,115,105,98,108,101,120,2,105,100,119,3,89,101,115,118,2,2,105,100,119,2,78,111,7,118,105,115,105,98,108,101,120,1,149,205,253,206,14,0,161,135,161,218,171,7,5,12,1,238,188,221,160,14,0,161,149,205,253,206,14,11,2,1,212,226,138,162,13,0,161,251,237,143,129,13,6,39,1,251,237,143,129,13,0,161,248,251,128,198,10,6,7,1,248,251,128,198,10,0,161,151,225,131,140,9,1,7,1,151,225,131,140,9,0,161,244,240,200,227,1,32,2,1,195,240,220,252,7,0,161,139,153,229,238,6,1,5,2,230,172,170,202,7,0,161,195,240,220,252,7,4,7,168,230,172,170,202,7,6,1,122,0,0,0,0,102,88,25,34,1,135,161,218,171,7,0,161,225,154,253,156,5,1,6,1,139,153,229,238,6,0,161,158,192,169,36,17,2,1,225,154,253,156,5,0,161,237,201,168,43,15,2,1,244,240,200,227,1,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,33,1,190,203,155,67,0,161,135,161,218,171,7,5,2,1,237,201,168,43,0,161,212,226,138,162,13,38,16,1,158,192,169,36,0,161,238,188,221,160,14,1,18,16,225,154,253,156,5,1,0,2,195,240,220,252,7,1,0,5,230,172,170,202,7,1,0,7,135,161,218,171,7,1,0,6,139,153,229,238,6,1,0,2,237,201,168,43,1,0,16,238,188,221,160,14,1,0,2,244,240,200,227,1,1,0,33,181,255,217,196,15,10,16,10,31,1,42,4,51,1,56,1,58,15,78,1,87,1,92,4,100,1,212,226,138,162,13,1,0,39,151,225,131,140,9,1,0,2,248,251,128,198,10,1,0,7,149,205,253,206,14,1,0,12,251,237,143,129,13,1,0,7,158,192,169,36,1,0,18,190,203,155,67,1,0,2],"version":0,"object_id":"ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d"},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/ce267d12-3b61-4ebb-bb03-d65272f5f817.json b/frontend/appflowy_web_app/cypress/fixtures/database/ce267d12-3b61-4ebb-bb03-d65272f5f817.json new file mode 100644 index 0000000000..428ca72d5b --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/ce267d12-3b61-4ebb-bb03-d65272f5f817.json @@ -0,0 +1 @@ +{"data":{"state_vector":[20,162,178,170,161,1,6,131,222,171,184,9,39,130,208,239,179,11,2,133,224,179,154,9,2,231,138,159,208,10,2,231,217,162,139,1,5,170,249,160,147,7,21,139,202,180,177,14,33,236,192,251,208,2,9,204,220,240,227,3,212,1,145,151,150,143,2,7,146,214,128,188,1,65,243,175,215,198,3,7,212,178,171,164,8,14,149,159,177,202,15,2,149,178,144,155,15,8,247,242,142,226,14,6,249,247,244,162,15,37,219,228,172,146,1,10,251,157,254,151,3,107],"doc_state":[20,1,149,159,177,202,15,0,161,170,249,160,147,7,20,2,22,249,247,244,162,15,0,39,0,251,157,254,151,3,3,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,1,40,0,249,247,244,162,15,0,2,105,100,1,119,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,40,0,249,247,244,162,15,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,249,247,244,162,15,0,4,110,97,109,101,1,119,16,86,105,101,119,32,111,102,32,67,97,108,101,110,100,97,114,40,0,249,247,244,162,15,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,40,0,249,247,244,162,15,0,11,109,111,100,105,102,105,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,39,0,249,247,244,162,15,0,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,249,247,244,162,15,6,1,50,1,40,0,249,247,244,162,15,7,9,108,97,121,111,117,116,95,116,121,1,122,0,0,0,0,0,0,0,0,40,0,249,247,244,162,15,7,17,115,104,111,119,95,119,101,101,107,95,110,117,109,98,101,114,115,1,120,40,0,249,247,244,162,15,7,17,102,105,114,115,116,95,100,97,121,95,111,102,95,119,101,101,107,1,122,0,0,0,0,0,0,0,0,40,0,249,247,244,162,15,7,13,115,104,111,119,95,119,101,101,107,101,110,100,115,1,120,40,0,249,247,244,162,15,7,8,102,105,101,108,100,95,105,100,1,119,6,71,115,66,65,97,76,40,0,249,247,244,162,15,0,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,39,0,249,247,244,162,15,0,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,249,247,244,162,15,0,7,102,105,108,116,101,114,115,0,39,0,249,247,244,162,15,0,6,103,114,111,117,112,115,0,39,0,249,247,244,162,15,0,5,115,111,114,116,115,0,39,0,249,247,244,162,15,0,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,249,247,244,162,15,18,11,118,1,2,105,100,119,6,72,95,74,113,85,76,118,1,2,105,100,119,6,55,85,107,117,54,82,118,1,2,105,100,119,6,95,82,45,112,104,105,118,1,2,105,100,119,6,99,78,53,98,120,74,118,1,2,105,100,119,6,71,115,66,65,97,76,118,1,2,105,100,119,6,71,79,80,107,116,118,118,1,2,105,100,119,6,70,99,112,109,80,101,118,1,2,105,100,119,6,112,70,120,57,67,45,118,1,2,105,100,119,6,101,49,98,55,48,88,118,1,2,105,100,119,6,80,78,113,89,102,76,118,1,2,105,100,119,6,75,71,50,113,74,65,39,0,249,247,244,162,15,0,10,114,111,119,95,111,114,100,101,114,115,0,8,0,249,247,244,162,15,30,6,118,2,2,105,100,119,36,55,55,49,55,48,55,57,98,45,48,53,98,54,45,52,97,48,97,45,56,101,101,52,45,52,56,55,51,57,102,98,102,51,97,53,50,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,97,55,51,54,55,52,97,101,45,51,51,48,49,45,52,53,97,51,45,98,56,48,49,45,51,102,49,50,101,54,102,99,98,53,54,54,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,50,49,53,48,99,102,102,54,45,102,102,56,48,45,52,51,51,52,45,56,99,56,97,45,57,52,101,56,50,97,54,52,51,55,57,97,6,104,101,105,103,104,116,125,60,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,53,49,99,102,48,57,48,54,45,97,100,52,54,45,52,100,97,101,45,97,51,98,57,45,50,101,48,48,51,102,56,51,54,56,99,49,118,2,2,105,100,119,36,97,48,48,101,99,102,55,56,45,97,56,50,51,45,52,51,102,49,45,98,53,52,50,45,101,100,48,55,49,51,57,52,97,55,49,55,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,57,50,97,50,49,51,55,101,45,98,48,48,98,45,52,51,56,56,45,56,53,49,102,45,97,48,101,102,99,51,100,101,55,99,97,51,6,104,101,105,103,104,116,125,60,2,149,178,144,155,15,0,161,231,217,162,139,1,4,7,168,149,178,144,155,15,6,1,122,0,0,0,0,102,88,25,34,1,247,242,142,226,14,0,161,243,175,215,198,3,6,6,1,139,202,180,177,14,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,33,1,130,208,239,179,11,0,161,247,242,142,226,14,5,2,1,231,138,159,208,10,0,161,219,228,172,146,1,9,2,1,131,222,171,184,9,0,161,146,214,128,188,1,64,39,1,133,224,179,154,9,0,161,231,138,159,208,10,1,2,1,212,178,171,164,8,0,161,162,178,170,161,1,5,14,1,170,249,160,147,7,0,161,133,224,179,154,9,1,21,204,1,204,220,240,227,3,0,161,251,157,254,151,3,91,1,136,251,157,254,151,3,74,1,118,2,2,105,100,119,36,97,55,51,54,55,52,97,101,45,51,51,48,49,45,52,53,97,51,45,98,56,48,49,45,51,102,49,50,101,54,102,99,98,53,54,54,6,104,101,105,103,104,116,125,60,161,204,220,240,227,3,0,1,136,204,220,240,227,3,1,1,118,2,2,105,100,119,36,50,49,53,48,99,102,102,54,45,102,102,56,48,45,52,51,51,52,45,56,99,56,97,45,57,52,101,56,50,97,54,52,51,55,57,97,6,104,101,105,103,104,116,125,60,161,204,220,240,227,3,2,1,136,204,220,240,227,3,3,1,118,2,2,105,100,119,36,53,49,99,102,48,57,48,54,45,97,100,52,54,45,52,100,97,101,45,97,51,98,57,45,50,101,48,48,51,102,56,51,54,56,99,49,6,104,101,105,103,104,116,125,60,161,204,220,240,227,3,4,1,136,204,220,240,227,3,5,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,97,48,48,101,99,102,55,56,45,97,56,50,51,45,52,51,102,49,45,98,53,52,50,45,101,100,48,55,49,51,57,52,97,55,49,55,39,0,251,157,254,151,3,3,36,54,54,97,54,102,51,98,99,45,99,55,56,102,45,52,102,55,52,45,97,48,57,101,45,48,56,100,52,55,49,55,98,102,49,102,100,1,40,0,204,220,240,227,3,8,2,105,100,1,119,36,54,54,97,54,102,51,98,99,45,99,55,56,102,45,52,102,55,52,45,97,48,57,101,45,48,56,100,52,55,49,55,98,102,49,102,100,40,0,204,220,240,227,3,8,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,204,220,240,227,3,8,4,110,97,109,101,1,119,4,71,114,105,100,40,0,204,220,240,227,3,8,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,0,0,0,0,33,0,204,220,240,227,3,8,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,204,220,240,227,3,8,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,40,0,204,220,240,227,3,8,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,39,0,204,220,240,227,3,8,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,204,220,240,227,3,8,7,102,105,108,116,101,114,115,0,39,0,204,220,240,227,3,8,6,103,114,111,117,112,115,0,39,0,204,220,240,227,3,8,5,115,111,114,116,115,0,39,0,204,220,240,227,3,8,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,204,220,240,227,3,20,5,118,1,2,105,100,119,6,72,95,74,113,85,76,118,1,2,105,100,119,6,55,85,107,117,54,82,118,1,2,105,100,119,6,95,82,45,112,104,105,118,1,2,105,100,119,6,99,78,53,98,120,74,118,1,2,105,100,119,6,71,115,66,65,97,76,39,0,204,220,240,227,3,8,10,114,111,119,95,111,114,100,101,114,115,0,8,0,204,220,240,227,3,26,5,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,55,55,49,55,48,55,57,98,45,48,53,98,54,45,52,97,48,97,45,56,101,101,52,45,52,56,55,51,57,102,98,102,51,97,53,50,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,97,55,51,54,55,52,97,101,45,51,51,48,49,45,52,53,97,51,45,98,56,48,49,45,51,102,49,50,101,54,102,99,98,53,54,54,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,50,49,53,48,99,102,102,54,45,102,102,56,48,45,52,51,51,52,45,56,99,56,97,45,57,52,101,56,50,97,54,52,51,55,57,97,118,2,2,105,100,119,36,53,49,99,102,48,57,48,54,45,97,100,52,54,45,52,100,97,101,45,97,51,98,57,45,50,101,48,48,51,102,56,51,54,56,99,49,6,104,101,105,103,104,116,125,60,118,2,2,105,100,119,36,97,48,48,101,99,102,55,56,45,97,56,50,51,45,52,51,102,49,45,98,53,52,50,45,101,100,48,55,49,51,57,52,97,55,49,55,6,104,101,105,103,104,116,125,60,161,251,157,254,151,3,85,1,168,251,157,254,151,3,87,1,122,0,0,0,0,0,0,0,6,39,0,251,157,254,151,3,88,1,54,1,40,0,204,220,240,227,3,34,7,99,111,110,116,101,110,116,1,119,0,40,0,204,220,240,227,3,34,3,117,114,108,1,119,0,168,204,220,240,227,3,32,1,122,0,0,0,0,102,77,165,82,40,0,251,157,254,151,3,89,7,99,111,110,116,101,110,116,1,119,0,40,0,251,157,254,151,3,89,3,117,114,108,1,119,0,161,204,220,240,227,3,6,1,161,204,220,240,227,3,13,1,161,204,220,240,227,3,40,1,136,251,157,254,151,3,92,1,118,1,2,105,100,119,6,71,79,80,107,116,118,39,0,251,157,254,151,3,52,6,71,79,80,107,116,118,1,40,0,204,220,240,227,3,44,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,204,220,240,227,3,41,1,136,204,220,240,227,3,25,1,118,1,2,105,100,119,6,71,79,80,107,116,118,39,0,204,220,240,227,3,16,6,71,79,80,107,116,118,1,40,0,204,220,240,227,3,48,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,2,6,71,79,80,107,116,118,1,40,0,204,220,240,227,3,50,2,105,100,1,119,6,71,79,80,107,116,118,40,0,204,220,240,227,3,50,4,110,97,109,101,1,119,4,84,101,120,116,40,0,204,220,240,227,3,50,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,99,33,0,204,220,240,227,3,50,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,204,220,240,227,3,50,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,204,220,240,227,3,50,2,116,121,1,39,0,204,220,240,227,3,50,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,204,220,240,227,3,57,1,48,1,40,0,204,220,240,227,3,58,4,100,97,116,97,1,119,0,161,204,220,240,227,3,54,1,168,204,220,240,227,3,56,1,122,0,0,0,0,0,0,0,3,39,0,204,220,240,227,3,57,1,51,1,33,0,204,220,240,227,3,62,7,99,111,110,116,101,110,116,1,161,204,220,240,227,3,60,1,40,0,204,220,240,227,3,58,7,99,111,110,116,101,110,116,1,119,36,123,34,111,112,116,105,111,110,115,34,58,91,93,44,34,100,105,115,97,98,108,101,95,99,111,108,111,114,34,58,102,97,108,115,101,125,161,204,220,240,227,3,42,1,161,204,220,240,227,3,46,1,168,251,157,254,151,3,75,1,122,0,0,0,0,102,77,165,108,168,251,157,254,151,3,76,1,119,121,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,110,103,110,85,34,44,34,110,97,109,101,34,58,34,49,49,49,34,44,34,99,111,108,111,114,34,58,34,80,105,110,107,34,125,44,123,34,105,100,34,58,34,73,73,66,100,34,44,34,110,97,109,101,34,58,34,49,50,50,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,100,105,115,97,98,108,101,95,99,111,108,111,114,34,58,102,97,108,115,101,125,161,204,220,240,227,3,64,1,161,204,220,240,227,3,63,1,168,204,220,240,227,3,70,1,122,0,0,0,0,102,77,165,117,168,204,220,240,227,3,71,1,119,121,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,89,101,75,100,34,44,34,110,97,109,101,34,58,34,51,50,49,34,44,34,99,111,108,111,114,34,58,34,80,105,110,107,34,125,44,123,34,105,100,34,58,34,104,77,109,67,34,44,34,110,97,109,101,34,58,34,49,50,51,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,100,105,115,97,98,108,101,95,99,111,108,111,114,34,58,102,97,108,115,101,125,161,204,220,240,227,3,66,1,136,204,220,240,227,3,43,1,118,1,2,105,100,119,6,70,99,112,109,80,101,39,0,251,157,254,151,3,52,6,70,99,112,109,80,101,1,40,0,204,220,240,227,3,76,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,204,220,240,227,3,67,1,136,204,220,240,227,3,47,1,118,1,2,105,100,119,6,70,99,112,109,80,101,39,0,204,220,240,227,3,16,6,70,99,112,109,80,101,1,40,0,204,220,240,227,3,80,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,2,6,70,99,112,109,80,101,1,40,0,204,220,240,227,3,82,2,105,100,1,119,6,70,99,112,109,80,101,40,0,204,220,240,227,3,82,4,110,97,109,101,1,119,4,84,101,120,116,40,0,204,220,240,227,3,82,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,120,33,0,204,220,240,227,3,82,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,204,220,240,227,3,82,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,204,220,240,227,3,82,2,116,121,1,39,0,204,220,240,227,3,82,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,204,220,240,227,3,89,1,48,1,40,0,204,220,240,227,3,90,4,100,97,116,97,1,119,0,168,204,220,240,227,3,86,1,122,0,0,0,0,102,77,165,125,168,204,220,240,227,3,88,1,122,0,0,0,0,0,0,0,5,39,0,204,220,240,227,3,89,1,53,1,161,204,220,240,227,3,74,1,136,204,220,240,227,3,75,1,118,1,2,105,100,119,6,112,70,120,57,67,45,39,0,251,157,254,151,3,52,6,112,70,120,57,67,45,1,40,0,204,220,240,227,3,97,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,204,220,240,227,3,78,1,136,204,220,240,227,3,79,1,118,1,2,105,100,119,6,112,70,120,57,67,45,39,0,204,220,240,227,3,16,6,112,70,120,57,67,45,1,40,0,204,220,240,227,3,101,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,2,6,112,70,120,57,67,45,1,40,0,204,220,240,227,3,103,2,105,100,1,119,6,112,70,120,57,67,45,40,0,204,220,240,227,3,103,4,110,97,109,101,1,119,4,84,101,120,116,40,0,204,220,240,227,3,103,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,129,33,0,204,220,240,227,3,103,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,204,220,240,227,3,103,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,204,220,240,227,3,103,2,116,121,1,39,0,204,220,240,227,3,103,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,204,220,240,227,3,110,1,48,1,40,0,204,220,240,227,3,111,4,100,97,116,97,1,119,0,168,204,220,240,227,3,107,1,122,0,0,0,0,102,77,165,135,168,204,220,240,227,3,109,1,122,0,0,0,0,0,0,0,7,39,0,204,220,240,227,3,110,1,55,1,161,204,220,240,227,3,95,1,136,204,220,240,227,3,96,1,118,1,2,105,100,119,6,101,49,98,55,48,88,39,0,251,157,254,151,3,52,6,101,49,98,55,48,88,1,40,0,204,220,240,227,3,118,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,204,220,240,227,3,99,1,136,204,220,240,227,3,100,1,118,1,2,105,100,119,6,101,49,98,55,48,88,39,0,204,220,240,227,3,16,6,101,49,98,55,48,88,1,40,0,204,220,240,227,3,122,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,2,6,101,49,98,55,48,88,1,40,0,204,220,240,227,3,124,2,105,100,1,119,6,101,49,98,55,48,88,40,0,204,220,240,227,3,124,4,110,97,109,101,1,119,4,84,101,120,116,40,0,204,220,240,227,3,124,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,151,33,0,204,220,240,227,3,124,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,204,220,240,227,3,124,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,204,220,240,227,3,124,2,116,121,1,39,0,204,220,240,227,3,124,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,204,220,240,227,3,131,1,1,48,1,40,0,204,220,240,227,3,132,1,4,100,97,116,97,1,119,0,161,204,220,240,227,3,128,1,1,168,204,220,240,227,3,130,1,1,122,0,0,0,0,0,0,0,8,39,0,204,220,240,227,3,131,1,1,56,1,40,0,204,220,240,227,3,136,1,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,40,0,204,220,240,227,3,136,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,8,40,0,204,220,240,227,3,136,1,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,204,220,240,227,3,136,1,12,105,110,99,108,117,100,101,95,116,105,109,101,1,120,168,204,220,240,227,3,134,1,1,122,0,0,0,0,102,77,165,161,40,0,204,220,240,227,3,132,1,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,204,220,240,227,3,132,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,8,40,0,204,220,240,227,3,132,1,12,105,110,99,108,117,100,101,95,116,105,109,101,1,120,40,0,204,220,240,227,3,132,1,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,161,204,220,240,227,3,116,1,161,204,220,240,227,3,120,1,161,204,220,240,227,3,146,1,1,136,204,220,240,227,3,117,1,118,1,2,105,100,119,6,80,78,113,89,102,76,39,0,251,157,254,151,3,52,6,80,78,113,89,102,76,1,40,0,204,220,240,227,3,150,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,204,220,240,227,3,147,1,1,136,204,220,240,227,3,121,1,118,1,2,105,100,119,6,80,78,113,89,102,76,39,0,204,220,240,227,3,16,6,80,78,113,89,102,76,1,40,0,204,220,240,227,3,154,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,2,6,80,78,113,89,102,76,1,40,0,204,220,240,227,3,156,1,2,105,100,1,119,6,80,78,113,89,102,76,40,0,204,220,240,227,3,156,1,4,110,97,109,101,1,119,4,84,101,120,116,40,0,204,220,240,227,3,156,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,164,33,0,204,220,240,227,3,156,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,204,220,240,227,3,156,1,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,204,220,240,227,3,156,1,2,116,121,1,39,0,204,220,240,227,3,156,1,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,204,220,240,227,3,163,1,1,48,1,40,0,204,220,240,227,3,164,1,4,100,97,116,97,1,119,0,161,204,220,240,227,3,160,1,1,168,204,220,240,227,3,162,1,1,122,0,0,0,0,0,0,0,9,39,0,204,220,240,227,3,163,1,1,57,1,40,0,204,220,240,227,3,168,1,12,105,110,99,108,117,100,101,95,116,105,109,101,1,120,40,0,204,220,240,227,3,168,1,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,204,220,240,227,3,168,1,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,40,0,204,220,240,227,3,168,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,9,168,204,220,240,227,3,166,1,1,122,0,0,0,0,102,77,165,166,40,0,204,220,240,227,3,164,1,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,204,220,240,227,3,164,1,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,40,0,204,220,240,227,3,164,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,9,40,0,204,220,240,227,3,164,1,12,105,110,99,108,117,100,101,95,116,105,109,101,1,120,161,204,220,240,227,3,148,1,1,161,204,220,240,227,3,152,1,1,161,204,220,240,227,3,178,1,1,136,204,220,240,227,3,149,1,1,118,1,2,105,100,119,6,75,71,50,113,74,65,39,0,251,157,254,151,3,52,6,75,71,50,113,74,65,1,40,0,204,220,240,227,3,182,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,161,204,220,240,227,3,179,1,1,136,204,220,240,227,3,153,1,1,118,1,2,105,100,119,6,75,71,50,113,74,65,39,0,204,220,240,227,3,16,6,75,71,50,113,74,65,1,40,0,204,220,240,227,3,186,1,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,2,6,75,71,50,113,74,65,1,40,0,204,220,240,227,3,188,1,2,105,100,1,119,6,75,71,50,113,74,65,40,0,204,220,240,227,3,188,1,4,110,97,109,101,1,119,4,84,101,120,116,40,0,204,220,240,227,3,188,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,168,33,0,204,220,240,227,3,188,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,204,220,240,227,3,188,1,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,204,220,240,227,3,188,1,2,116,121,1,39,0,204,220,240,227,3,188,1,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,204,220,240,227,3,195,1,1,48,1,40,0,204,220,240,227,3,196,1,4,100,97,116,97,1,119,0,161,204,220,240,227,3,192,1,1,168,204,220,240,227,3,194,1,1,122,0,0,0,0,0,0,0,10,39,0,204,220,240,227,3,195,1,2,49,48,1,33,0,204,220,240,227,3,200,1,11,100,97,116,97,98,97,115,101,95,105,100,1,161,204,220,240,227,3,198,1,1,40,0,204,220,240,227,3,196,1,11,100,97,116,97,98,97,115,101,95,105,100,1,119,0,161,204,220,240,227,3,180,1,1,161,204,220,240,227,3,184,1,1,168,204,220,240,227,3,202,1,1,122,0,0,0,0,102,77,165,173,168,204,220,240,227,3,201,1,1,119,36,97,100,55,100,99,52,53,98,45,52,52,98,53,45,52,57,56,102,45,98,102,97,50,45,48,102,52,51,98,102,48,53,99,99,48,100,168,204,220,240,227,3,204,1,1,122,0,0,0,0,102,77,187,135,136,204,220,240,227,3,7,1,118,2,6,104,101,105,103,104,116,125,60,2,105,100,119,36,57,50,97,50,49,51,55,101,45,98,48,48,98,45,52,51,56,56,45,56,53,49,102,45,97,48,101,102,99,51,100,101,55,99,97,51,168,204,220,240,227,3,205,1,1,122,0,0,0,0,102,77,187,135,136,204,220,240,227,3,31,1,118,2,2,105,100,119,36,57,50,97,50,49,51,55,101,45,98,48,48,98,45,52,51,56,56,45,56,53,49,102,45,97,48,101,102,99,51,100,101,55,99,97,51,6,104,101,105,103,104,116,125,60,1,243,175,215,198,3,0,161,236,192,251,208,2,8,7,105,251,157,254,151,3,0,39,1,4,100,97,116,97,8,100,97,116,97,98,97,115,101,1,40,0,251,157,254,151,3,0,2,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,39,0,251,157,254,151,3,0,6,102,105,101,108,100,115,1,39,0,251,157,254,151,3,0,5,118,105,101,119,115,1,39,0,251,157,254,151,3,0,5,109,101,116,97,115,1,40,0,251,157,254,151,3,4,3,105,105,100,1,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,39,0,251,157,254,151,3,2,6,72,95,74,113,85,76,1,40,0,251,157,254,151,3,6,2,105,100,1,119,6,72,95,74,113,85,76,40,0,251,157,254,151,3,6,4,110,97,109,101,1,119,5,84,105,116,108,101,40,0,251,157,254,151,3,6,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,101,231,40,0,251,157,254,151,3,6,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,101,231,40,0,251,157,254,151,3,6,10,105,115,95,112,114,105,109,97,114,121,1,120,40,0,251,157,254,151,3,6,2,116,121,1,122,0,0,0,0,0,0,0,0,39,0,251,157,254,151,3,6,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,251,157,254,151,3,13,1,48,1,40,0,251,157,254,151,3,14,4,100,97,116,97,1,119,0,39,0,251,157,254,151,3,2,6,55,85,107,117,54,82,1,40,0,251,157,254,151,3,16,2,105,100,1,119,6,55,85,107,117,54,82,40,0,251,157,254,151,3,16,4,110,97,109,101,1,119,4,68,97,116,101,40,0,251,157,254,151,3,16,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,101,231,40,0,251,157,254,151,3,16,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,101,231,40,0,251,157,254,151,3,16,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,251,157,254,151,3,16,2,116,121,1,122,0,0,0,0,0,0,0,2,39,0,251,157,254,151,3,16,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,251,157,254,151,3,23,1,50,1,40,0,251,157,254,151,3,24,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,3,40,0,251,157,254,151,3,24,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,40,0,251,157,254,151,3,24,11,116,105,109,101,122,111,110,101,95,105,100,1,119,0,39,0,251,157,254,151,3,2,6,95,82,45,112,104,105,1,40,0,251,157,254,151,3,28,2,105,100,1,119,6,95,82,45,112,104,105,40,0,251,157,254,151,3,28,4,110,97,109,101,1,119,4,84,97,103,115,40,0,251,157,254,151,3,28,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,101,231,33,0,251,157,254,151,3,28,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,251,157,254,151,3,28,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,251,157,254,151,3,28,2,116,121,1,122,0,0,0,0,0,0,0,4,39,0,251,157,254,151,3,28,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,251,157,254,151,3,35,1,52,1,33,0,251,157,254,151,3,36,7,99,111,110,116,101,110,116,1,39,0,251,157,254,151,3,3,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,1,40,0,251,157,254,151,3,38,2,105,100,1,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,40,0,251,157,254,151,3,38,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,251,157,254,151,3,38,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,251,157,254,151,3,38,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,101,231,33,0,251,157,254,151,3,38,11,109,111,100,105,102,105,101,100,95,97,116,1,39,0,251,157,254,151,3,38,15,108,97,121,111,117,116,95,115,101,116,116,105,110,103,115,1,39,0,251,157,254,151,3,44,1,50,1,40,0,251,157,254,151,3,45,13,115,104,111,119,95,119,101,101,107,101,110,100,115,1,120,40,0,251,157,254,151,3,45,9,108,97,121,111,117,116,95,116,121,1,122,0,0,0,0,0,0,0,0,40,0,251,157,254,151,3,45,8,102,105,101,108,100,95,105,100,1,119,6,55,85,107,117,54,82,40,0,251,157,254,151,3,45,17,102,105,114,115,116,95,100,97,121,95,111,102,95,119,101,101,107,1,122,0,0,0,0,0,0,0,0,40,0,251,157,254,151,3,45,17,115,104,111,119,95,119,101,101,107,95,110,117,109,98,101,114,115,1,120,40,0,251,157,254,151,3,38,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,39,0,251,157,254,151,3,38,14,102,105,101,108,100,95,115,101,116,116,105,110,103,115,1,39,0,251,157,254,151,3,52,6,72,95,74,113,85,76,1,40,0,251,157,254,151,3,53,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,40,0,251,157,254,151,3,53,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,0,40,0,251,157,254,151,3,53,4,119,114,97,112,1,120,39,0,251,157,254,151,3,52,6,55,85,107,117,54,82,1,40,0,251,157,254,151,3,57,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,40,0,251,157,254,151,3,57,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,40,0,251,157,254,151,3,57,4,119,114,97,112,1,120,39,0,251,157,254,151,3,52,6,95,82,45,112,104,105,1,40,0,251,157,254,151,3,61,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,40,0,251,157,254,151,3,61,5,119,105,100,116,104,1,122,0,0,0,0,0,0,0,150,40,0,251,157,254,151,3,61,4,119,114,97,112,1,120,39,0,251,157,254,151,3,38,7,102,105,108,116,101,114,115,0,39,0,251,157,254,151,3,38,6,103,114,111,117,112,115,0,39,0,251,157,254,151,3,38,5,115,111,114,116,115,0,39,0,251,157,254,151,3,38,12,102,105,101,108,100,95,111,114,100,101,114,115,0,8,0,251,157,254,151,3,68,3,118,1,2,105,100,119,6,72,95,74,113,85,76,118,1,2,105,100,119,6,55,85,107,117,54,82,118,1,2,105,100,119,6,95,82,45,112,104,105,39,0,251,157,254,151,3,38,10,114,111,119,95,111,114,100,101,114,115,0,161,251,157,254,151,3,43,1,8,0,251,157,254,151,3,72,1,118,2,2,105,100,119,36,55,55,49,55,48,55,57,98,45,48,53,98,54,45,52,97,48,97,45,56,101,101,52,45,52,56,55,51,57,102,98,102,51,97,53,50,6,104,101,105,103,104,116,125,60,161,251,157,254,151,3,32,1,161,251,157,254,151,3,37,1,161,251,157,254,151,3,73,1,136,251,157,254,151,3,71,1,118,1,2,105,100,119,6,99,78,53,98,120,74,39,0,251,157,254,151,3,52,6,99,78,53,98,120,74,1,40,0,251,157,254,151,3,79,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,251,157,254,151,3,2,6,99,78,53,98,120,74,1,40,0,251,157,254,151,3,81,2,105,100,1,119,6,99,78,53,98,120,74,40,0,251,157,254,151,3,81,4,110,97,109,101,1,119,4,84,101,120,116,40,0,251,157,254,151,3,81,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,102,8,33,0,251,157,254,151,3,81,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,40,0,251,157,254,151,3,81,10,105,115,95,112,114,105,109,97,114,121,1,121,33,0,251,157,254,151,3,81,2,116,121,1,39,0,251,157,254,151,3,81,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,251,157,254,151,3,88,1,48,1,40,0,251,157,254,151,3,89,4,100,97,116,97,1,119,0,161,251,157,254,151,3,77,1,136,251,157,254,151,3,78,1,118,1,2,105,100,119,6,71,115,66,65,97,76,39,0,251,157,254,151,3,52,6,71,115,66,65,97,76,1,40,0,251,157,254,151,3,93,10,118,105,115,105,98,105,108,105,116,121,1,122,0,0,0,0,0,0,0,1,39,0,251,157,254,151,3,2,6,71,115,66,65,97,76,1,40,0,251,157,254,151,3,95,2,105,100,1,119,6,71,115,66,65,97,76,40,0,251,157,254,151,3,95,4,110,97,109,101,1,119,4,68,97,116,101,40,0,251,157,254,151,3,95,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,102,24,40,0,251,157,254,151,3,95,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,102,24,40,0,251,157,254,151,3,95,10,105,115,95,112,114,105,109,97,114,121,1,121,40,0,251,157,254,151,3,95,2,116,121,1,122,0,0,0,0,0,0,0,2,39,0,251,157,254,151,3,95,11,116,121,112,101,95,111,112,116,105,111,110,1,39,0,251,157,254,151,3,102,1,50,1,40,0,251,157,254,151,3,103,11,116,105,109,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,0,40,0,251,157,254,151,3,103,11,116,105,109,101,122,111,110,101,95,105,100,1,119,0,40,0,251,157,254,151,3,103,11,100,97,116,101,95,102,111,114,109,97,116,1,122,0,0,0,0,0,0,0,1,1,236,192,251,208,2,0,161,145,151,150,143,2,6,9,1,145,151,150,143,2,0,161,131,222,171,184,9,38,7,1,146,214,128,188,1,0,161,212,178,171,164,8,13,65,1,162,178,170,161,1,0,161,139,202,180,177,14,32,6,2,219,228,172,146,1,0,161,247,242,142,226,14,5,1,161,130,208,239,179,11,1,9,1,231,217,162,139,1,0,161,149,159,177,202,15,1,5,19,130,208,239,179,11,1,0,2,162,178,170,161,1,1,0,6,131,222,171,184,9,1,0,39,133,224,179,154,9,1,0,2,231,217,162,139,1,1,0,5,231,138,159,208,10,1,0,2,170,249,160,147,7,1,0,21,139,202,180,177,14,1,0,33,236,192,251,208,2,1,0,9,204,220,240,227,3,39,0,1,2,1,4,1,6,1,13,1,32,1,40,3,46,1,54,1,56,1,60,1,63,2,66,2,70,2,74,1,78,1,86,1,88,1,95,1,99,1,107,1,109,1,116,1,120,1,128,1,1,130,1,1,134,1,1,146,1,3,152,1,1,160,1,1,162,1,1,166,1,1,178,1,3,184,1,1,192,1,1,194,1,1,198,1,1,201,1,2,204,1,2,145,151,150,143,2,1,0,7,146,214,128,188,1,1,0,65,243,175,215,198,3,1,0,7,212,178,171,164,8,1,0,14,149,159,177,202,15,1,0,2,149,178,144,155,15,1,0,7,247,242,142,226,14,1,0,6,219,228,172,146,1,1,0,10,251,157,254,151,3,8,32,1,37,1,43,1,73,1,75,3,85,1,87,1,91,1],"version":0,"object_id":"ce267d12-3b61-4ebb-bb03-d65272f5f817"},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/databases.json b/frontend/appflowy_web_app/cypress/fixtures/database/databases.json new file mode 100644 index 0000000000..7c06ca35ab --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/databases.json @@ -0,0 +1 @@ +[{"database_id":"037a985f-f369-4c4a-8011-620012850a68","created_at":"1713429700","views":["48c52cf7-bf98-43fa-96ad-b31aade9b071"]},{"database_id":"daea6aee-9365-4703-a8e2-a2fa6a07b214","created_at":"1714449533","views":["b6347acb-3174-4f0e-98e9-dcce07e5dbf7"]},{"database_id":"4c658817-20db-4f56-b7f9-0637a22dfeb6","created_at":"0","views":["7d2148fc-cace-4452-9c5c-96e52e6bf8b5","e410747b-5f2f-45a0-b2f7-890ad3001355","2143e95d-5dcb-4e0f-bb2c-50944e6e019f","a5566e49-f156-4168-9b2d-17926c5da329","135615fa-66f7-4451-9b54-d7e99445fca4","b4e77203-5c8b-48df-bbc5-2e1143eb0e61","a6af311f-cbc8-42c2-b801-7115619c3776"]},{"database_id":"4c658817-20db-4f56-b7f9-0637a22dfeb6","created_at":"0","views":["7d2148fc-cace-4452-9c5c-96e52e6bf8b5","e97877f5-c365-4025-9e6a-e590c4b19dbb","f0c59921-04ee-4971-995c-79b7fd8c00e2","7eb697cd-6a55-40bb-96ac-0d4a3bc924b2"]},{"database_id":"ee63da2b-aa2a-4d0b-aab0-59008635363a","created_at":"0","views":["2c1ee95a-1b09-4a1f-8d5e-501bc4861a9d","91ea7c08-f6b3-4b81-aa1e-d3664686186f"]},{"database_id":"e788f014-d0d3-4dfe-81ef-aa1ebb4d6366","created_at":"0","views":["1b0e322d-4909-4c63-914a-d034fc363097","350f425b-b671-4e2d-8182-5998a6e62924"]},{"database_id":"ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d","created_at":"0","views":["0ce13415-6cce-4497-94c6-475ad96c249e","e4c89421-12b2-4d02-863d-20949eec9271"]},{"database_id":"ce267d12-3b61-4ebb-bb03-d65272f5f817","created_at":"0","views":["ee3ae8ce-959a-4df3-8734-40b535ff88e3","66a6f3bc-c78f-4f74-a09e-08d4717bf1fd","2bf50c03-f41f-4363-b5b1-101216a6c5cc"]}] \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/rows/4c658817-20db-4f56-b7f9-0637a22dfeb6.json b/frontend/appflowy_web_app/cypress/fixtures/database/rows/4c658817-20db-4f56-b7f9-0637a22dfeb6.json new file mode 100644 index 0000000000..a55622fdfb --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/rows/4c658817-20db-4f56-b7f9-0637a22dfeb6.json @@ -0,0 +1 @@ +{"2f944220-9f45-40d9-96b5-e8c0888daf7c":[58,1,230,232,236,161,15,0,161,147,212,241,172,2,1,6,1,144,227,205,159,15,0,161,150,141,187,97,5,10,17,186,193,182,130,15,0,161,237,231,215,147,4,0,1,39,0,128,159,198,124,8,6,115,111,118,85,116,69,1,40,0,186,193,182,130,15,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,9,22,40,0,186,193,182,130,15,1,4,100,97,116,97,1,119,0,40,0,186,193,182,130,15,1,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,119,0,40,0,186,193,182,130,15,1,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,40,0,186,193,182,130,15,1,8,105,115,95,114,97,110,103,101,1,121,40,0,186,193,182,130,15,1,11,114,101,109,105,110,100,101,114,95,105,100,1,119,0,40,0,186,193,182,130,15,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,2,40,0,186,193,182,130,15,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,67,9,22,161,186,193,182,130,15,0,1,39,0,128,159,198,124,8,6,106,87,101,95,116,54,1,40,0,186,193,182,130,15,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,52,223,39,0,186,193,182,130,15,11,4,100,97,116,97,0,8,0,186,193,182,130,15,13,1,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,40,0,186,193,182,130,15,11,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,10,40,0,186,193,182,130,15,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,67,52,223,1,209,188,177,215,14,0,161,205,239,215,19,1,26,1,167,253,145,211,14,0,161,171,194,204,160,8,3,6,1,170,128,188,181,14,0,161,156,191,219,249,8,1,2,1,131,157,176,150,14,0,161,147,200,155,248,11,63,8,1,229,227,137,140,13,0,161,149,252,241,115,5,5,1,159,212,134,166,12,0,161,134,132,140,164,1,3,10,1,195,193,152,153,12,0,161,222,161,195,148,2,1,24,1,133,166,132,140,12,0,161,159,241,200,168,2,3,5,1,147,200,155,248,11,0,161,254,149,155,218,7,0,64,5,192,252,137,204,11,0,161,139,151,195,245,8,6,1,161,139,151,195,245,8,8,2,168,192,252,137,204,11,0,1,121,161,192,252,137,204,11,2,1,168,192,252,137,204,11,4,1,122,0,0,0,0,102,78,233,162,1,192,211,236,177,11,0,161,245,221,232,242,6,22,8,2,147,146,137,224,10,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,113,161,147,146,137,224,10,112,6,19,213,209,142,213,10,0,161,237,231,215,147,4,0,1,39,0,128,159,198,124,8,6,54,76,70,72,66,54,1,40,0,213,209,142,213,10,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,60,204,6,33,0,213,209,142,213,10,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,213,209,142,213,10,1,4,100,97,116,97,1,33,0,213,209,142,213,10,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,213,209,142,213,10,0,1,168,213,209,142,213,10,3,1,122,0,0,0,0,0,0,0,6,168,213,209,142,213,10,4,1,119,11,97,112,112,102,108,111,119,121,46,105,111,168,213,209,142,213,10,5,1,122,0,0,0,0,102,60,204,7,161,213,209,142,213,10,6,1,33,0,128,159,198,124,8,6,106,87,101,95,116,54,1,0,8,161,213,209,142,213,10,10,1,0,7,161,213,209,142,213,10,20,1,0,7,161,213,209,142,213,10,28,1,0,7,1,252,175,185,165,10,0,161,157,218,228,199,8,1,2,1,252,249,181,162,10,0,161,135,190,197,222,2,11,6,1,234,188,148,129,10,0,161,131,157,176,150,14,7,10,1,243,149,144,209,9,0,161,151,148,151,141,4,7,19,4,171,231,189,153,9,0,161,235,147,219,255,2,26,1,0,4,161,171,231,189,153,9,0,1,0,5,1,156,191,219,249,8,0,161,238,201,163,245,7,15,2,6,139,151,195,245,8,0,33,0,128,159,198,124,1,36,49,101,100,98,98,102,101,100,45,101,52,51,54,45,53,98,55,51,45,56,49,98,101,45,56,54,98,55,98,50,57,57,49,102,98,49,1,161,186,193,182,130,15,10,2,168,139,151,195,245,8,0,1,119,4,240,159,143,175,161,139,151,195,245,8,2,2,33,0,128,159,198,124,1,36,57,97,53,50,49,56,100,102,45,53,99,54,57,45,53,50,99,54,45,56,102,48,49,45,48,52,102,51,50,52,56,51,49,100,53,51,1,161,139,151,195,245,8,5,2,1,157,218,228,199,8,0,161,225,218,138,252,4,1,2,1,188,146,237,189,8,0,161,230,232,236,161,15,5,4,1,171,194,204,160,8,0,161,195,193,152,153,12,23,4,1,243,186,209,152,8,0,161,167,253,145,211,14,5,2,1,153,186,129,131,8,0,161,243,149,144,209,9,18,19,1,238,201,163,245,7,0,161,195,136,140,158,7,3,16,1,254,149,155,218,7,0,161,153,186,129,131,8,18,1,1,195,136,140,158,7,0,161,188,146,237,189,8,3,4,1,245,221,232,242,6,0,161,170,128,188,181,14,1,23,1,252,139,187,215,6,0,161,229,227,137,140,13,4,8,1,253,240,216,178,6,0,161,134,225,192,253,1,38,11,3,180,238,233,229,5,0,161,147,146,137,224,10,112,1,161,147,146,137,224,10,118,15,161,180,238,233,229,5,15,4,2,185,193,252,188,5,0,161,133,166,132,140,12,4,6,168,185,193,252,188,5,5,1,122,0,0,0,0,102,88,25,34,1,225,218,138,252,4,0,161,129,245,221,210,4,5,2,1,129,245,221,210,4,0,161,252,139,187,215,6,7,6,1,175,245,211,160,4,0,161,250,139,140,49,23,2,6,237,231,215,147,4,0,161,128,159,198,124,9,1,39,0,128,159,198,124,8,6,70,114,115,115,74,100,1,40,0,237,231,215,147,4,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,177,241,40,0,237,231,215,147,4,1,4,100,97,116,97,1,119,4,120,90,48,51,40,0,237,231,215,147,4,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,237,231,215,147,4,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,48,177,241,1,151,148,151,141,4,0,161,192,211,236,177,11,7,8,1,230,189,235,175,3,0,161,243,186,209,152,8,1,34,1,169,180,242,165,3,0,161,159,212,134,166,12,9,6,1,157,197,206,156,3,0,161,252,249,181,162,10,5,29,27,235,147,219,255,2,0,161,213,209,142,213,10,36,1,39,0,128,159,198,124,8,6,86,89,52,50,103,49,1,40,0,235,147,219,255,2,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,128,254,33,0,235,147,219,255,2,1,4,100,97,116,97,1,33,0,235,147,219,255,2,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,235,147,219,255,2,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,235,147,219,255,2,0,1,168,235,147,219,255,2,3,1,119,13,49,46,57,57,57,57,57,57,57,57,57,57,57,168,235,147,219,255,2,4,1,122,0,0,0,0,0,0,0,1,168,235,147,219,255,2,5,1,122,0,0,0,0,102,65,129,93,161,235,147,219,255,2,6,1,33,0,128,159,198,124,8,6,115,111,118,85,116,69,1,0,4,161,235,147,219,255,2,10,1,39,0,128,159,198,124,8,6,120,69,81,65,111,75,1,40,0,235,147,219,255,2,17,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,49,251,33,0,235,147,219,255,2,17,10,102,105,101,108,100,95,116,121,112,101,1,33,0,235,147,219,255,2,17,4,100,97,116,97,1,33,0,235,147,219,255,2,17,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,235,147,219,255,2,16,1,161,235,147,219,255,2,20,1,161,235,147,219,255,2,19,1,161,235,147,219,255,2,21,1,161,235,147,219,255,2,22,1,168,235,147,219,255,2,23,1,119,83,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,111,84,120,83,34,44,34,110,97,109,101,34,58,34,56,56,57,57,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,115,101,108,101,99,116,101,100,95,111,112,116,105,111,110,95,105,100,115,34,58,91,93,125,168,235,147,219,255,2,24,1,122,0,0,0,0,0,0,0,7,168,235,147,219,255,2,25,1,122,0,0,0,0,102,67,49,255,1,135,190,197,222,2,0,161,234,188,148,129,10,9,12,1,242,204,147,190,2,0,161,150,141,187,97,5,2,1,147,212,241,172,2,0,161,252,175,185,165,10,1,2,1,159,241,200,168,2,0,161,209,188,177,215,14,25,4,1,222,161,195,148,2,0,161,213,141,134,218,1,3,2,1,134,225,192,253,1,0,161,169,180,242,165,3,5,39,1,213,141,134,218,1,0,161,157,197,206,156,3,28,4,1,134,132,140,164,1,0,161,230,189,235,175,3,33,4,15,128,159,198,124,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,128,159,198,124,0,2,105,100,1,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,40,0,128,159,198,124,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,128,159,198,124,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,128,159,198,124,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,33,0,128,159,198,124,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,128,159,198,124,0,5,99,101,108,108,115,1,161,128,159,198,124,7,1,39,0,128,159,198,124,8,6,89,53,52,81,73,115,1,40,0,128,159,198,124,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,111,158,40,0,128,159,198,124,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,128,159,198,124,10,4,100,97,116,97,1,119,3,49,50,51,40,0,128,159,198,124,10,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,48,111,158,2,149,252,241,115,0,161,180,238,233,229,5,15,1,161,180,238,233,229,5,19,9,1,150,141,187,97,0,161,175,245,211,160,4,1,6,1,250,139,140,49,0,161,253,240,216,178,6,10,24,1,205,239,215,19,0,161,144,227,205,159,15,9,2,58,128,159,198,124,2,7,1,9,1,129,245,221,210,4,1,0,6,254,149,155,218,7,1,0,1,131,157,176,150,14,1,0,8,133,166,132,140,12,1,0,5,134,132,140,164,1,1,0,4,135,190,197,222,2,1,0,12,134,225,192,253,1,1,0,39,139,151,195,245,8,2,0,3,4,5,144,227,205,159,15,1,0,10,147,146,137,224,10,1,0,119,147,212,241,172,2,1,0,2,149,252,241,115,1,0,10,147,200,155,248,11,1,0,64,151,148,151,141,4,1,0,8,150,141,187,97,1,0,6,153,186,129,131,8,1,0,19,156,191,219,249,8,1,0,2,157,197,206,156,3,1,0,29,157,218,228,199,8,1,0,2,159,212,134,166,12,1,0,10,159,241,200,168,2,1,0,4,167,253,145,211,14,1,0,6,169,180,242,165,3,1,0,6,170,128,188,181,14,1,0,2,171,194,204,160,8,1,0,4,171,231,189,153,9,1,0,11,175,245,211,160,4,1,0,2,180,238,233,229,5,1,0,20,185,193,252,188,5,1,0,6,186,193,182,130,15,2,0,1,10,1,188,146,237,189,8,1,0,4,192,211,236,177,11,1,0,8,192,252,137,204,11,2,0,3,4,1,195,136,140,158,7,1,0,4,195,193,152,153,12,1,0,24,205,239,215,19,1,0,2,209,188,177,215,14,1,0,26,213,141,134,218,1,1,0,4,213,209,142,213,10,3,0,1,3,4,10,34,222,161,195,148,2,1,0,2,225,218,138,252,4,1,0,2,229,227,137,140,13,1,0,5,230,232,236,161,15,1,0,6,230,189,235,175,3,1,0,34,234,188,148,129,10,1,0,10,235,147,219,255,2,4,0,1,3,4,10,7,19,8,237,231,215,147,4,1,0,1,238,201,163,245,7,1,0,16,242,204,147,190,2,1,0,2,243,149,144,209,9,1,0,19,243,186,209,152,8,1,0,2,245,221,232,242,6,1,0,23,250,139,140,49,1,0,24,252,175,185,165,10,1,0,2,252,249,181,162,10,1,0,6,253,240,216,178,6,1,0,11,252,139,187,215,6,1,0,8],"318aa415-92ae-489a-a14f-a24692a2efa6":[34,16,133,247,247,224,15,0,161,204,206,244,208,8,26,1,39,0,204,206,244,208,8,9,6,70,114,115,115,74,100,1,40,0,133,247,247,224,15,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,140,55,40,0,133,247,247,224,15,1,4,100,97,116,97,1,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,40,0,133,247,247,224,15,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,133,247,247,224,15,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,65,140,55,161,133,247,247,224,15,0,1,39,0,204,206,244,208,8,9,6,115,111,118,85,116,69,1,40,0,133,247,247,224,15,7,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,65,33,0,133,247,247,224,15,7,4,100,97,116,97,1,33,0,133,247,247,224,15,7,10,102,105,101,108,100,95,116,121,112,101,1,33,0,133,247,247,224,15,7,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,133,247,247,224,15,6,1,168,133,247,247,224,15,10,1,122,0,0,0,0,0,0,0,4,168,133,247,247,224,15,9,1,119,73,57,100,48,48,56,50,51,97,45,100,57,101,50,45,52,102,98,55,45,98,100,98,54,45,99,97,102,54,101,98,99,54,99,49,50,51,44,49,99,52,102,53,52,54,57,45,54,101,49,49,45,52,55,48,51,45,57,48,56,54,45,101,98,98,50,51,57,49,53,100,53,100,56,168,133,247,247,224,15,11,1,122,0,0,0,0,102,65,147,66,1,143,148,196,184,15,0,161,241,201,182,143,5,8,2,1,246,154,152,188,14,0,161,200,145,163,182,5,11,6,1,145,225,236,177,14,0,161,160,131,157,175,8,3,2,1,252,203,148,253,13,0,161,170,153,233,132,10,11,26,1,142,228,130,255,12,0,161,143,148,196,184,15,1,6,1,182,246,158,246,11,0,161,246,154,152,188,14,5,29,2,186,166,174,226,11,0,161,212,236,181,165,9,4,6,168,186,166,174,226,11,5,1,122,0,0,0,0,102,88,25,34,1,159,139,140,218,11,0,161,173,216,200,210,1,23,4,1,214,215,253,213,11,0,161,226,183,173,212,7,23,1,1,200,218,157,187,11,0,161,248,139,142,248,1,1,35,1,145,236,232,195,10,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,8,1,214,213,255,190,10,0,161,222,208,153,250,3,38,7,1,233,137,131,159,10,0,161,145,236,232,195,10,7,10,1,215,229,183,133,10,0,161,214,215,253,213,11,0,48,1,190,196,251,132,10,0,161,200,218,157,187,11,34,4,1,170,153,233,132,10,0,161,142,228,130,255,12,5,12,1,218,242,205,188,9,0,161,190,196,251,132,10,3,10,1,212,236,181,165,9,0,161,176,202,194,187,3,2,5,34,204,206,244,208,8,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,204,206,244,208,8,0,2,105,100,1,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,40,0,204,206,244,208,8,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,204,206,244,208,8,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,204,206,244,208,8,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,204,206,244,208,8,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,11,33,0,204,206,244,208,8,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,204,206,244,208,8,0,5,99,101,108,108,115,1,161,204,206,244,208,8,8,1,39,0,204,206,244,208,8,9,6,86,89,52,50,103,49,1,40,0,204,206,244,208,8,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,15,40,0,204,206,244,208,8,11,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,1,40,0,204,206,244,208,8,11,4,100,97,116,97,1,119,3,54,54,54,40,0,204,206,244,208,8,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,61,247,15,161,204,206,244,208,8,10,1,39,0,204,206,244,208,8,9,6,106,87,101,95,116,54,1,40,0,204,206,244,208,8,17,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,83,33,0,204,206,244,208,8,17,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,204,206,244,208,8,17,8,105,115,95,114,97,110,103,101,1,33,0,204,206,244,208,8,17,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,204,206,244,208,8,17,4,100,97,116,97,1,33,0,204,206,244,208,8,17,10,102,105,101,108,100,95,116,121,112,101,1,33,0,204,206,244,208,8,17,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,204,206,244,208,8,17,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,204,206,244,208,8,16,1,168,204,206,244,208,8,19,1,119,0,161,204,206,244,208,8,23,1,168,204,206,244,208,8,24,1,121,168,204,206,244,208,8,21,1,119,21,51,50,78,50,75,100,121,72,114,104,84,55,83,99,54,76,106,78,90,100,51,161,204,206,244,208,8,22,1,168,204,206,244,208,8,20,1,121,161,204,206,244,208,8,25,1,1,217,249,214,203,8,0,161,142,228,130,255,12,5,2,1,228,182,208,185,8,0,161,227,143,130,249,4,7,10,1,160,131,157,175,8,0,161,182,246,158,246,11,28,4,1,226,183,173,212,7,0,161,233,137,131,159,10,9,24,1,200,145,163,182,5,0,161,228,182,208,185,8,9,12,1,241,201,182,143,5,0,161,214,213,255,190,10,6,9,1,227,143,130,249,4,0,161,215,229,183,133,10,47,8,1,160,249,160,227,4,0,161,159,139,140,218,11,3,6,1,222,208,153,250,3,0,161,189,166,144,23,5,39,1,176,202,194,187,3,0,161,252,203,148,253,13,25,3,1,248,139,142,248,1,0,161,160,249,160,227,4,5,2,1,173,216,200,210,1,0,161,145,225,236,177,14,1,24,5,128,181,139,77,0,168,133,247,247,224,15,12,1,122,0,0,0,0,102,67,57,178,168,204,206,244,208,8,28,1,122,0,0,0,0,0,0,0,10,167,204,206,244,208,8,31,0,8,0,128,181,139,77,2,1,119,36,50,102,57,52,52,50,50,48,45,57,102,52,53,45,52,48,100,57,45,57,54,98,53,45,101,56,99,48,56,56,56,100,97,102,55,99,168,204,206,244,208,8,33,1,122,0,0,0,0,102,67,57,178,1,189,166,144,23,0,161,218,242,205,188,9,9,6,33,133,247,247,224,15,3,0,1,6,1,9,4,200,145,163,182,5,1,0,12,200,218,157,187,11,1,0,35,204,206,244,208,8,7,8,1,10,1,16,1,19,8,28,1,31,1,33,1,142,228,130,255,12,1,0,6,143,148,196,184,15,1,0,2,145,236,232,195,10,1,0,8,145,225,236,177,14,1,0,2,212,236,181,165,9,1,0,5,214,215,253,213,11,1,0,1,215,229,183,133,10,1,0,48,214,213,255,190,10,1,0,7,217,249,214,203,8,1,0,2,218,242,205,188,9,1,0,10,222,208,153,250,3,1,0,39,159,139,140,218,11,1,0,4,160,131,157,175,8,1,0,4,160,249,160,227,4,1,0,6,226,183,173,212,7,1,0,24,227,143,130,249,4,1,0,8,228,182,208,185,8,1,0,10,233,137,131,159,10,1,0,10,170,153,233,132,10,1,0,12,173,216,200,210,1,1,0,24,176,202,194,187,3,1,0,3,241,201,182,143,5,1,0,9,246,154,152,188,14,1,0,6,182,246,158,246,11,1,0,29,248,139,142,248,1,1,0,2,186,166,174,226,11,1,0,6,252,203,148,253,13,1,0,26,189,166,144,23,1,0,6,190,196,251,132,10,1,0,4],"dd6c8d13-4867-41c6-8599-b888350f52ee":[53,1,197,130,149,248,15,0,161,158,234,217,249,6,4,8,1,235,218,250,209,15,0,161,228,141,195,172,1,28,3,1,186,200,234,175,15,0,161,147,160,184,220,9,5,12,1,253,249,233,173,15,0,161,142,253,173,141,11,1,2,1,145,176,227,152,15,0,161,227,177,139,177,7,6,2,1,213,199,181,135,15,0,161,155,234,245,236,5,17,39,9,129,162,211,229,14,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,129,162,211,229,14,0,2,105,100,1,119,36,100,100,54,99,56,100,49,51,45,52,56,54,55,45,52,49,99,54,45,56,53,57,57,45,98,56,56,56,51,53,48,102,53,50,101,101,40,0,129,162,211,229,14,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,129,162,211,229,14,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,129,162,211,229,14,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,33,0,129,162,211,229,14,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,129,162,211,229,14,0,5,99,101,108,108,115,1,1,185,146,147,208,14,0,161,222,239,172,216,10,3,2,1,250,188,188,173,14,0,161,147,160,184,220,9,5,2,1,177,253,176,145,14,0,161,139,215,211,140,4,29,1,1,153,153,172,165,13,0,161,168,180,153,248,6,23,4,2,185,249,173,251,12,0,161,155,214,174,214,9,111,16,161,185,249,173,251,12,15,4,1,138,141,245,198,12,0,161,240,197,174,164,3,5,4,1,163,150,249,138,12,0,161,174,167,159,184,4,3,9,1,225,225,173,133,12,0,161,205,245,156,144,3,7,10,1,240,245,224,143,11,0,161,163,150,249,138,12,8,6,1,142,253,173,141,11,0,161,140,141,210,196,7,15,2,1,222,239,172,216,10,0,161,158,239,153,203,9,25,4,1,160,254,254,214,10,0,161,224,134,128,190,4,5,2,1,242,190,222,204,10,0,161,213,199,181,135,15,38,8,3,212,192,173,181,10,0,161,185,249,173,251,12,15,1,161,185,249,173,251,12,19,5,161,212,192,173,181,10,5,4,1,201,249,157,231,9,0,161,240,245,224,143,11,5,39,1,147,160,184,220,9,0,161,179,235,169,194,8,1,6,1,155,214,174,214,9,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,118,1,158,239,153,203,9,0,161,220,226,182,197,1,5,26,38,150,189,211,186,9,0,161,182,238,220,247,3,24,1,39,0,129,162,211,229,14,8,6,70,114,115,115,74,100,1,40,0,150,189,211,186,9,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,140,50,33,0,150,189,211,186,9,1,4,100,97,116,97,1,33,0,150,189,211,186,9,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,150,189,211,186,9,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,150,189,211,186,9,0,1,161,150,189,211,186,9,4,1,161,150,189,211,186,9,3,1,161,150,189,211,186,9,5,1,161,150,189,211,186,9,6,1,168,150,189,211,186,9,7,1,122,0,0,0,0,0,0,0,3,168,150,189,211,186,9,8,1,119,36,54,49,50,100,50,99,51,98,45,56,50,98,99,45,52,55,51,98,45,98,49,52,53,45,55,102,53,55,49,56,54,101,51,102,55,101,168,150,189,211,186,9,9,1,122,0,0,0,0,102,65,140,51,161,150,189,211,186,9,10,1,39,0,129,162,211,229,14,8,6,115,111,118,85,116,69,1,40,0,150,189,211,186,9,15,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,58,33,0,150,189,211,186,9,15,4,100,97,116,97,1,33,0,150,189,211,186,9,15,10,102,105,101,108,100,95,116,121,112,101,1,33,0,150,189,211,186,9,15,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,150,189,211,186,9,14,1,161,150,189,211,186,9,17,1,161,150,189,211,186,9,18,1,161,150,189,211,186,9,19,1,161,150,189,211,186,9,20,1,161,150,189,211,186,9,22,1,161,150,189,211,186,9,21,1,161,150,189,211,186,9,23,1,161,150,189,211,186,9,24,1,168,150,189,211,186,9,25,1,122,0,0,0,0,0,0,0,4,168,150,189,211,186,9,26,1,119,147,1,49,99,52,102,53,52,54,57,45,54,101,49,49,45,52,55,48,51,45,57,48,56,54,45,101,98,98,50,51,57,49,53,100,53,100,56,44,57,100,48,48,56,50,51,97,45,100,57,101,50,45,52,102,98,55,45,98,100,98,54,45,99,97,102,54,101,98,99,54,99,49,50,51,44,48,52,48,102,98,48,98,102,45,50,101,100,97,45,52,99,97,51,45,56,54,99,97,45,53,98,57,49,98,55,48,50,102,101,49,54,44,52,49,57,50,51,51,57,51,45,102,55,99,51,45,52,50,51,53,45,98,54,49,51,45,102,57,97,101,56,52,102,102,53,56,56,57,168,150,189,211,186,9,27,1,122,0,0,0,0,102,65,147,60,161,150,189,211,186,9,28,1,39,0,129,162,211,229,14,8,6,89,80,102,105,50,109,1,40,0,150,189,211,186,9,33,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,206,40,0,150,189,211,186,9,33,4,100,97,116,97,1,119,3,89,101,115,40,0,150,189,211,186,9,33,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,5,40,0,150,189,211,186,9,33,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,65,147,206,2,141,231,246,230,8,0,161,229,240,171,135,7,4,1,168,141,231,246,230,8,0,1,122,0,0,0,0,102,88,25,35,1,179,235,169,194,8,0,161,137,254,221,87,15,2,1,219,210,242,162,8,0,161,235,218,250,209,15,2,5,1,140,141,210,196,7,0,161,222,168,212,145,3,3,16,1,227,177,139,177,7,0,161,153,153,172,165,13,3,7,1,229,240,171,135,7,0,161,219,210,242,162,8,4,5,1,158,234,217,249,6,0,161,212,192,173,181,10,5,5,1,168,180,153,248,6,0,161,185,146,147,208,14,1,24,1,195,153,238,185,6,0,161,145,176,227,152,15,1,35,1,144,169,186,164,6,0,161,160,254,254,214,10,1,2,1,155,234,245,236,5,0,161,253,249,233,173,15,1,18,1,202,211,156,221,5,0,161,177,253,176,145,14,0,62,1,250,181,208,232,4,0,161,144,169,186,164,6,1,2,2,224,134,128,190,4,0,161,197,130,149,248,15,7,1,161,212,192,173,181,10,9,5,1,174,167,159,184,4,0,161,195,153,238,185,6,34,4,1,139,215,211,140,4,0,161,152,171,228,253,2,9,30,34,182,238,220,247,3,0,161,129,162,211,229,14,7,1,39,0,129,162,211,229,14,8,6,86,89,52,50,103,49,1,40,0,182,238,220,247,3,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,144,110,33,0,182,238,220,247,3,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,182,238,220,247,3,1,4,100,97,116,97,1,33,0,182,238,220,247,3,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,182,238,220,247,3,0,1,168,182,238,220,247,3,4,1,119,4,56,56,56,57,168,182,238,220,247,3,3,1,122,0,0,0,0,0,0,0,1,168,182,238,220,247,3,5,1,122,0,0,0,0,102,61,145,39,161,182,238,220,247,3,6,1,39,0,129,162,211,229,14,8,6,54,76,70,72,66,54,1,40,0,182,238,220,247,3,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,145,93,33,0,182,238,220,247,3,11,10,102,105,101,108,100,95,116,121,112,101,1,33,0,182,238,220,247,3,11,4,100,97,116,97,1,33,0,182,238,220,247,3,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,182,238,220,247,3,10,1,161,182,238,220,247,3,13,1,161,182,238,220,247,3,14,1,161,182,238,220,247,3,15,1,161,182,238,220,247,3,16,1,168,182,238,220,247,3,18,1,119,9,98,97,105,100,117,46,99,111,109,168,182,238,220,247,3,17,1,122,0,0,0,0,0,0,0,6,168,182,238,220,247,3,19,1,122,0,0,0,0,102,61,145,95,161,182,238,220,247,3,20,1,39,0,129,162,211,229,14,8,6,106,87,101,95,116,54,1,40,0,182,238,220,247,3,25,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,78,33,0,182,238,220,247,3,25,10,102,105,101,108,100,95,116,121,112,101,1,40,0,182,238,220,247,3,25,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,119,0,33,0,182,238,220,247,3,25,4,100,97,116,97,1,40,0,182,238,220,247,3,25,8,105,115,95,114,97,110,103,101,1,121,40,0,182,238,220,247,3,25,11,114,101,109,105,110,100,101,114,95,105,100,1,119,0,40,0,182,238,220,247,3,25,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,33,0,182,238,220,247,3,25,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,1,240,197,174,164,3,0,161,141,225,222,162,2,1,6,1,222,168,212,145,3,0,161,138,141,245,198,12,3,4,1,205,245,156,144,3,0,161,202,211,156,221,5,61,8,1,152,171,228,253,2,0,161,242,190,222,204,10,7,10,1,141,225,222,162,2,0,161,250,181,208,232,4,1,2,5,160,193,167,129,2,0,168,150,189,211,186,9,32,1,122,0,0,0,0,102,67,57,110,168,182,238,220,247,3,27,1,122,0,0,0,0,0,0,0,10,167,182,238,220,247,3,29,0,8,0,160,193,167,129,2,2,1,119,36,51,49,56,97,97,52,49,53,45,57,50,97,101,45,52,56,57,97,45,97,49,52,102,45,97,50,52,54,57,50,97,50,101,102,97,54,168,182,238,220,247,3,33,1,122,0,0,0,0,102,67,57,110,1,220,226,182,197,1,0,161,130,157,172,36,11,6,1,228,141,195,172,1,0,161,186,200,234,175,15,11,29,1,137,254,221,87,0,161,201,249,157,231,9,38,16,1,130,157,172,36,0,161,225,225,173,133,12,9,12,52,129,162,211,229,14,1,7,1,130,157,172,36,1,0,12,195,153,238,185,6,1,0,35,197,130,149,248,15,1,0,8,201,249,157,231,9,1,0,39,138,141,245,198,12,1,0,4,139,215,211,140,4,1,0,30,140,141,210,196,7,1,0,16,205,245,156,144,3,1,0,8,141,225,222,162,2,1,0,2,142,253,173,141,11,1,0,2,144,169,186,164,6,1,0,2,145,176,227,152,15,1,0,2,202,211,156,221,5,1,0,62,137,254,221,87,1,0,16,212,192,173,181,10,1,0,10,213,199,181,135,15,1,0,39,147,160,184,220,9,1,0,6,150,189,211,186,9,5,0,1,3,8,14,1,17,12,32,1,152,171,228,253,2,1,0,10,153,153,172,165,13,1,0,4,141,231,246,230,8,1,0,1,155,214,174,214,9,1,0,118,220,226,182,197,1,1,0,6,155,234,245,236,5,1,0,18,158,239,153,203,9,1,0,26,158,234,217,249,6,1,0,5,224,134,128,190,4,1,0,6,160,254,254,214,10,1,0,2,225,225,173,133,12,1,0,10,222,168,212,145,3,1,0,4,222,239,172,216,10,1,0,4,227,177,139,177,7,1,0,7,163,150,249,138,12,1,0,9,228,141,195,172,1,1,0,29,168,180,153,248,6,1,0,24,219,210,242,162,8,1,0,5,229,240,171,135,7,1,0,5,235,218,250,209,15,1,0,3,174,167,159,184,4,1,0,4,240,197,174,164,3,1,0,6,177,253,176,145,14,1,0,1,242,190,222,204,10,1,0,8,240,245,224,143,11,1,0,6,179,235,169,194,8,1,0,2,182,238,220,247,3,8,0,1,3,4,10,1,13,8,24,1,27,1,29,1,33,1,185,249,173,251,12,1,0,20,250,181,208,232,4,1,0,2,185,146,147,208,14,1,0,2,186,200,234,175,15,1,0,12,253,249,233,173,15,1,0,2,250,188,188,173,14,1,0,2],"0160e587-41f4-4391-abb3-d322b523edb2":[34,1,169,243,176,173,14,0,161,136,210,233,249,3,12,10,1,149,233,213,204,13,0,161,200,193,211,175,13,1,26,1,200,193,211,175,13,0,161,171,146,234,226,2,9,2,1,176,222,150,172,13,0,161,189,136,144,179,10,1,6,1,174,136,245,243,12,0,161,144,251,151,19,5,39,1,145,167,143,155,12,0,161,132,147,219,143,3,6,9,2,204,172,143,149,12,0,161,148,160,235,175,1,4,7,168,204,172,143,149,12,6,1,122,0,0,0,0,102,88,25,35,28,156,179,144,186,11,0,161,214,221,216,208,2,10,1,39,0,214,221,216,208,2,9,6,70,114,115,115,74,100,1,40,0,156,179,144,186,11,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,140,60,33,0,156,179,144,186,11,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,156,179,144,186,11,1,4,100,97,116,97,1,33,0,156,179,144,186,11,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,156,179,144,186,11,0,1,168,156,179,144,186,11,4,1,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,168,156,179,144,186,11,3,1,122,0,0,0,0,0,0,0,3,168,156,179,144,186,11,5,1,122,0,0,0,0,102,65,140,110,161,156,179,144,186,11,6,1,39,0,214,221,216,208,2,9,6,115,111,118,85,116,69,1,40,0,156,179,144,186,11,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,72,33,0,156,179,144,186,11,11,10,102,105,101,108,100,95,116,121,112,101,1,33,0,156,179,144,186,11,11,4,100,97,116,97,1,33,0,156,179,144,186,11,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,156,179,144,186,11,10,1,161,156,179,144,186,11,14,1,161,156,179,144,186,11,13,1,161,156,179,144,186,11,15,1,161,156,179,144,186,11,16,1,161,156,179,144,186,11,17,1,161,156,179,144,186,11,18,1,161,156,179,144,186,11,19,1,168,156,179,144,186,11,20,1,122,0,0,0,0,102,65,147,75,168,156,179,144,186,11,21,1,119,73,102,99,100,54,101,102,56,99,45,56,99,100,54,45,52,49,98,51,45,57,50,52,53,45,57,57,56,57,51,49,100,52,57,97,49,54,44,57,100,48,48,56,50,51,97,45,100,57,101,50,45,52,102,98,55,45,98,100,98,54,45,99,97,102,54,101,98,99,54,99,49,50,51,168,156,179,144,186,11,22,1,122,0,0,0,0,0,0,0,4,168,156,179,144,186,11,23,1,122,0,0,0,0,102,65,147,75,1,146,233,137,149,11,0,161,216,226,128,250,2,9,12,1,132,204,135,146,11,0,161,246,211,137,45,5,26,1,189,136,144,179,10,0,161,145,167,143,155,12,8,2,1,190,135,128,165,10,0,161,180,231,185,129,2,3,10,1,213,169,224,237,9,0,161,244,148,242,155,4,3,6,1,227,133,204,217,9,0,161,176,222,150,172,13,5,2,1,251,233,161,212,7,0,161,213,169,224,237,9,5,3,1,255,171,204,197,7,0,161,248,180,185,229,2,3,2,1,249,211,146,138,7,0,161,149,233,213,204,13,25,3,1,203,203,186,212,6,0,161,132,132,171,141,1,29,1,1,197,235,146,149,5,0,161,251,233,161,212,7,2,34,1,187,192,226,180,4,0,161,241,252,150,189,1,47,8,1,244,148,242,155,4,0,161,176,135,229,160,1,23,4,1,136,210,233,249,3,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,13,1,132,147,219,143,3,0,161,174,136,245,243,12,38,7,1,216,226,128,250,2,0,161,187,192,226,180,4,7,10,1,248,180,185,229,2,0,161,132,204,135,146,11,25,4,2,171,146,234,226,2,0,161,176,222,150,172,13,5,1,161,227,133,204,217,9,1,9,16,214,221,216,208,2,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,214,221,216,208,2,0,2,105,100,1,119,36,48,49,54,48,101,53,56,55,45,52,49,102,52,45,52,51,57,49,45,97,98,98,51,45,100,51,50,50,98,53,50,51,101,100,98,50,40,0,214,221,216,208,2,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,214,221,216,208,2,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,214,221,216,208,2,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,214,221,216,208,2,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,182,33,0,214,221,216,208,2,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,214,221,216,208,2,0,5,99,101,108,108,115,1,161,214,221,216,208,2,8,1,39,0,214,221,216,208,2,9,6,86,89,52,50,103,49,1,40,0,214,221,216,208,2,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,198,40,0,214,221,216,208,2,11,4,100,97,116,97,1,119,3,56,56,56,40,0,214,221,216,208,2,11,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,1,40,0,214,221,216,208,2,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,61,247,198,1,180,231,185,129,2,0,161,197,235,146,149,5,33,4,1,241,252,150,189,1,0,161,203,203,186,212,6,0,48,1,148,160,235,175,1,0,161,249,211,146,138,7,2,5,1,176,135,229,160,1,0,161,255,171,204,197,7,1,24,1,132,132,171,141,1,0,161,169,243,176,173,14,9,30,1,246,211,137,45,0,161,146,233,137,149,11,11,6,1,144,251,151,19,0,161,190,135,128,165,10,9,6,34,132,132,171,141,1,1,0,30,132,204,135,146,11,1,0,26,197,235,146,149,5,1,0,34,132,147,219,143,3,1,0,7,136,210,233,249,3,1,0,13,200,193,211,175,13,1,0,2,203,203,186,212,6,1,0,1,204,172,143,149,12,1,0,7,144,251,151,19,1,0,6,145,167,143,155,12,1,0,9,146,233,137,149,11,1,0,12,148,160,235,175,1,1,0,5,213,169,224,237,9,1,0,6,149,233,213,204,13,1,0,26,214,221,216,208,2,2,8,1,10,1,216,226,128,250,2,1,0,10,156,179,144,186,11,4,0,1,3,4,10,1,13,11,227,133,204,217,9,1,0,2,169,243,176,173,14,1,0,10,171,146,234,226,2,1,0,10,174,136,245,243,12,1,0,39,176,222,150,172,13,1,0,6,176,135,229,160,1,1,0,24,241,252,150,189,1,1,0,48,244,148,242,155,4,1,0,4,180,231,185,129,2,1,0,4,246,211,137,45,1,0,6,248,180,185,229,2,1,0,4,249,211,146,138,7,1,0,3,187,192,226,180,4,1,0,8,251,233,161,212,7,1,0,3,189,136,144,179,10,1,0,2,190,135,128,165,10,1,0,10,255,171,204,197,7,1,0,2],"1cb91fa2-638d-40d6-a7c4-394f0d8b1913":[36,1,238,137,157,247,15,0,161,221,232,159,196,3,14,29,1,203,245,161,202,15,0,161,188,205,187,245,3,38,7,1,187,170,199,190,15,0,161,167,237,232,169,3,9,2,1,170,171,213,133,15,0,161,183,186,132,201,5,8,6,1,201,227,232,191,14,0,161,181,253,171,218,8,3,2,54,176,143,254,225,13,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,176,143,254,225,13,0,2,105,100,1,119,36,49,99,98,57,49,102,97,50,45,54,51,56,100,45,52,48,100,54,45,97,55,99,52,45,51,57,52,102,48,100,56,98,49,57,49,51,40,0,176,143,254,225,13,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,176,143,254,225,13,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,176,143,254,225,13,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,176,143,254,225,13,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,145,9,33,0,176,143,254,225,13,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,176,143,254,225,13,0,5,99,101,108,108,115,1,161,176,143,254,225,13,8,1,39,0,176,143,254,225,13,9,6,86,89,52,50,103,49,1,40,0,176,143,254,225,13,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,208,16,33,0,176,143,254,225,13,11,10,102,105,101,108,100,95,116,121,112,101,1,33,0,176,143,254,225,13,11,4,100,97,116,97,1,33,0,176,143,254,225,13,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,176,143,254,225,13,10,1,161,176,143,254,225,13,13,1,161,176,143,254,225,13,14,1,161,176,143,254,225,13,15,1,161,176,143,254,225,13,16,1,39,0,176,143,254,225,13,9,6,106,87,101,95,116,54,1,40,0,176,143,254,225,13,21,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,108,33,0,176,143,254,225,13,21,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,176,143,254,225,13,21,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,176,143,254,225,13,21,10,102,105,101,108,100,95,116,121,112,101,1,33,0,176,143,254,225,13,21,8,105,115,95,114,97,110,103,101,1,33,0,176,143,254,225,13,21,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,176,143,254,225,13,21,4,100,97,116,97,1,33,0,176,143,254,225,13,21,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,176,143,254,225,13,20,1,161,176,143,254,225,13,28,1,161,176,143,254,225,13,25,1,161,176,143,254,225,13,23,1,161,176,143,254,225,13,24,1,161,176,143,254,225,13,26,1,161,176,143,254,225,13,27,1,161,176,143,254,225,13,29,1,161,176,143,254,225,13,30,1,161,176,143,254,225,13,32,1,161,176,143,254,225,13,33,1,161,176,143,254,225,13,31,1,161,176,143,254,225,13,34,1,161,176,143,254,225,13,35,1,161,176,143,254,225,13,36,1,161,176,143,254,225,13,37,1,161,176,143,254,225,13,38,1,168,176,143,254,225,13,39,1,122,0,0,0,0,0,0,0,2,168,176,143,254,225,13,41,1,119,10,49,55,49,54,50,48,49,48,55,48,168,176,143,254,225,13,42,1,121,168,176,143,254,225,13,43,1,120,168,176,143,254,225,13,44,1,119,0,168,176,143,254,225,13,40,1,119,10,49,55,49,54,53,52,54,54,55,48,168,176,143,254,225,13,45,1,122,0,0,0,0,102,61,247,110,1,130,240,184,196,13,0,161,178,163,133,192,10,8,2,1,153,175,162,242,12,0,161,252,192,199,162,9,2,5,1,153,220,165,207,12,0,161,249,139,227,143,7,23,4,1,166,194,251,203,12,0,161,215,220,249,203,2,5,2,1,152,210,190,161,12,0,161,190,172,167,219,5,7,10,6,175,192,222,199,11,0,161,176,143,254,225,13,46,1,39,0,176,143,254,225,13,9,6,89,80,102,105,50,109,1,40,0,175,192,222,199,11,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,250,101,40,0,175,192,222,199,11,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,5,40,0,175,192,222,199,11,1,4,100,97,116,97,1,119,3,89,101,115,40,0,175,192,222,199,11,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,61,250,101,1,184,246,254,146,11,0,161,182,191,217,143,3,5,12,1,215,244,255,242,10,0,161,187,170,199,190,15,1,24,1,178,163,133,192,10,0,161,203,245,161,202,15,6,9,1,170,181,130,222,9,0,161,168,209,143,134,8,0,48,1,252,192,199,162,9,0,161,215,244,255,242,10,23,3,1,185,162,192,153,9,0,161,179,139,229,135,7,11,6,1,181,253,171,218,8,0,161,155,177,225,165,7,25,4,1,168,209,143,134,8,0,161,238,137,157,247,15,28,1,1,155,177,225,165,7,0,161,185,162,192,153,9,5,26,1,249,139,227,143,7,0,161,201,227,232,191,14,1,24,1,179,139,229,135,7,0,161,152,210,190,161,12,9,12,1,234,179,204,154,6,0,161,208,165,135,137,5,5,2,1,190,172,167,219,5,0,161,170,181,130,222,9,47,8,1,183,186,132,201,5,0,161,224,212,129,14,3,9,1,208,165,135,137,5,0,161,153,220,165,207,12,3,6,1,244,213,208,134,5,0,161,234,179,204,154,6,1,34,1,188,205,187,245,3,0,161,170,171,213,133,15,5,39,20,130,147,164,198,3,0,161,175,192,222,199,11,0,1,168,176,143,254,225,13,18,1,119,9,48,46,53,54,54,54,54,54,54,168,176,143,254,225,13,17,1,122,0,0,0,0,0,0,0,1,168,176,143,254,225,13,19,1,122,0,0,0,0,102,65,130,1,161,130,147,164,198,3,0,1,39,0,176,143,254,225,13,9,6,70,114,115,115,74,100,1,40,0,130,147,164,198,3,5,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,140,53,40,0,130,147,164,198,3,5,4,100,97,116,97,1,119,4,120,90,48,51,40,0,130,147,164,198,3,5,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,130,147,164,198,3,5,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,65,140,53,161,130,147,164,198,3,4,1,39,0,176,143,254,225,13,9,6,115,111,118,85,116,69,1,40,0,130,147,164,198,3,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,63,33,0,130,147,164,198,3,11,4,100,97,116,97,1,33,0,130,147,164,198,3,11,10,102,105,101,108,100,95,116,121,112,101,1,33,0,130,147,164,198,3,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,168,130,147,164,198,3,10,1,122,0,0,0,0,102,65,147,221,168,130,147,164,198,3,14,1,122,0,0,0,0,0,0,0,4,168,130,147,164,198,3,13,1,119,73,56,51,51,50,99,52,56,51,45,102,56,57,99,45,52,48,53,55,45,57,101,99,57,45,101,50,53,53,56,54,53,48,52,52,51,56,44,48,52,48,102,98,48,98,102,45,50,101,100,97,45,52,99,97,51,45,56,54,99,97,45,53,98,57,49,98,55,48,50,102,101,49,54,168,130,147,164,198,3,15,1,122,0,0,0,0,102,65,147,221,1,221,232,159,196,3,0,161,184,246,254,146,11,11,15,2,167,237,232,169,3,0,161,215,220,249,203,2,5,1,161,166,194,251,203,12,1,9,1,182,191,217,143,3,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,6,1,215,220,249,203,2,0,161,130,240,184,196,13,1,6,2,235,238,250,238,1,0,161,153,175,162,242,12,4,6,168,235,238,250,238,1,5,1,122,0,0,0,0,102,88,25,34,1,224,212,129,14,0,161,244,213,208,134,5,33,4,36,130,240,184,196,13,1,0,2,130,147,164,198,3,4,0,1,4,1,10,1,13,3,201,227,232,191,14,1,0,2,203,245,161,202,15,1,0,7,208,165,135,137,5,1,0,6,215,220,249,203,2,1,0,6,152,210,190,161,12,1,0,10,153,220,165,207,12,1,0,4,215,244,255,242,10,1,0,24,155,177,225,165,7,1,0,26,153,175,162,242,12,1,0,5,221,232,159,196,3,1,0,15,224,212,129,14,1,0,4,166,194,251,203,12,1,0,2,167,237,232,169,3,1,0,10,168,209,143,134,8,1,0,1,170,181,130,222,9,1,0,48,234,179,204,154,6,1,0,2,170,171,213,133,15,1,0,6,235,238,250,238,1,1,0,6,238,137,157,247,15,1,0,29,175,192,222,199,11,1,0,1,176,143,254,225,13,4,8,1,10,1,13,8,23,24,178,163,133,192,10,1,0,9,179,139,229,135,7,1,0,12,244,213,208,134,5,1,0,34,181,253,171,218,8,1,0,4,182,191,217,143,3,1,0,6,183,186,132,201,5,1,0,9,184,246,254,146,11,1,0,12,249,139,227,143,7,1,0,24,185,162,192,153,9,1,0,6,187,170,199,190,15,1,0,2,188,205,187,245,3,1,0,39,252,192,199,162,9,1,0,3,190,172,167,219,5,1,0,8],"3ccd17e0-d78b-44e2-afd1-1bf7cc49cb56":[34,1,206,233,228,195,15,0,161,170,189,188,208,5,5,2,1,253,134,198,190,15,0,161,193,228,168,220,13,3,2,1,153,141,151,158,15,0,161,222,235,157,159,14,8,6,1,148,232,153,164,14,0,161,136,255,156,248,4,24,3,1,222,235,157,159,14,0,161,252,145,253,197,3,3,9,1,182,194,169,138,14,0,161,169,138,231,172,3,5,2,1,193,228,168,220,13,0,161,155,223,214,152,11,25,4,2,215,249,231,218,13,0,161,145,163,160,202,11,4,6,168,215,249,231,218,13,5,1,122,0,0,0,0,102,88,25,35,1,194,189,155,132,13,0,161,144,133,245,185,2,23,1,1,226,198,237,226,12,0,161,158,166,203,46,23,4,1,137,217,190,128,12,0,161,133,194,167,165,11,38,7,42,214,218,172,227,11,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,214,218,172,227,11,0,2,105,100,1,119,36,51,99,99,100,49,55,101,48,45,100,55,56,98,45,52,52,101,50,45,97,102,100,49,45,49,98,102,55,99,99,52,57,99,98,53,54,40,0,214,218,172,227,11,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,214,218,172,227,11,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,214,218,172,227,11,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,214,218,172,227,11,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,32,33,0,214,218,172,227,11,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,214,218,172,227,11,0,5,99,101,108,108,115,1,161,214,218,172,227,11,8,1,39,0,214,218,172,227,11,9,6,86,89,52,50,103,49,1,40,0,214,218,172,227,11,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,36,40,0,214,218,172,227,11,11,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,1,40,0,214,218,172,227,11,11,4,100,97,116,97,1,119,3,55,55,55,40,0,214,218,172,227,11,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,61,247,36,161,214,218,172,227,11,10,1,39,0,214,218,172,227,11,9,6,106,87,101,95,116,54,1,40,0,214,218,172,227,11,17,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,247,92,33,0,214,218,172,227,11,17,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,214,218,172,227,11,17,8,105,115,95,114,97,110,103,101,1,33,0,214,218,172,227,11,17,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,214,218,172,227,11,17,4,100,97,116,97,1,33,0,214,218,172,227,11,17,10,102,105,101,108,100,95,116,121,112,101,1,33,0,214,218,172,227,11,17,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,214,218,172,227,11,17,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,214,218,172,227,11,16,1,161,214,218,172,227,11,21,1,161,214,218,172,227,11,23,1,161,214,218,172,227,11,19,1,161,214,218,172,227,11,20,1,161,214,218,172,227,11,24,1,161,214,218,172,227,11,22,1,161,214,218,172,227,11,25,1,161,214,218,172,227,11,26,1,168,214,218,172,227,11,27,1,119,0,168,214,218,172,227,11,32,1,119,10,49,55,49,53,57,52,49,56,48,48,168,214,218,172,227,11,29,1,120,168,214,218,172,227,11,28,1,122,0,0,0,0,0,0,0,2,168,214,218,172,227,11,30,1,121,168,214,218,172,227,11,31,1,119,21,71,99,83,71,68,56,119,81,82,81,90,116,68,101,122,109,115,122,73,97,74,168,214,218,172,227,11,33,1,122,0,0,0,0,102,61,247,101,1,179,151,213,226,11,0,161,142,245,238,213,8,11,6,1,145,163,160,202,11,0,161,148,232,153,164,14,2,5,1,133,194,167,165,11,0,161,153,141,151,158,15,5,39,1,155,223,214,152,11,0,161,179,151,213,226,11,5,26,1,182,179,204,141,10,0,161,148,207,232,183,3,11,10,1,142,245,238,213,8,0,161,179,170,225,17,9,12,6,158,225,233,217,7,0,161,214,218,172,227,11,34,1,39,0,214,218,172,227,11,9,6,89,80,102,105,50,109,1,40,0,158,225,233,217,7,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,250,105,40,0,158,225,233,217,7,1,4,100,97,116,97,1,119,3,89,101,115,40,0,158,225,233,217,7,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,5,40,0,158,225,233,217,7,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,61,250,105,1,158,231,208,154,7,0,161,148,249,197,139,5,8,2,1,170,189,188,208,5,0,161,226,198,237,226,12,3,6,2,184,177,221,199,5,0,161,169,138,231,172,3,5,1,161,182,194,169,138,14,1,11,1,148,249,197,139,5,0,161,137,217,190,128,12,6,9,1,136,255,156,248,4,0,161,184,177,221,199,5,11,25,16,208,242,145,212,4,0,161,158,225,233,217,7,0,1,39,0,214,218,172,227,11,9,6,70,114,115,115,74,100,1,40,0,208,242,145,212,4,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,140,57,40,0,208,242,145,212,4,1,4,100,97,116,97,1,119,36,54,49,50,100,50,99,51,98,45,56,50,98,99,45,52,55,51,98,45,98,49,52,53,45,55,102,53,55,49,56,54,101,51,102,55,101,40,0,208,242,145,212,4,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,208,242,145,212,4,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,65,140,57,161,208,242,145,212,4,0,1,39,0,214,218,172,227,11,9,6,115,111,118,85,116,69,1,40,0,208,242,145,212,4,7,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,68,33,0,208,242,145,212,4,7,10,102,105,101,108,100,95,116,121,112,101,1,33,0,208,242,145,212,4,7,4,100,97,116,97,1,33,0,208,242,145,212,4,7,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,168,208,242,145,212,4,6,1,122,0,0,0,0,102,65,147,69,168,208,242,145,212,4,9,1,122,0,0,0,0,0,0,0,4,168,208,242,145,212,4,10,1,119,73,52,53,53,98,100,49,56,51,45,54,54,57,102,45,52,98,49,55,45,56,99,56,57,45,56,102,56,53,48,102,102,50,48,51,54,52,44,57,97,102,51,49,102,100,53,45,98,54,53,52,45,52,54,54,54,45,98,101,101,57,45,101,50,52,55,49,51,55,50,53,49,102,53,168,208,242,145,212,4,11,1,122,0,0,0,0,102,65,147,69,1,252,145,253,197,3,0,161,222,146,227,251,2,33,4,1,148,207,232,183,3,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,12,1,169,138,231,172,3,0,161,158,231,208,154,7,1,6,1,222,146,227,251,2,0,161,206,233,228,195,15,1,34,1,144,133,245,185,2,0,161,182,179,204,141,10,9,24,1,198,237,231,132,2,0,161,194,189,155,132,13,0,48,1,153,149,181,61,0,161,198,237,231,132,2,47,8,1,158,166,203,46,0,161,253,134,198,190,15,1,24,1,179,170,225,17,0,161,153,149,181,61,7,10,34,193,228,168,220,13,1,0,4,194,189,155,132,13,1,0,1,133,194,167,165,11,1,0,39,198,237,231,132,2,1,0,48,136,255,156,248,4,1,0,25,137,217,190,128,12,1,0,7,142,245,238,213,8,1,0,12,206,233,228,195,15,1,0,2,144,133,245,185,2,1,0,24,145,163,160,202,11,1,0,5,208,242,145,212,4,3,0,1,6,1,9,3,148,207,232,183,3,1,0,12,148,249,197,139,5,1,0,9,148,232,153,164,14,1,0,3,214,218,172,227,11,4,8,1,10,1,16,1,19,16,215,249,231,218,13,1,0,6,153,149,181,61,1,0,8,153,141,151,158,15,1,0,6,155,223,214,152,11,1,0,26,158,166,203,46,1,0,24,222,146,227,251,2,1,0,34,158,225,233,217,7,1,0,1,222,235,157,159,14,1,0,9,226,198,237,226,12,1,0,4,158,231,208,154,7,1,0,2,169,138,231,172,3,1,0,6,170,189,188,208,5,1,0,6,179,170,225,17,1,0,10,179,151,213,226,11,1,0,6,182,194,169,138,14,1,0,2,182,179,204,141,10,1,0,10,184,177,221,199,5,1,0,12,252,145,253,197,3,1,0,4,253,134,198,190,15,1,0,2],"4b560c2d-3f39-4086-aa3d-c2590d129850":[23,1,171,144,240,132,15,0,161,177,185,133,253,10,8,6,1,132,180,178,130,15,0,161,209,233,132,156,1,11,28,1,156,220,236,216,13,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,17,1,208,149,239,158,11,0,161,168,150,210,229,5,33,4,1,177,185,133,253,10,0,161,208,149,239,158,11,3,9,1,207,140,163,157,10,0,161,213,152,246,243,7,6,9,1,228,231,188,223,9,0,161,230,228,200,164,7,5,2,1,160,143,150,180,9,0,161,244,180,255,255,8,1,6,1,244,180,255,255,8,0,161,207,140,163,157,10,8,2,1,213,152,246,243,7,0,161,141,170,152,151,3,38,7,1,183,242,197,235,7,0,161,160,143,150,180,9,5,2,10,159,171,231,213,7,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,159,171,231,213,7,0,2,105,100,1,119,36,52,98,53,54,48,99,50,100,45,51,102,51,57,45,52,48,56,54,45,97,97,51,100,45,99,50,53,57,48,100,49,50,57,56,53,48,40,0,159,171,231,213,7,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,159,171,231,213,7,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,159,171,231,213,7,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,159,171,231,213,7,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,69,115,240,40,0,159,171,231,213,7,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,69,115,240,39,0,159,171,231,213,7,0,5,99,101,108,108,115,1,1,240,167,210,197,7,0,161,156,220,236,216,13,16,2,1,230,228,200,164,7,0,161,151,235,176,134,1,3,6,2,246,239,129,224,6,0,161,185,162,129,222,6,4,6,168,246,239,129,224,6,5,1,122,0,0,0,0,102,88,25,34,1,185,162,129,222,6,0,161,209,145,212,136,2,2,5,1,209,227,201,148,6,0,161,254,152,161,193,3,1,24,1,168,150,210,229,5,0,161,228,231,188,223,9,1,34,1,254,152,161,193,3,0,161,240,167,210,197,7,1,2,1,141,170,152,151,3,0,161,171,144,240,132,15,5,39,1,209,145,212,136,2,0,161,132,180,178,130,15,27,3,2,209,233,132,156,1,0,161,160,143,150,180,9,5,1,161,183,242,197,235,7,1,11,1,151,235,176,134,1,0,161,209,227,201,148,6,23,4,22,160,143,150,180,9,1,0,6,228,231,188,223,9,1,0,2,132,180,178,130,15,1,0,28,230,228,200,164,7,1,0,6,168,150,210,229,5,1,0,34,171,144,240,132,15,1,0,6,141,170,152,151,3,1,0,39,207,140,163,157,10,1,0,9,240,167,210,197,7,1,0,2,209,227,201,148,6,1,0,24,208,149,239,158,11,1,0,4,177,185,133,253,10,1,0,9,244,180,255,255,8,1,0,2,213,152,246,243,7,1,0,7,209,233,132,156,1,1,0,12,151,235,176,134,1,1,0,4,183,242,197,235,7,1,0,2,209,145,212,136,2,1,0,3,185,162,129,222,6,1,0,5,246,239,129,224,6,1,0,6,156,220,236,216,13,1,0,17,254,152,161,193,3,1,0,2],"88fa36b2-6d72-44de-b0df-d3b2e6d744d6":[18,1,177,156,240,229,15,0,161,147,222,174,199,5,34,4,1,224,147,154,227,15,0,161,247,228,241,157,4,5,2,1,236,146,204,211,15,0,161,177,156,240,229,15,3,10,1,254,245,134,175,14,0,161,194,254,163,142,12,1,5,1,184,249,249,169,13,0,161,245,165,251,164,5,11,25,81,221,254,206,225,12,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,221,254,206,225,12,0,2,105,100,1,119,36,56,56,102,97,51,54,98,50,45,54,100,55,50,45,52,52,100,101,45,98,48,100,102,45,100,51,98,50,101,54,100,55,52,52,100,54,40,0,221,254,206,225,12,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,221,254,206,225,12,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,221,254,206,225,12,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,221,254,206,225,12,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,60,209,33,0,221,254,206,225,12,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,221,254,206,225,12,0,5,99,101,108,108,115,1,39,0,221,254,206,225,12,9,6,70,114,115,115,74,100,1,40,0,221,254,206,225,12,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,221,254,206,225,12,10,4,100,97,116,97,1,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,161,221,254,206,225,12,8,1,39,0,221,254,206,225,12,9,6,84,102,117,121,104,84,1,40,0,221,254,206,225,12,14,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,61,9,40,0,221,254,206,225,12,14,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,221,254,206,225,12,14,4,100,97,116,97,1,119,27,229,150,157,228,186,134,229,165,189,229,164,154,233,133,146,231,157,161,229,144,167,231,157,161,229,144,167,40,0,221,254,206,225,12,14,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,75,61,9,161,221,254,206,225,12,13,1,39,0,221,254,206,225,12,9,6,52,57,85,69,86,53,1,40,0,221,254,206,225,12,20,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,61,9,33,0,221,254,206,225,12,20,4,100,97,116,97,1,33,0,221,254,206,225,12,20,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,221,254,206,225,12,20,8,105,115,95,114,97,110,103,101,1,33,0,221,254,206,225,12,20,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,221,254,206,225,12,20,10,102,105,101,108,100,95,116,121,112,101,1,33,0,221,254,206,225,12,20,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,221,254,206,225,12,20,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,221,254,206,225,12,19,1,161,221,254,206,225,12,23,1,161,221,254,206,225,12,22,1,161,221,254,206,225,12,26,1,161,221,254,206,225,12,27,1,161,221,254,206,225,12,24,1,161,221,254,206,225,12,25,1,161,221,254,206,225,12,28,1,161,221,254,206,225,12,29,1,161,221,254,206,225,12,31,1,161,221,254,206,225,12,34,1,161,221,254,206,225,12,33,1,161,221,254,206,225,12,30,1,161,221,254,206,225,12,32,1,161,221,254,206,225,12,35,1,161,221,254,206,225,12,36,1,161,221,254,206,225,12,37,1,161,221,254,206,225,12,41,1,161,221,254,206,225,12,40,1,161,221,254,206,225,12,43,1,161,221,254,206,225,12,42,1,161,221,254,206,225,12,38,1,161,221,254,206,225,12,39,1,161,221,254,206,225,12,44,1,161,221,254,206,225,12,45,1,161,221,254,206,225,12,48,1,161,221,254,206,225,12,49,1,161,221,254,206,225,12,47,1,161,221,254,206,225,12,50,1,161,221,254,206,225,12,46,1,161,221,254,206,225,12,51,1,161,221,254,206,225,12,52,1,161,221,254,206,225,12,53,1,168,221,254,206,225,12,55,1,122,0,0,0,0,0,0,0,2,168,221,254,206,225,12,56,1,119,0,168,221,254,206,225,12,59,1,121,168,221,254,206,225,12,54,1,119,0,168,221,254,206,225,12,57,1,119,10,49,55,49,54,54,51,56,56,49,52,168,221,254,206,225,12,58,1,121,168,221,254,206,225,12,60,1,122,0,0,0,0,102,75,61,9,161,221,254,206,225,12,61,1,39,0,221,254,206,225,12,9,6,120,69,81,65,111,75,1,40,0,221,254,206,225,12,70,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,61,9,40,0,221,254,206,225,12,70,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,7,40,0,221,254,206,225,12,70,4,100,97,116,97,1,119,79,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,109,100,117,67,34,44,34,110,97,109,101,34,58,34,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,115,101,108,101,99,116,101,100,95,111,112,116,105,111,110,95,105,100,115,34,58,91,93,125,40,0,221,254,206,225,12,70,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,75,61,9,168,221,254,206,225,12,69,1,122,0,0,0,0,102,75,66,138,39,0,221,254,206,225,12,9,6,89,53,52,81,73,115,1,40,0,221,254,206,225,12,76,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,66,138,40,0,221,254,206,225,12,76,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,221,254,206,225,12,76,4,100,97,116,97,1,119,9,232,129,154,232,129,154,228,188,154,40,0,221,254,206,225,12,76,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,75,66,138,1,194,254,163,142,12,0,161,184,249,249,169,13,24,2,1,169,227,206,252,11,0,161,246,235,254,152,6,12,3,1,139,151,193,189,8,0,161,211,169,247,209,2,8,2,1,195,158,149,248,6,0,161,236,146,204,211,15,9,6,1,246,235,254,152,6,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,13,1,147,222,174,199,5,0,161,169,227,206,252,11,2,35,2,245,165,251,164,5,0,161,247,228,241,157,4,5,1,161,224,147,154,227,15,1,11,1,247,228,241,157,4,0,161,139,151,193,189,8,1,6,1,143,134,194,128,4,0,161,195,158,149,248,6,5,39,1,211,169,247,209,2,0,161,168,233,136,186,2,6,9,1,168,233,136,186,2,0,161,143,134,194,128,4,38,7,2,187,223,143,158,1,0,161,254,245,134,175,14,4,6,168,187,223,143,158,1,5,1,122,0,0,0,0,102,88,25,35,18,224,147,154,227,15,1,0,2,194,254,163,142,12,1,0,2,195,158,149,248,6,1,0,6,168,233,136,186,2,1,0,7,169,227,206,252,11,1,0,3,139,151,193,189,8,1,0,2,236,146,204,211,15,1,0,10,143,134,194,128,4,1,0,39,177,156,240,229,15,1,0,4,147,222,174,199,5,1,0,35,211,169,247,209,2,1,0,9,245,165,251,164,5,1,0,12,246,235,254,152,6,1,0,13,247,228,241,157,4,1,0,6,184,249,249,169,13,1,0,25,187,223,143,158,1,1,0,6,221,254,206,225,12,5,8,1,13,1,19,1,22,40,69,1,254,245,134,175,14,1,0,5],"1047f2d0-3757-4799-bcf2-e8f97464d2b5":[56,1,136,227,164,244,15,0,161,217,223,147,169,3,9,24,1,255,191,221,240,15,0,161,194,230,250,156,15,1,6,1,250,198,240,231,15,0,161,225,252,149,175,6,15,2,1,212,143,130,218,15,0,161,134,233,204,201,4,1,5,1,203,248,239,208,15,0,161,244,182,169,180,5,5,4,1,157,234,181,165,15,0,161,181,209,194,135,15,0,65,1,194,230,250,156,15,0,161,233,156,145,228,3,25,2,1,147,237,217,153,15,0,161,203,130,173,226,5,11,26,1,181,209,194,135,15,0,161,136,227,164,244,15,23,1,1,177,145,243,240,13,0,161,233,249,213,131,12,1,25,1,238,159,247,242,12,0,161,203,248,239,208,15,3,4,1,219,150,244,224,12,0,161,250,198,240,231,15,1,2,1,131,245,207,191,12,0,161,199,180,231,144,7,7,6,1,189,250,148,144,12,0,161,177,145,243,240,13,24,4,1,233,249,213,131,12,0,161,253,161,181,242,3,3,2,16,232,166,159,250,11,0,161,201,208,178,205,1,0,1,39,0,217,152,170,150,10,8,6,70,114,115,115,74,100,1,40,0,232,166,159,250,11,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,140,47,40,0,232,166,159,250,11,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,232,166,159,250,11,1,4,100,97,116,97,1,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,40,0,232,166,159,250,11,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,65,140,47,161,232,166,159,250,11,0,1,39,0,217,152,170,150,10,8,6,115,111,118,85,116,69,1,40,0,232,166,159,250,11,7,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,65,147,55,33,0,232,166,159,250,11,7,10,102,105,101,108,100,95,116,121,112,101,1,33,0,232,166,159,250,11,7,4,100,97,116,97,1,33,0,232,166,159,250,11,7,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,232,166,159,250,11,6,1,168,232,166,159,250,11,10,1,119,73,50,100,54,48,51,48,99,51,45,57,55,49,101,45,52,100,52,53,45,98,53,55,48,45,100,101,57,50,102,100,101,97,100,97,101,54,44,102,99,100,54,101,102,56,99,45,56,99,100,54,45,52,49,98,51,45,57,50,52,53,45,57,57,56,57,51,49,100,52,57,97,49,54,168,232,166,159,250,11,9,1,122,0,0,0,0,0,0,0,4,168,232,166,159,250,11,11,1,122,0,0,0,0,102,65,147,55,1,196,171,189,241,11,0,161,226,147,204,180,8,1,2,1,146,223,210,202,11,0,161,219,150,244,224,12,1,68,1,226,144,128,160,11,0,161,255,191,221,240,15,5,2,5,140,145,178,142,11,0,40,0,217,152,170,150,10,1,36,53,101,48,55,56,53,50,97,45,102,98,53,100,45,53,49,97,52,45,57,98,48,97,45,98,99,100,53,99,54,52,102,57,49,53,100,1,119,6,226,152,152,239,184,143,161,227,133,179,139,3,0,2,40,0,217,152,170,150,10,1,36,54,53,50,51,98,51,50,55,45,100,100,55,49,45,53,97,53,97,45,56,100,98,56,45,102,99,100,98,97,56,100,101,48,57,97,50,1,121,161,140,145,178,142,11,2,1,168,140,145,178,142,11,4,1,122,0,0,0,0,102,78,229,130,1,201,229,189,239,10,0,161,204,184,157,221,9,7,10,9,217,152,170,150,10,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,217,152,170,150,10,0,2,105,100,1,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,40,0,217,152,170,150,10,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,217,152,170,150,10,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,217,152,170,150,10,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,138,33,0,217,152,170,150,10,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,217,152,170,150,10,0,5,99,101,108,108,115,1,1,174,133,132,239,9,0,161,252,135,150,213,5,1,2,1,204,184,157,221,9,0,161,157,234,181,165,15,64,8,1,228,231,180,195,9,0,161,228,255,253,171,9,5,5,1,228,255,253,171,9,0,161,147,193,234,210,6,15,10,66,216,221,232,222,8,0,161,217,152,170,150,10,7,1,39,0,217,152,170,150,10,8,6,54,76,70,72,66,54,1,40,0,216,221,232,222,8,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,60,201,79,33,0,216,221,232,222,8,1,4,100,97,116,97,1,33,0,216,221,232,222,8,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,216,221,232,222,8,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,216,221,232,222,8,0,1,39,0,217,152,170,150,10,8,6,89,53,52,81,73,115,1,40,0,216,221,232,222,8,7,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,60,201,92,33,0,216,221,232,222,8,7,10,102,105,101,108,100,95,116,121,112,101,1,33,0,216,221,232,222,8,7,4,100,97,116,97,1,33,0,216,221,232,222,8,7,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,216,221,232,222,8,6,1,161,216,221,232,222,8,9,1,161,216,221,232,222,8,10,1,161,216,221,232,222,8,11,1,161,216,221,232,222,8,12,1,161,216,221,232,222,8,13,1,161,216,221,232,222,8,14,1,161,216,221,232,222,8,15,1,161,216,221,232,222,8,16,1,161,216,221,232,222,8,18,1,161,216,221,232,222,8,17,1,161,216,221,232,222,8,19,1,161,216,221,232,222,8,20,1,161,216,221,232,222,8,21,1,161,216,221,232,222,8,22,1,161,216,221,232,222,8,23,1,161,216,221,232,222,8,24,1,161,216,221,232,222,8,25,1,161,216,221,232,222,8,26,1,161,216,221,232,222,8,27,1,161,216,221,232,222,8,28,1,168,216,221,232,222,8,30,1,122,0,0,0,0,0,0,0,0,168,216,221,232,222,8,29,1,119,72,106,115,106,115,104,100,104,100,104,98,32,115,104,115,104,115,104,104,115,104,115,104,115,106,115,106,115,106,115,106,32,117,115,105,115,105,115,106,115,106,230,128,157,230,128,157,229,167,144,32,85,231,155,190,232,174,176,229,190,151,229,176,177,232,161,140,229,147,136,229,147,136,168,216,221,232,222,8,31,1,122,0,0,0,0,102,60,201,101,161,216,221,232,222,8,32,1,161,216,221,232,222,8,4,1,161,216,221,232,222,8,3,1,161,216,221,232,222,8,5,1,161,216,221,232,222,8,36,1,161,216,221,232,222,8,38,1,161,216,221,232,222,8,37,1,161,216,221,232,222,8,39,1,161,216,221,232,222,8,40,1,168,216,221,232,222,8,42,1,122,0,0,0,0,0,0,0,6,168,216,221,232,222,8,41,1,119,6,104,97,104,97,104,97,168,216,221,232,222,8,43,1,122,0,0,0,0,102,60,204,16,161,216,221,232,222,8,44,1,39,0,217,152,170,150,10,8,6,86,89,52,50,103,49,1,40,0,216,221,232,222,8,49,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,144,108,33,0,216,221,232,222,8,49,10,102,105,101,108,100,95,116,121,112,101,1,33,0,216,221,232,222,8,49,4,100,97,116,97,1,33,0,216,221,232,222,8,49,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,216,221,232,222,8,48,1,161,216,221,232,222,8,51,1,161,216,221,232,222,8,52,1,161,216,221,232,222,8,53,1,161,216,221,232,222,8,54,1,161,216,221,232,222,8,55,1,161,216,221,232,222,8,56,1,161,216,221,232,222,8,57,1,161,216,221,232,222,8,58,1,168,216,221,232,222,8,59,1,122,0,0,0,0,0,0,0,1,168,216,221,232,222,8,60,1,119,6,54,54,54,48,48,48,168,216,221,232,222,8,61,1,122,0,0,0,0,102,61,145,64,1,226,147,204,180,8,0,161,131,245,207,191,12,5,2,1,210,134,148,169,8,0,161,242,252,231,244,2,11,6,1,249,253,252,152,8,0,161,146,223,210,202,11,67,49,1,171,244,155,131,8,0,161,249,253,252,152,8,48,9,1,155,170,193,254,7,0,161,211,253,225,214,2,33,4,1,199,180,231,144,7,0,161,228,231,180,195,9,4,8,1,147,193,234,210,6,0,161,206,133,235,151,4,111,20,1,225,252,149,175,6,0,161,238,159,247,242,12,3,16,3,149,130,129,246,5,0,161,217,152,170,150,10,7,1,33,0,217,152,170,150,10,8,6,89,53,52,81,73,115,1,0,4,2,203,130,173,226,5,0,161,255,191,221,240,15,5,1,161,226,144,128,160,11,1,11,1,252,135,150,213,5,0,161,196,171,189,241,11,1,2,7,233,143,142,198,5,0,161,149,130,129,246,5,0,1,39,0,217,152,170,150,10,8,6,106,87,101,95,116,54,1,40,0,233,143,142,198,5,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,67,54,21,39,0,233,143,142,198,5,1,4,100,97,116,97,0,8,0,233,143,142,198,5,3,1,119,36,49,48,52,55,102,50,100,48,45,51,55,53,55,45,52,55,57,57,45,98,99,102,50,45,101,56,102,57,55,52,54,52,100,50,98,53,40,0,233,143,142,198,5,1,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,10,40,0,233,143,142,198,5,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,67,54,21,1,244,182,169,180,5,0,161,174,133,132,239,9,1,6,1,211,218,202,203,4,0,161,253,204,235,17,8,6,1,134,233,204,201,4,0,161,147,237,217,153,15,25,2,1,206,133,235,151,4,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,118,1,253,161,181,242,3,0,161,180,216,208,192,2,25,4,1,233,156,145,228,3,0,161,173,195,221,80,38,26,1,217,223,147,169,3,0,161,171,244,155,131,8,8,10,2,134,177,139,145,3,0,161,212,143,130,218,15,4,7,168,134,177,139,145,3,6,1,122,0,0,0,0,102,88,25,34,4,227,133,179,139,3,0,161,232,166,159,250,11,12,1,168,201,208,178,205,1,4,1,119,3,89,101,115,168,201,208,178,205,1,3,1,122,0,0,0,0,0,0,0,5,168,201,208,178,205,1,5,1,122,0,0,0,0,102,67,57,98,1,190,184,172,134,3,0,161,189,250,148,144,12,3,7,1,242,252,231,244,2,0,161,201,229,189,239,10,9,12,1,211,253,225,214,2,0,161,143,144,136,34,1,34,1,180,216,208,192,2,0,161,210,134,148,169,8,5,26,6,201,208,178,205,1,0,161,216,221,232,222,8,62,1,39,0,217,152,170,150,10,8,6,89,80,102,105,50,109,1,40,0,201,208,178,205,1,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,61,250,104,33,0,201,208,178,205,1,1,10,102,105,101,108,100,95,116,121,112,101,1,33,0,201,208,178,205,1,1,4,100,97,116,97,1,33,0,201,208,178,205,1,1,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,1,173,195,221,80,0,161,211,218,202,203,4,5,39,1,143,144,136,34,0,161,190,184,172,134,3,6,2,1,253,204,235,17,0,161,155,170,193,254,7,3,9,56,189,250,148,144,12,1,0,4,190,184,172,134,3,1,0,7,194,230,250,156,15,1,0,2,131,245,207,191,12,1,0,6,196,171,189,241,11,1,0,2,134,233,204,201,4,1,0,2,199,180,231,144,7,1,0,8,136,227,164,244,15,1,0,24,201,229,189,239,10,1,0,10,201,208,178,205,1,2,0,1,3,3,203,248,239,208,15,1,0,4,204,184,157,221,9,1,0,8,203,130,173,226,5,1,0,12,206,133,235,151,4,1,0,118,143,144,136,34,1,0,2,140,145,178,142,11,2,1,2,4,1,134,177,139,145,3,1,0,7,146,223,210,202,11,1,0,68,147,193,234,210,6,1,0,20,210,134,148,169,8,1,0,6,211,253,225,214,2,1,0,34,211,218,202,203,4,1,0,6,147,237,217,153,15,1,0,26,212,143,130,218,15,1,0,5,217,223,147,169,3,1,0,10,217,152,170,150,10,1,7,1,219,150,244,224,12,1,0,2,155,170,193,254,7,1,0,4,157,234,181,165,15,1,0,65,216,221,232,222,8,6,0,1,3,4,9,24,36,9,48,1,51,12,149,130,129,246,5,1,0,6,225,252,149,175,6,1,0,16,226,147,204,180,8,1,0,2,226,144,128,160,11,1,0,2,228,255,253,171,9,1,0,10,228,231,180,195,9,1,0,5,227,133,179,139,3,1,0,1,232,166,159,250,11,3,0,1,6,1,9,4,233,249,213,131,12,1,0,2,233,156,145,228,3,1,0,26,171,244,155,131,8,1,0,9,233,143,142,198,5,1,0,1,173,195,221,80,1,0,39,238,159,247,242,12,1,0,4,174,133,132,239,9,1,0,2,177,145,243,240,13,1,0,25,242,252,231,244,2,1,0,12,244,182,169,180,5,1,0,6,181,209,194,135,15,1,0,1,180,216,208,192,2,1,0,26,249,253,252,152,8,1,0,49,250,198,240,231,15,1,0,2,252,135,150,213,5,1,0,2,253,204,235,17,1,0,9,253,161,181,242,3,1,0,4,255,191,221,240,15,1,0,6],"3aadcc41-4b4d-4570-a5de-06ebe3f460ec":[19,1,198,208,139,248,15,0,161,232,249,153,165,14,34,4,2,178,201,178,226,15,0,161,249,156,177,132,11,4,6,168,178,201,178,226,15,5,1,122,0,0,0,0,102,88,25,35,1,217,221,136,169,15,0,161,247,190,164,130,3,1,6,1,239,247,162,248,14,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,8,1,130,223,137,178,14,0,161,238,205,207,218,4,8,6,1,232,249,153,165,14,0,161,187,231,222,18,1,35,1,214,231,164,137,11,0,161,217,221,136,169,15,5,2,1,249,156,177,132,11,0,161,163,196,200,219,4,1,5,1,238,165,252,166,9,0,161,192,192,155,154,2,1,25,1,157,244,237,240,7,0,161,129,142,211,195,2,6,9,1,163,196,200,219,4,0,161,238,165,252,166,9,24,2,1,238,205,207,218,4,0,161,198,208,139,248,15,3,9,1,220,144,217,197,4,0,161,130,223,137,178,14,5,39,2,176,222,138,182,3,0,161,217,221,136,169,15,5,1,161,214,231,164,137,11,1,9,19,217,192,185,135,3,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,217,192,185,135,3,0,2,105,100,1,119,36,51,97,97,100,99,99,52,49,45,52,98,52,100,45,52,53,55,48,45,97,53,100,101,45,48,54,101,98,101,51,102,52,54,48,101,99,40,0,217,192,185,135,3,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,52,99,54,53,56,56,49,55,45,50,48,100,98,45,52,102,53,54,45,98,55,102,57,45,48,54,51,55,97,50,50,100,102,101,98,54,40,0,217,192,185,135,3,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,217,192,185,135,3,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,217,192,185,135,3,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,60,195,33,0,217,192,185,135,3,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,217,192,185,135,3,0,5,99,101,108,108,115,1,39,0,217,192,185,135,3,9,6,70,114,115,115,74,100,1,40,0,217,192,185,135,3,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,217,192,185,135,3,10,4,100,97,116,97,1,119,36,48,52,102,52,55,48,51,55,45,49,56,54,97,45,52,56,55,102,45,98,54,56,101,45,102,49,98,102,97,48,102,101,54,54,53,101,168,217,192,185,135,3,8,1,122,0,0,0,0,102,75,60,207,39,0,217,192,185,135,3,9,6,84,102,117,121,104,84,1,40,0,217,192,185,135,3,14,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,75,60,207,40,0,217,192,185,135,3,14,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,217,192,185,135,3,14,4,100,97,116,97,1,119,18,229,147,136,229,147,136,229,147,136,229,147,136,229,147,136,229,147,136,40,0,217,192,185,135,3,14,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,75,60,207,1,247,190,164,130,3,0,161,157,244,237,240,7,8,2,1,129,142,211,195,2,0,161,220,144,217,197,4,38,7,1,192,192,155,154,2,0,161,176,222,138,182,3,9,2,1,187,231,222,18,0,161,239,247,162,248,14,7,2,19,192,192,155,154,2,1,0,2,129,142,211,195,2,1,0,7,130,223,137,178,14,1,0,6,163,196,200,219,4,1,0,2,198,208,139,248,15,1,0,4,232,249,153,165,14,1,0,35,238,165,252,166,9,1,0,25,238,205,207,218,4,1,0,9,176,222,138,182,3,1,0,10,239,247,162,248,14,1,0,8,178,201,178,226,15,1,0,6,214,231,164,137,11,1,0,2,247,190,164,130,3,1,0,2,217,221,136,169,15,1,0,6,249,156,177,132,11,1,0,5,187,231,222,18,1,0,2,220,144,217,197,4,1,0,39,157,244,237,240,7,1,0,9,217,192,185,135,3,1,8,1]} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/rows/ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d.json b/frontend/appflowy_web_app/cypress/fixtures/database/rows/ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d.json new file mode 100644 index 0000000000..10fc50a811 --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/rows/ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d.json @@ -0,0 +1 @@ +{"208d248f-5c08-4be5-a022-e0a97c2d705e":[16,1,162,212,253,234,14,0,161,166,231,212,218,8,3,39,1,245,198,128,205,14,0,161,233,140,128,164,8,5,2,1,165,222,139,132,12,0,161,128,181,233,166,8,1,7,1,179,227,145,238,11,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,10,2,213,228,161,169,9,0,161,233,140,128,164,8,5,1,161,245,198,128,205,14,1,9,2,185,222,141,169,9,0,161,140,225,231,182,6,2,4,168,185,222,141,169,9,3,1,122,0,0,0,0,102,88,52,85,1,138,182,251,229,8,0,161,162,212,253,234,14,38,7,1,166,231,212,218,8,0,161,165,222,139,132,12,6,4,1,128,181,233,166,8,0,161,179,227,145,238,11,9,2,1,233,140,128,164,8,0,161,221,230,177,144,4,1,6,1,239,245,240,149,8,0,161,157,238,145,201,3,1,2,1,140,225,231,182,6,0,161,239,245,240,149,8,1,3,1,246,148,237,174,6,0,161,138,182,251,229,8,6,5,16,221,174,135,220,5,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,221,174,135,220,5,0,2,105,100,1,119,36,50,48,56,100,50,52,56,102,45,53,99,48,56,45,52,98,101,53,45,97,48,50,50,45,101,48,97,57,55,99,50,100,55,48,53,101,40,0,221,174,135,220,5,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,97,100,55,100,99,52,53,98,45,52,52,98,53,45,52,57,56,102,45,98,102,97,50,45,48,102,52,51,98,102,48,53,99,99,48,100,40,0,221,174,135,220,5,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,221,174,135,220,5,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,221,174,135,220,5,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,39,162,40,0,221,174,135,220,5,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,39,162,39,0,221,174,135,220,5,0,5,99,101,108,108,115,1,39,0,221,174,135,220,5,9,6,121,52,52,50,48,119,1,40,0,221,174,135,220,5,10,4,100,97,116,97,1,119,4,117,76,117,51,40,0,221,174,135,220,5,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,39,0,221,174,135,220,5,9,6,51,111,45,90,115,109,1,40,0,221,174,135,220,5,13,4,100,97,116,97,1,119,6,67,97,114,100,32,49,40,0,221,174,135,220,5,13,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,1,221,230,177,144,4,0,161,246,148,237,174,6,4,2,1,157,238,145,201,3,0,161,213,228,161,169,9,9,2,15,128,181,233,166,8,1,0,2,162,212,253,234,14,1,0,39,165,222,139,132,12,1,0,7,166,231,212,218,8,1,0,4,233,140,128,164,8,1,0,6,138,182,251,229,8,1,0,7,140,225,231,182,6,1,0,3,239,245,240,149,8,1,0,2,179,227,145,238,11,1,0,10,245,198,128,205,14,1,0,2,246,148,237,174,6,1,0,5,213,228,161,169,9,1,0,10,185,222,141,169,9,1,0,4,221,230,177,144,4,1,0,2,157,238,145,201,3,1,0,2]} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/database/rows/ce267d12-3b61-4ebb-bb03-d65272f5f817.json b/frontend/appflowy_web_app/cypress/fixtures/database/rows/ce267d12-3b61-4ebb-bb03-d65272f5f817.json new file mode 100644 index 0000000000..9820d03b24 --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/database/rows/ce267d12-3b61-4ebb-bb03-d65272f5f817.json @@ -0,0 +1 @@ +{"a00ecf78-a823-43f1-b542-ed071394a717":[14,1,235,137,137,244,15,0,161,252,139,206,213,10,1,2,1,133,172,162,242,15,0,161,137,192,210,179,15,1,2,2,186,176,205,207,15,0,161,196,230,218,150,10,3,2,168,186,176,205,207,15,1,1,122,0,0,0,0,102,88,31,89,1,137,192,210,179,15,0,161,235,137,137,244,15,1,2,1,245,193,213,231,13,0,161,153,225,207,224,1,1,2,1,246,177,194,222,13,0,161,133,172,162,242,15,1,6,1,205,151,244,151,13,0,161,246,177,194,222,13,5,12,23,239,227,232,242,10,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,239,227,232,242,10,0,2,105,100,1,119,36,97,48,48,101,99,102,55,56,45,97,56,50,51,45,52,51,102,49,45,98,53,52,50,45,101,100,48,55,49,51,57,52,97,55,49,55,40,0,239,227,232,242,10,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,239,227,232,242,10,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,239,227,232,242,10,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,239,227,232,242,10,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,121,252,33,0,239,227,232,242,10,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,239,227,232,242,10,0,5,99,101,108,108,115,1,39,0,239,227,232,242,10,9,6,55,85,107,117,54,82,1,40,0,239,227,232,242,10,10,4,100,97,116,97,1,119,10,49,55,49,54,51,48,55,50,48,48,40,0,239,227,232,242,10,10,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,119,0,40,0,239,227,232,242,10,10,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,40,0,239,227,232,242,10,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,2,40,0,239,227,232,242,10,10,8,105,115,95,114,97,110,103,101,1,121,40,0,239,227,232,242,10,10,11,114,101,109,105,110,100,101,114,95,105,100,1,119,0,168,239,227,232,242,10,8,1,122,0,0,0,0,102,77,124,84,39,0,239,227,232,242,10,9,6,72,95,74,113,85,76,1,40,0,239,227,232,242,10,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,124,84,40,0,239,227,232,242,10,18,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,239,227,232,242,10,18,4,100,97,116,97,1,119,5,49,49,49,49,49,40,0,239,227,232,242,10,18,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,124,84,1,252,139,206,213,10,0,161,155,206,144,191,3,37,2,1,222,138,222,196,10,0,161,246,177,194,222,13,5,2,1,196,230,218,150,10,0,161,245,193,213,231,13,1,4,1,239,171,159,202,8,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,15,1,155,206,144,191,3,0,161,239,171,159,202,8,14,38,1,153,225,207,224,1,0,161,205,151,244,151,13,11,2,14,235,137,137,244,15,1,0,2,205,151,244,151,13,1,0,12,239,171,159,202,8,1,0,15,196,230,218,150,10,1,0,4,245,193,213,231,13,1,0,2,246,177,194,222,13,1,0,6,133,172,162,242,15,1,0,2,137,192,210,179,15,1,0,2,186,176,205,207,15,1,0,2,153,225,207,224,1,1,0,2,155,206,144,191,3,1,0,38,252,139,206,213,10,1,0,2,222,138,222,196,10,1,0,2,239,227,232,242,10,1,8,1],"a73674ae-3301-45a3-b801-3f12e6fcb566":[16,1,216,136,201,234,15,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,14,8,151,154,187,181,15,0,161,167,192,205,202,8,78,1,161,167,192,205,202,8,54,1,161,167,192,205,202,8,53,1,161,167,192,205,202,8,55,1,168,151,154,187,181,15,0,1,122,0,0,0,0,102,80,8,134,168,151,154,187,181,15,2,1,119,2,104,105,168,151,154,187,181,15,1,1,122,0,0,0,0,0,0,0,0,168,151,154,187,181,15,3,1,122,0,0,0,0,102,80,8,134,1,225,161,205,165,15,0,161,236,244,246,235,2,1,4,1,232,241,163,254,12,0,161,216,136,201,234,15,13,28,1,243,242,150,150,12,0,161,198,181,227,192,1,1,2,1,170,212,149,201,11,0,161,232,241,163,254,12,27,39,1,203,244,164,187,11,0,161,189,165,195,186,4,11,6,2,225,242,132,222,9,0,161,225,161,205,165,15,3,2,168,225,242,132,222,9,1,1,122,0,0,0,0,102,88,31,91,82,167,192,205,202,8,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,167,192,205,202,8,0,2,105,100,1,119,36,97,55,51,54,55,52,97,101,45,51,51,48,49,45,52,53,97,51,45,98,56,48,49,45,51,102,49,50,101,54,102,99,98,53,54,54,40,0,167,192,205,202,8,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,167,192,205,202,8,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,167,192,205,202,8,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,167,192,205,202,8,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,88,135,33,0,167,192,205,202,8,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,167,192,205,202,8,0,5,99,101,108,108,115,1,39,0,167,192,205,202,8,9,6,55,85,107,117,54,82,1,33,0,167,192,205,202,8,10,10,102,105,101,108,100,95,116,121,112,101,1,33,0,167,192,205,202,8,10,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,167,192,205,202,8,10,8,105,115,95,114,97,110,103,101,1,33,0,167,192,205,202,8,10,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,167,192,205,202,8,10,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,167,192,205,202,8,10,4,100,97,116,97,1,161,167,192,205,202,8,8,1,39,0,167,192,205,202,8,9,6,95,82,45,112,104,105,1,40,0,167,192,205,202,8,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,88,139,40,0,167,192,205,202,8,18,4,100,97,116,97,1,119,4,73,73,66,100,40,0,167,192,205,202,8,18,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,4,40,0,167,192,205,202,8,18,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,88,139,161,167,192,205,202,8,17,1,40,0,167,192,205,202,8,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,88,142,168,167,192,205,202,8,13,1,121,168,167,192,205,202,8,11,1,122,0,0,0,0,0,0,0,2,168,167,192,205,202,8,15,1,119,0,168,167,192,205,202,8,14,1,119,0,168,167,192,205,202,8,16,1,119,10,49,55,49,54,54,48,52,49,55,52,168,167,192,205,202,8,12,1,121,40,0,167,192,205,202,8,10,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,88,142,161,167,192,205,202,8,23,1,39,0,167,192,205,202,8,9,6,71,115,66,65,97,76,1,40,0,167,192,205,202,8,33,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,88,150,33,0,167,192,205,202,8,33,8,105,115,95,114,97,110,103,101,1,33,0,167,192,205,202,8,33,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,167,192,205,202,8,33,10,102,105,101,108,100,95,116,121,112,101,1,33,0,167,192,205,202,8,33,4,100,97,116,97,1,33,0,167,192,205,202,8,33,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,167,192,205,202,8,33,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,167,192,205,202,8,33,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,167,192,205,202,8,32,1,168,167,192,205,202,8,39,1,119,0,168,167,192,205,202,8,38,1,119,10,49,55,49,55,49,50,50,53,56,51,168,167,192,205,202,8,37,1,122,0,0,0,0,0,0,0,2,168,167,192,205,202,8,40,1,121,168,167,192,205,202,8,35,1,121,168,167,192,205,202,8,36,1,119,0,168,167,192,205,202,8,41,1,122,0,0,0,0,102,77,88,151,161,167,192,205,202,8,42,1,39,0,167,192,205,202,8,9,6,72,95,74,113,85,76,1,40,0,167,192,205,202,8,51,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,75,33,0,167,192,205,202,8,51,4,100,97,116,97,1,33,0,167,192,205,202,8,51,10,102,105,101,108,100,95,116,121,112,101,1,33,0,167,192,205,202,8,51,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,167,192,205,202,8,50,1,39,0,167,192,205,202,8,9,6,99,78,53,98,120,74,1,40,0,167,192,205,202,8,57,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,89,40,0,167,192,205,202,8,57,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,6,40,0,167,192,205,202,8,57,4,100,97,116,97,1,119,3,49,50,51,40,0,167,192,205,202,8,57,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,89,161,167,192,205,202,8,56,1,39,0,167,192,205,202,8,9,6,71,79,80,107,116,118,1,40,0,167,192,205,202,8,63,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,117,40,0,167,192,205,202,8,63,4,100,97,116,97,1,119,4,89,101,75,100,40,0,167,192,205,202,8,63,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,167,192,205,202,8,63,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,117,161,167,192,205,202,8,62,1,39,0,167,192,205,202,8,9,6,112,70,120,57,67,45,1,40,0,167,192,205,202,8,69,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,142,33,0,167,192,205,202,8,69,10,102,105,101,108,100,95,116,121,112,101,1,33,0,167,192,205,202,8,69,4,100,97,116,97,1,33,0,167,192,205,202,8,69,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,167,192,205,202,8,68,1,161,167,192,205,202,8,71,1,161,167,192,205,202,8,72,1,161,167,192,205,202,8,73,1,161,167,192,205,202,8,74,1,168,167,192,205,202,8,75,1,122,0,0,0,0,0,0,0,7,168,167,192,205,202,8,76,1,119,134,1,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,99,72,80,113,34,44,34,110,97,109,101,34,58,34,51,51,51,51,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,44,123,34,105,100,34,58,34,74,106,52,74,34,44,34,110,97,109,101,34,58,34,51,51,51,51,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,115,101,108,101,99,116,101,100,95,111,112,116,105,111,110,95,105,100,115,34,58,91,34,99,72,80,113,34,93,125,168,167,192,205,202,8,77,1,122,0,0,0,0,102,77,165,145,1,170,185,193,131,8,0,161,210,149,158,230,4,5,2,1,194,218,151,236,5,0,161,170,212,149,201,11,38,2,1,210,149,158,230,4,0,161,143,148,251,251,1,1,6,2,189,165,195,186,4,0,161,210,149,158,230,4,5,1,161,170,185,193,131,8,1,11,1,236,244,246,235,2,0,161,203,244,164,187,11,5,2,1,143,148,251,251,1,0,161,243,242,150,150,12,1,2,1,198,181,227,192,1,0,161,194,218,151,236,5,1,2,16,225,161,205,165,15,1,0,4,194,218,151,236,5,1,0,2,225,242,132,222,9,1,0,2,198,181,227,192,1,1,0,2,167,192,205,202,8,10,8,1,11,7,23,1,32,1,35,8,50,1,53,4,62,1,68,1,71,8,232,241,163,254,12,1,0,28,170,212,149,201,11,1,0,39,170,185,193,131,8,1,0,2,236,244,246,235,2,1,0,2,203,244,164,187,11,1,0,6,143,148,251,251,1,1,0,2,210,149,158,230,4,1,0,6,243,242,150,150,12,1,0,2,151,154,187,181,15,1,0,4,216,136,201,234,15,1,0,14,189,165,195,186,4,1,0,12],"51cf0906-ad46-4dae-a3b9-2e003f8368c1":[15,1,196,176,146,143,13,0,161,211,131,137,205,5,5,12,1,175,214,229,215,11,0,161,164,251,162,159,11,1,4,1,167,131,238,183,11,0,161,218,233,217,251,6,1,2,1,164,251,162,159,11,0,161,135,135,213,129,7,1,2,1,252,183,246,136,10,0,161,211,131,137,205,5,5,2,1,184,218,170,237,8,0,161,226,213,154,133,6,7,16,1,253,213,204,144,8,0,161,254,207,234,185,3,1,2,1,135,135,213,129,7,0,161,196,176,146,143,13,11,2,1,218,233,217,251,6,0,161,213,133,230,230,2,38,2,1,226,213,154,133,6,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,8,1,211,131,137,205,5,0,161,253,213,204,144,8,1,6,2,205,251,166,251,4,0,161,175,214,229,215,11,3,2,168,205,251,166,251,4,1,1,122,0,0,0,0,102,88,31,89,30,239,237,241,245,4,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,239,237,241,245,4,0,2,105,100,1,119,36,53,49,99,102,48,57,48,54,45,97,100,52,54,45,52,100,97,101,45,97,51,98,57,45,50,101,48,48,51,102,56,51,54,56,99,49,40,0,239,237,241,245,4,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,239,237,241,245,4,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,239,237,241,245,4,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,239,237,241,245,4,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,95,173,33,0,239,237,241,245,4,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,239,237,241,245,4,0,5,99,101,108,108,115,1,39,0,239,237,241,245,4,9,6,55,85,107,117,54,82,1,40,0,239,237,241,245,4,10,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,40,0,239,237,241,245,4,10,11,114,101,109,105,110,100,101,114,95,105,100,1,119,0,40,0,239,237,241,245,4,10,4,100,97,116,97,1,119,10,49,55,49,54,51,48,55,50,48,48,40,0,239,237,241,245,4,10,8,105,115,95,114,97,110,103,101,1,121,40,0,239,237,241,245,4,10,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,119,0,40,0,239,237,241,245,4,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,2,161,239,237,241,245,4,8,1,39,0,239,237,241,245,4,9,6,72,95,74,113,85,76,1,40,0,239,237,241,245,4,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,79,40,0,239,237,241,245,4,18,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,239,237,241,245,4,18,4,100,97,116,97,1,119,2,48,48,40,0,239,237,241,245,4,18,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,79,168,239,237,241,245,4,17,1,122,0,0,0,0,102,77,165,181,39,0,239,237,241,245,4,9,6,75,71,50,113,74,65,1,40,0,239,237,241,245,4,24,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,181,40,0,239,237,241,245,4,24,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,10,39,0,239,237,241,245,4,24,4,100,97,116,97,0,8,0,239,237,241,245,4,27,1,119,36,100,51,50,101,52,56,97,52,45,99,102,48,100,45,52,56,97,56,45,57,53,57,57,45,53,51,51,57,97,56,49,53,56,99,53,48,40,0,239,237,241,245,4,24,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,181,1,254,207,234,185,3,0,161,167,131,238,183,11,1,2,1,213,133,230,230,2,0,161,184,218,170,237,8,15,39,15,226,213,154,133,6,1,0,8,196,176,146,143,13,1,0,12,164,251,162,159,11,1,0,2,135,135,213,129,7,1,0,2,167,131,238,183,11,1,0,2,205,251,166,251,4,1,0,2,175,214,229,215,11,1,0,4,239,237,241,245,4,2,8,1,17,1,211,131,137,205,5,1,0,6,213,133,230,230,2,1,0,39,184,218,170,237,8,1,0,16,218,233,217,251,6,1,0,2,252,183,246,136,10,1,0,2,253,213,204,144,8,1,0,2,254,207,234,185,3,1,0,2],"92a2137e-b00b-4388-851f-a0efc3de7ca3":[13,1,238,246,169,231,15,0,161,163,149,186,140,1,3,2,1,148,143,229,148,15,0,161,170,241,252,142,10,38,2,1,142,159,154,239,14,0,161,199,176,167,174,6,5,12,1,237,148,148,223,13,0,161,222,150,248,170,3,2,4,1,195,215,232,135,13,0,161,199,176,167,174,6,5,2,1,170,241,252,142,10,0,161,132,169,228,37,13,39,26,227,145,252,193,9,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,227,145,252,193,9,0,2,105,100,1,119,36,57,50,97,50,49,51,55,101,45,98,48,48,98,45,52,51,56,56,45,56,53,49,102,45,97,48,101,102,99,51,100,101,55,99,97,51,40,0,227,145,252,193,9,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,227,145,252,193,9,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,227,145,252,193,9,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,227,145,252,193,9,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,187,135,33,0,227,145,252,193,9,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,227,145,252,193,9,0,5,99,101,108,108,115,1,161,227,145,252,193,9,8,1,39,0,227,145,252,193,9,9,6,72,95,74,113,85,76,1,40,0,227,145,252,193,9,11,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,187,143,33,0,227,145,252,193,9,11,10,102,105,101,108,100,95,116,121,112,101,1,33,0,227,145,252,193,9,11,4,100,97,116,97,1,33,0,227,145,252,193,9,11,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,227,145,252,193,9,10,1,168,227,145,252,193,9,14,1,119,7,57,57,57,57,57,50,50,168,227,145,252,193,9,13,1,122,0,0,0,0,0,0,0,0,168,227,145,252,193,9,15,1,122,0,0,0,0,102,77,187,221,168,227,145,252,193,9,16,1,122,0,0,0,0,102,77,187,222,39,0,227,145,252,193,9,9,6,95,82,45,112,104,105,1,40,0,227,145,252,193,9,21,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,187,222,40,0,227,145,252,193,9,21,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,4,40,0,227,145,252,193,9,21,4,100,97,116,97,1,119,4,73,73,66,100,40,0,227,145,252,193,9,21,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,187,222,1,199,176,167,174,6,0,161,238,246,169,231,15,1,6,1,166,146,188,210,5,0,161,142,159,154,239,14,11,2,1,222,150,248,170,3,0,161,166,146,188,210,5,1,3,2,149,229,205,200,1,0,161,237,148,148,223,13,3,2,168,149,229,205,200,1,1,1,122,0,0,0,0,102,88,31,89,1,163,149,186,140,1,0,161,148,143,229,148,15,1,4,1,132,169,228,37,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,14,13,238,246,169,231,15,1,0,2,195,215,232,135,13,1,0,2,163,149,186,140,1,1,0,4,132,169,228,37,1,0,14,148,143,229,148,15,1,0,2,199,176,167,174,6,1,0,6,166,146,188,210,5,1,0,2,227,145,252,193,9,3,8,1,10,1,13,4,170,241,252,142,10,1,0,39,149,229,205,200,1,1,0,2,237,148,148,223,13,1,0,4,222,150,248,170,3,1,0,3,142,159,154,239,14,1,0,12],"2150cff6-ff80-4334-8c8a-94e82a64379a":[15,35,184,224,238,246,15,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,184,224,238,246,15,0,2,105,100,1,119,36,50,49,53,48,99,102,102,54,45,102,102,56,48,45,52,51,51,52,45,56,99,56,97,45,57,52,101,56,50,97,54,52,51,55,57,97,40,0,184,224,238,246,15,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,184,224,238,246,15,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,184,224,238,246,15,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,184,224,238,246,15,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,95,172,33,0,184,224,238,246,15,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,184,224,238,246,15,0,5,99,101,108,108,115,1,39,0,184,224,238,246,15,9,6,55,85,107,117,54,82,1,40,0,184,224,238,246,15,10,4,100,97,116,97,1,119,10,49,55,49,54,51,48,55,50,48,48,40,0,184,224,238,246,15,10,11,114,101,109,105,110,100,101,114,95,105,100,1,119,0,40,0,184,224,238,246,15,10,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,2,40,0,184,224,238,246,15,10,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,40,0,184,224,238,246,15,10,8,105,115,95,114,97,110,103,101,1,121,40,0,184,224,238,246,15,10,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,119,0,161,184,224,238,246,15,8,1,39,0,184,224,238,246,15,9,6,72,95,74,113,85,76,1,40,0,184,224,238,246,15,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,76,40,0,184,224,238,246,15,18,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,184,224,238,246,15,18,4,100,97,116,97,1,119,3,104,105,49,40,0,184,224,238,246,15,18,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,76,161,184,224,238,246,15,17,1,39,0,184,224,238,246,15,9,6,70,99,112,109,80,101,1,40,0,184,224,238,246,15,24,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,127,40,0,184,224,238,246,15,24,4,100,97,116,97,1,119,3,89,101,115,40,0,184,224,238,246,15,24,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,5,40,0,184,224,238,246,15,24,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,127,168,184,224,238,246,15,23,1,122,0,0,0,0,102,77,165,148,39,0,184,224,238,246,15,9,6,112,70,120,57,67,45,1,40,0,184,224,238,246,15,30,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,148,40,0,184,224,238,246,15,30,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,7,40,0,184,224,238,246,15,30,4,100,97,116,97,1,119,82,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,119,122,107,74,34,44,34,110,97,109,101,34,58,34,53,53,53,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,115,101,108,101,99,116,101,100,95,111,112,116,105,111,110,95,105,100,115,34,58,91,93,125,40,0,184,224,238,246,15,30,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,148,2,205,147,147,241,14,0,161,239,184,147,146,4,3,2,168,205,147,147,241,14,1,1,122,0,0,0,0,102,88,31,91,1,246,235,197,205,14,0,161,185,248,189,241,10,1,2,1,194,245,173,211,11,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,8,1,185,248,189,241,10,0,161,241,200,244,209,10,1,2,1,176,221,143,219,10,0,161,194,245,173,211,11,7,21,1,241,200,244,209,10,0,161,166,226,191,247,8,1,2,1,166,226,191,247,8,0,161,240,207,252,192,1,38,2,1,186,199,157,206,8,0,161,203,254,130,163,1,1,2,1,185,239,230,135,7,0,161,189,129,252,252,2,5,2,2,174,181,215,227,6,0,161,189,129,252,252,2,5,1,161,185,239,230,135,7,1,11,1,239,184,147,146,4,0,161,186,199,157,206,8,1,4,1,189,129,252,252,2,0,161,246,235,197,205,14,1,6,1,240,207,252,192,1,0,161,176,221,143,219,10,20,39,1,203,254,130,163,1,0,161,174,181,215,227,6,11,2,15,194,245,173,211,11,1,0,8,166,226,191,247,8,1,0,2,203,254,130,163,1,1,0,2,205,147,147,241,14,1,0,2,174,181,215,227,6,1,0,12,239,184,147,146,4,1,0,4,176,221,143,219,10,1,0,21,240,207,252,192,1,1,0,39,241,200,244,209,10,1,0,2,246,235,197,205,14,1,0,2,184,224,238,246,15,3,8,1,17,1,23,1,185,248,189,241,10,1,0,2,185,239,230,135,7,1,0,2,186,199,157,206,8,1,0,2,189,129,252,252,2,1,0,6],"7717079b-05b6-4a0a-8ee4-48739fbf3a52":[18,1,238,246,246,209,14,0,161,222,139,223,157,3,30,6,1,242,233,195,179,14,0,161,147,233,229,181,2,9,2,1,176,198,177,177,14,0,161,242,233,195,179,14,1,2,1,171,249,223,240,13,0,161,176,198,177,177,14,1,2,1,189,169,216,163,13,0,161,229,212,189,183,1,3,2,1,241,188,132,177,11,0,161,171,249,223,240,13,1,5,2,176,157,175,239,9,0,161,241,188,132,177,11,4,2,168,176,157,175,239,9,1,1,122,0,0,0,0,102,88,31,91,1,244,197,233,193,9,0,161,189,169,216,163,13,1,6,1,231,233,173,168,9,0,161,206,211,220,252,6,33,40,1,206,211,220,252,6,0,161,243,207,130,177,3,8,34,54,237,203,168,145,4,0,161,145,187,128,129,2,39,1,40,0,145,187,128,129,2,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,89,162,161,145,187,128,129,2,13,1,161,145,187,128,129,2,11,1,161,145,187,128,129,2,15,1,161,145,187,128,129,2,12,1,161,145,187,128,129,2,14,1,161,145,187,128,129,2,16,1,33,0,145,187,128,129,2,10,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,237,203,168,145,4,0,1,168,237,203,168,145,4,6,1,119,10,49,55,49,54,52,51,49,54,53,49,168,237,203,168,145,4,4,1,121,168,237,203,168,145,4,7,1,120,168,237,203,168,145,4,2,1,119,0,168,237,203,168,145,4,3,1,122,0,0,0,0,0,0,0,2,168,237,203,168,145,4,5,1,119,10,49,55,49,54,51,52,53,50,53,49,168,237,203,168,145,4,8,1,122,0,0,0,0,102,77,89,163,161,237,203,168,145,4,9,1,168,145,187,128,129,2,27,1,122,0,0,0,0,0,0,0,6,168,145,187,128,129,2,26,1,119,11,97,112,112,102,108,111,119,121,46,105,111,168,145,187,128,129,2,28,1,122,0,0,0,0,102,77,165,88,161,237,203,168,145,4,17,1,168,145,187,128,129,2,20,1,119,9,73,73,66,100,44,110,103,110,85,168,145,187,128,129,2,21,1,122,0,0,0,0,0,0,0,4,168,145,187,128,129,2,22,1,122,0,0,0,0,102,77,165,108,161,237,203,168,145,4,21,1,39,0,145,187,128,129,2,9,6,71,79,80,107,116,118,1,40,0,237,203,168,145,4,26,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,114,40,0,237,203,168,145,4,26,4,100,97,116,97,1,119,4,104,77,109,67,40,0,237,203,168,145,4,26,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,3,40,0,237,203,168,145,4,26,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,114,161,237,203,168,145,4,25,1,39,0,145,187,128,129,2,9,6,70,99,112,109,80,101,1,40,0,237,203,168,145,4,32,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,126,40,0,237,203,168,145,4,32,4,100,97,116,97,1,119,3,89,101,115,40,0,237,203,168,145,4,32,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,5,40,0,237,203,168,145,4,32,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,126,161,237,203,168,145,4,31,1,39,0,145,187,128,129,2,9,6,112,70,120,57,67,45,1,40,0,237,203,168,145,4,38,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,137,33,0,237,203,168,145,4,38,10,102,105,101,108,100,95,116,121,112,101,1,33,0,237,203,168,145,4,38,4,100,97,116,97,1,33,0,237,203,168,145,4,38,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,237,203,168,145,4,37,1,168,237,203,168,145,4,40,1,122,0,0,0,0,0,0,0,7,168,237,203,168,145,4,41,1,119,88,123,34,111,112,116,105,111,110,115,34,58,91,123,34,105,100,34,58,34,106,97,56,104,34,44,34,110,97,109,101,34,58,34,49,50,51,34,44,34,99,111,108,111,114,34,58,34,80,117,114,112,108,101,34,125,93,44,34,115,101,108,101,99,116,101,100,95,111,112,116,105,111,110,95,105,100,115,34,58,91,34,106,97,56,104,34,93,125,168,237,203,168,145,4,42,1,122,0,0,0,0,102,77,165,139,168,237,203,168,145,4,43,1,122,0,0,0,0,102,77,165,176,39,0,145,187,128,129,2,9,6,75,71,50,113,74,65,1,40,0,237,203,168,145,4,48,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,176,40,0,237,203,168,145,4,48,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,10,39,0,237,203,168,145,4,48,4,100,97,116,97,0,8,0,237,203,168,145,4,51,1,119,36,50,48,56,100,50,52,56,102,45,53,99,48,56,45,52,98,101,53,45,97,48,50,50,45,101,48,97,57,55,99,50,100,55,48,53,101,40,0,237,203,168,145,4,48,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,77,165,176,1,235,139,213,209,3,0,161,231,233,173,168,9,39,2,1,243,207,130,177,3,0,161,238,246,246,209,14,5,9,1,222,139,223,157,3,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,31,1,147,233,229,181,2,0,161,244,197,233,193,9,5,10,45,145,187,128,129,2,0,39,1,4,100,97,116,97,4,100,97,116,97,1,39,1,4,100,97,116,97,4,109,101,116,97,1,39,1,4,100,97,116,97,7,99,111,109,109,101,110,116,0,40,0,145,187,128,129,2,0,2,105,100,1,119,36,55,55,49,55,48,55,57,98,45,48,53,98,54,45,52,97,48,97,45,56,101,101,52,45,52,56,55,51,57,102,98,102,51,97,53,50,40,0,145,187,128,129,2,0,11,100,97,116,97,98,97,115,101,95,105,100,1,119,36,99,101,50,54,55,100,49,50,45,51,98,54,49,45,52,101,98,98,45,98,98,48,51,45,100,54,53,50,55,50,102,53,102,56,49,55,40,0,145,187,128,129,2,0,6,104,101,105,103,104,116,1,122,0,0,0,0,0,0,0,60,40,0,145,187,128,129,2,0,10,118,105,115,105,98,105,108,105,116,121,1,120,40,0,145,187,128,129,2,0,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,101,247,33,0,145,187,128,129,2,0,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,39,0,145,187,128,129,2,0,5,99,101,108,108,115,1,39,0,145,187,128,129,2,9,6,55,85,107,117,54,82,1,33,0,145,187,128,129,2,10,10,102,105,101,108,100,95,116,121,112,101,1,33,0,145,187,128,129,2,10,4,100,97,116,97,1,33,0,145,187,128,129,2,10,11,114,101,109,105,110,100,101,114,95,105,100,1,33,0,145,187,128,129,2,10,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,33,0,145,187,128,129,2,10,12,105,110,99,108,117,100,101,95,116,105,109,101,1,33,0,145,187,128,129,2,10,8,105,115,95,114,97,110,103,101,1,161,145,187,128,129,2,8,1,39,0,145,187,128,129,2,9,6,95,82,45,112,104,105,1,40,0,145,187,128,129,2,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,101,255,33,0,145,187,128,129,2,18,4,100,97,116,97,1,33,0,145,187,128,129,2,18,10,102,105,101,108,100,95,116,121,112,101,1,33,0,145,187,128,129,2,18,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,145,187,128,129,2,17,1,39,0,145,187,128,129,2,9,6,99,78,53,98,120,74,1,40,0,145,187,128,129,2,24,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,102,14,33,0,145,187,128,129,2,24,4,100,97,116,97,1,33,0,145,187,128,129,2,24,10,102,105,101,108,100,95,116,121,112,101,1,33,0,145,187,128,129,2,24,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,161,145,187,128,129,2,23,1,39,0,145,187,128,129,2,9,6,71,115,66,65,97,76,1,40,0,145,187,128,129,2,30,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,102,25,40,0,145,187,128,129,2,30,8,105,115,95,114,97,110,103,101,1,121,40,0,145,187,128,129,2,30,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,2,40,0,145,187,128,129,2,30,12,105,110,99,108,117,100,101,95,116,105,109,101,1,121,40,0,145,187,128,129,2,30,4,100,97,116,97,1,119,10,49,55,49,54,52,53,53,55,48,53,40,0,145,187,128,129,2,30,11,114,101,109,105,110,100,101,114,95,105,100,1,119,0,40,0,145,187,128,129,2,30,13,101,110,100,95,116,105,109,101,115,116,97,109,112,1,119,0,40,0,145,187,128,129,2,30,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,102,25,161,145,187,128,129,2,29,1,39,0,145,187,128,129,2,9,6,72,95,74,113,85,76,1,40,0,145,187,128,129,2,40,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,102,32,40,0,145,187,128,129,2,40,10,102,105,101,108,100,95,116,121,112,101,1,122,0,0,0,0,0,0,0,0,40,0,145,187,128,129,2,40,4,100,97,116,97,1,119,5,119,111,114,108,100,40,0,145,187,128,129,2,40,13,108,97,115,116,95,109,111,100,105,102,105,101,100,1,122,0,0,0,0,102,76,102,32,1,229,212,189,183,1,0,161,235,139,213,209,3,1,4,1,222,172,192,75,0,161,244,197,233,193,9,5,2,18,229,212,189,183,1,1,0,4,231,233,173,168,9,1,0,40,235,139,213,209,3,1,0,2,171,249,223,240,13,1,0,2,237,203,168,145,4,8,0,1,2,8,17,1,21,1,25,1,31,1,37,1,40,4,238,246,246,209,14,1,0,6,206,211,220,252,6,1,0,34,176,198,177,177,14,1,0,2,241,188,132,177,11,1,0,5,242,233,195,179,14,1,0,2,243,207,130,177,3,1,0,9,244,197,233,193,9,1,0,6,147,233,229,181,2,1,0,10,145,187,128,129,2,5,8,1,11,7,20,4,26,4,39,1,176,157,175,239,9,1,0,2,189,169,216,163,13,1,0,2,222,139,223,157,3,1,0,31,222,172,192,75,1,0,2]} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/document/f56bdf0f-90c8-53fb-97d9-ad5860d2b7a0.json b/frontend/appflowy_web_app/cypress/fixtures/document/f56bdf0f-90c8-53fb-97d9-ad5860d2b7a0.json new file mode 100644 index 0000000000..53c4b0f6df --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/document/f56bdf0f-90c8-53fb-97d9-ad5860d2b7a0.json @@ -0,0 +1 @@ +{"data":{"state_vector":[6,248,208,217,159,7,16,226,250,246,177,3,17,211,142,141,147,5,8,196,148,203,38,26,230,150,209,139,14,193,6,167,238,246,72,86],"doc_state":[6,177,5,230,150,209,139,14,0,0,2,0,1,0,5,39,0,196,148,203,38,4,6,122,45,72,76,78,68,2,4,0,230,150,209,139,14,8,4,49,49,49,49,39,0,196,148,203,38,1,6,54,70,57,105,75,107,1,40,0,230,150,209,139,14,13,2,105,100,1,119,6,54,70,57,105,75,107,40,0,230,150,209,139,14,13,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,230,150,209,139,14,13,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,13,8,99,104,105,108,100,114,101,110,1,119,6,97,118,105,69,115,45,33,0,230,150,209,139,14,13,4,100,97,116,97,1,40,0,230,150,209,139,14,13,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,13,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,97,118,105,69,115,45,0,72,196,148,203,38,24,1,119,6,54,70,57,105,75,107,39,0,196,148,203,38,4,6,69,115,57,50,84,74,2,33,0,196,148,203,38,1,6,98,71,84,69,74,116,1,0,7,33,0,196,148,203,38,3,6,87,56,66,102,66,110,1,129,196,148,203,38,24,1,168,230,150,209,139,14,18,1,119,39,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,49,49,49,34,125,93,44,34,108,101,118,101,108,34,58,50,125,4,0,230,150,209,139,14,23,1,35,0,1,132,230,150,209,139,14,35,1,35,0,1,132,230,150,209,139,14,37,1,35,0,1,132,230,150,209,139,14,39,1,35,0,1,39,0,196,148,203,38,4,6,56,76,76,113,48,56,2,39,0,196,148,203,38,1,6,56,70,105,117,112,98,1,40,0,230,150,209,139,14,44,2,105,100,1,119,6,56,70,105,117,112,98,40,0,230,150,209,139,14,44,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,230,150,209,139,14,44,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,44,8,99,104,105,108,100,114,101,110,1,119,6,49,66,67,68,107,53,33,0,230,150,209,139,14,44,4,100,97,116,97,1,40,0,230,150,209,139,14,44,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,44,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,49,66,67,68,107,53,0,200,196,148,203,38,24,230,150,209,139,14,33,1,119,6,56,70,105,117,112,98,4,0,230,150,209,139,14,43,1,50,161,230,150,209,139,14,49,1,132,230,150,209,139,14,54,1,50,161,230,150,209,139,14,55,1,132,230,150,209,139,14,56,1,50,161,230,150,209,139,14,57,1,132,230,150,209,139,14,58,1,50,161,230,150,209,139,14,59,1,39,0,196,148,203,38,4,6,103,76,57,104,70,45,2,39,0,196,148,203,38,1,6,72,99,71,82,109,56,1,40,0,230,150,209,139,14,63,2,105,100,1,119,6,72,99,71,82,109,56,40,0,230,150,209,139,14,63,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,63,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,63,8,99,104,105,108,100,114,101,110,1,119,6,50,114,117,49,72,109,33,0,230,150,209,139,14,63,4,100,97,116,97,1,40,0,230,150,209,139,14,63,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,63,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,50,114,117,49,72,109,0,136,230,150,209,139,14,33,1,119,6,72,99,71,82,109,56,168,230,150,209,139,14,61,1,119,39,123,34,108,101,118,101,108,34,58,52,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,50,50,50,50,34,125,93,125,1,0,230,150,209,139,14,62,1,161,230,150,209,139,14,68,1,129,230,150,209,139,14,74,1,161,230,150,209,139,14,75,1,129,230,150,209,139,14,76,2,161,230,150,209,139,14,77,1,129,230,150,209,139,14,79,1,161,230,150,209,139,14,80,1,129,230,150,209,139,14,81,1,161,230,150,209,139,14,82,1,68,230,150,209,139,14,74,6,228,189,160,229,165,189,168,230,150,209,139,14,84,1,119,31,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,228,189,160,229,165,189,34,125,93,125,39,0,196,148,203,38,4,6,113,111,68,56,109,111,2,33,0,196,148,203,38,1,6,113,118,66,98,82,83,1,0,7,33,0,196,148,203,38,3,6,118,76,97,51,57,90,1,129,230,150,209,139,14,72,1,1,0,230,150,209,139,14,88,1,0,1,129,230,150,209,139,14,99,1,0,1,129,230,150,209,139,14,101,1,0,4,132,230,150,209,139,14,103,1,91,0,1,132,230,150,209,139,14,108,1,93,0,1,39,0,196,148,203,38,4,6,69,114,99,104,55,72,2,39,0,196,148,203,38,1,6,51,111,95,70,117,67,1,40,0,230,150,209,139,14,113,2,105,100,1,119,6,51,111,95,70,117,67,40,0,230,150,209,139,14,113,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,230,150,209,139,14,113,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,113,8,99,104,105,108,100,114,101,110,1,119,6,68,56,109,75,57,97,33,0,230,150,209,139,14,113,4,100,97,116,97,1,40,0,230,150,209,139,14,113,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,113,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,68,56,109,75,57,97,0,200,230,150,209,139,14,72,230,150,209,139,14,98,1,119,6,51,111,95,70,117,67,4,0,230,150,209,139,14,112,1,49,161,230,150,209,139,14,118,1,132,230,150,209,139,14,123,1,50,161,230,150,209,139,14,124,1,132,230,150,209,139,14,125,1,51,161,230,150,209,139,14,126,1,39,0,196,148,203,38,4,6,122,55,116,111,73,55,2,33,0,196,148,203,38,1,6,120,66,121,81,55,113,1,0,7,33,0,196,148,203,38,3,6,81,98,51,101,57,117,1,129,230,150,209,139,14,98,1,168,230,150,209,139,14,128,1,1,119,44,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,125,1,0,230,150,209,139,14,129,1,1,0,1,129,230,150,209,139,14,141,1,1,0,1,129,230,150,209,139,14,143,1,1,0,4,132,230,150,209,139,14,145,1,1,45,0,1,39,0,196,148,203,38,4,6,84,119,106,104,109,54,2,39,0,196,148,203,38,1,6,69,76,108,103,56,112,1,40,0,230,150,209,139,14,153,1,2,105,100,1,119,6,69,76,108,103,56,112,40,0,230,150,209,139,14,153,1,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,230,150,209,139,14,153,1,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,153,1,8,99,104,105,108,100,114,101,110,1,119,6,80,56,121,104,83,86,33,0,230,150,209,139,14,153,1,4,100,97,116,97,1,40,0,230,150,209,139,14,153,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,153,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,80,56,121,104,83,86,0,200,230,150,209,139,14,98,230,150,209,139,14,139,1,1,119,6,69,76,108,103,56,112,4,0,230,150,209,139,14,152,1,1,49,161,230,150,209,139,14,158,1,1,132,230,150,209,139,14,163,1,1,50,161,230,150,209,139,14,164,1,1,132,230,150,209,139,14,165,1,1,51,168,230,150,209,139,14,166,1,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,125,39,0,196,148,203,38,4,6,100,53,73,101,79,51,2,33,0,196,148,203,38,1,6,79,100,120,77,110,80,1,0,7,33,0,196,148,203,38,3,6,120,89,113,72,122,98,1,129,230,150,209,139,14,139,1,1,4,0,230,150,209,139,14,169,1,1,49,0,1,132,230,150,209,139,14,180,1,1,46,0,1,39,0,196,148,203,38,4,6,50,78,117,49,104,78,2,39,0,196,148,203,38,1,6,88,110,106,101,115,65,1,40,0,230,150,209,139,14,185,1,2,105,100,1,119,6,88,110,106,101,115,65,40,0,230,150,209,139,14,185,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,230,150,209,139,14,185,1,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,185,1,8,99,104,105,108,100,114,101,110,1,119,6,102,119,53,69,102,68,33,0,230,150,209,139,14,185,1,4,100,97,116,97,1,40,0,230,150,209,139,14,185,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,185,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,102,119,53,69,102,68,0,200,230,150,209,139,14,139,1,230,150,209,139,14,179,1,1,119,6,88,110,106,101,115,65,4,0,230,150,209,139,14,184,1,1,49,161,230,150,209,139,14,190,1,1,132,230,150,209,139,14,195,1,1,50,161,230,150,209,139,14,196,1,1,132,230,150,209,139,14,197,1,1,51,161,230,150,209,139,14,198,1,1,39,0,196,148,203,38,4,6,107,79,86,116,87,117,2,39,0,196,148,203,38,1,6,107,106,98,87,90,118,1,40,0,230,150,209,139,14,202,1,2,105,100,1,119,6,107,106,98,87,90,118,40,0,230,150,209,139,14,202,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,230,150,209,139,14,202,1,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,202,1,8,99,104,105,108,100,114,101,110,1,119,6,56,115,49,108,106,52,33,0,230,150,209,139,14,202,1,4,100,97,116,97,1,40,0,230,150,209,139,14,202,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,202,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,56,115,49,108,106,52,0,136,230,150,209,139,14,179,1,1,119,6,107,106,98,87,90,118,168,230,150,209,139,14,200,1,1,119,39,123,34,110,117,109,98,101,114,34,58,49,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,125,4,0,230,150,209,139,14,201,1,1,51,161,230,150,209,139,14,207,1,1,132,230,150,209,139,14,213,1,1,50,161,230,150,209,139,14,214,1,1,132,230,150,209,139,14,215,1,1,49,168,230,150,209,139,14,216,1,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,50,49,34,125,93,125,39,0,196,148,203,38,4,6,101,56,113,73,98,66,2,33,0,196,148,203,38,1,6,120,83,99,121,67,100,1,0,7,33,0,196,148,203,38,3,6,102,88,53,51,101,80,1,129,230,150,209,139,14,211,1,1,39,0,196,148,203,38,4,6,57,87,73,111,101,83,2,39,0,196,148,203,38,1,6,48,77,97,84,52,54,1,40,0,230,150,209,139,14,231,1,2,105,100,1,119,6,48,77,97,84,52,54,40,0,230,150,209,139,14,231,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,230,150,209,139,14,231,1,6,112,97,114,101,110,116,1,119,6,107,106,98,87,90,118,40,0,230,150,209,139,14,231,1,8,99,104,105,108,100,114,101,110,1,119,6,68,70,72,68,101,106,33,0,230,150,209,139,14,231,1,4,100,97,116,97,1,40,0,230,150,209,139,14,231,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,231,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,68,70,72,68,101,106,0,8,0,230,150,209,139,14,210,1,1,119,6,48,77,97,84,52,54,4,0,230,150,209,139,14,230,1,1,51,161,230,150,209,139,14,236,1,1,132,230,150,209,139,14,241,1,1,50,161,230,150,209,139,14,242,1,1,132,230,150,209,139,14,243,1,1,49,168,230,150,209,139,14,244,1,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,50,49,34,125,93,125,39,0,196,148,203,38,4,6,114,104,72,106,57,65,2,33,0,196,148,203,38,1,6,84,45,109,108,72,57,1,0,7,33,0,196,148,203,38,3,6,118,110,77,57,77,84,1,129,230,150,209,139,14,240,1,1,39,0,196,148,203,38,4,6,49,90,55,100,72,105,2,39,0,196,148,203,38,1,6,72,102,88,86,103,83,1,40,0,230,150,209,139,14,131,2,2,105,100,1,119,6,72,102,88,86,103,83,40,0,230,150,209,139,14,131,2,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,230,150,209,139,14,131,2,6,112,97,114,101,110,116,1,119,6,48,77,97,84,52,54,40,0,230,150,209,139,14,131,2,8,99,104,105,108,100,114,101,110,1,119,6,57,122,75,84,78,57,33,0,230,150,209,139,14,131,2,4,100,97,116,97,1,40,0,230,150,209,139,14,131,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,131,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,57,122,75,84,78,57,0,8,0,230,150,209,139,14,239,1,1,119,6,72,102,88,86,103,83,4,0,230,150,209,139,14,130,2,1,51,161,230,150,209,139,14,136,2,1,132,230,150,209,139,14,141,2,1,50,161,230,150,209,139,14,142,2,1,132,230,150,209,139,14,143,2,1,49,168,230,150,209,139,14,144,2,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,50,49,34,125,93,125,39,0,196,148,203,38,4,6,65,98,83,76,67,56,2,33,0,196,148,203,38,1,6,97,86,52,120,55,81,1,0,7,33,0,196,148,203,38,3,6,69,87,113,113,77,67,1,129,230,150,209,139,14,140,2,1,39,0,196,148,203,38,4,6,80,82,49,65,99,76,2,33,0,196,148,203,38,1,6,115,66,104,71,113,108,1,0,7,33,0,196,148,203,38,3,6,114,86,95,54,88,121,1,129,230,150,209,139,14,129,2,1,1,0,230,150,209,139,14,158,2,1,0,2,39,0,196,148,203,38,4,6,51,54,82,71,101,79,2,33,0,196,148,203,38,1,6,81,99,88,112,117,56,1,0,7,33,0,196,148,203,38,3,6,106,53,72,95,112,48,1,193,230,150,209,139,14,129,2,230,150,209,139,14,168,2,1,39,0,196,148,203,38,4,6,101,120,109,55,104,73,2,33,0,196,148,203,38,1,6,52,70,81,69,87,98,1,0,7,33,0,196,148,203,38,3,6,79,82,107,84,68,115,1,129,230,150,209,139,14,229,1,1,4,0,230,150,209,139,14,183,2,1,34,0,1,39,0,196,148,203,38,4,6,52,48,110,100,113,55,2,39,0,196,148,203,38,1,6,100,53,57,122,110,74,1,40,0,230,150,209,139,14,197,2,2,105,100,1,119,6,100,53,57,122,110,74,40,0,230,150,209,139,14,197,2,2,116,121,1,119,5,113,117,111,116,101,40,0,230,150,209,139,14,197,2,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,197,2,8,99,104,105,108,100,114,101,110,1,119,6,81,83,101,49,78,65,33,0,230,150,209,139,14,197,2,4,100,97,116,97,1,40,0,230,150,209,139,14,197,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,197,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,81,83,101,49,78,65,0,200,230,150,209,139,14,229,1,230,150,209,139,14,193,2,1,119,6,100,53,57,122,110,74,4,0,230,150,209,139,14,196,2,1,49,161,230,150,209,139,14,202,2,1,132,230,150,209,139,14,207,2,1,50,161,230,150,209,139,14,208,2,1,132,230,150,209,139,14,209,2,1,51,168,230,150,209,139,14,210,2,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,125,39,0,196,148,203,38,4,6,98,84,120,48,103,106,2,33,0,196,148,203,38,1,6,99,72,87,116,90,66,1,0,7,33,0,196,148,203,38,3,6,54,67,53,67,68,81,1,129,230,150,209,139,14,193,2,1,4,0,230,150,209,139,14,213,2,1,62,0,1,39,0,196,148,203,38,4,6,48,95,102,53,81,87,2,39,0,196,148,203,38,1,6,115,106,51,120,82,67,1,40,0,230,150,209,139,14,227,2,2,105,100,1,119,6,115,106,51,120,82,67,40,0,230,150,209,139,14,227,2,2,116,121,1,119,11,116,111,103,103,108,101,95,108,105,115,116,40,0,230,150,209,139,14,227,2,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,227,2,8,99,104,105,108,100,114,101,110,1,119,6,106,77,71,51,69,107,33,0,230,150,209,139,14,227,2,4,100,97,116,97,1,40,0,230,150,209,139,14,227,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,227,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,106,77,71,51,69,107,0,200,230,150,209,139,14,193,2,230,150,209,139,14,223,2,1,119,6,115,106,51,120,82,67,4,0,230,150,209,139,14,226,2,1,49,161,230,150,209,139,14,232,2,1,132,230,150,209,139,14,237,2,1,50,161,230,150,209,139,14,238,2,1,132,230,150,209,139,14,239,2,1,51,161,230,150,209,139,14,240,2,1,132,230,150,209,139,14,241,2,1,51,161,230,150,209,139,14,242,2,1,39,0,196,148,203,38,4,6,75,108,79,113,102,103,2,39,0,196,148,203,38,1,6,103,102,97,107,74,56,1,40,0,230,150,209,139,14,246,2,2,105,100,1,119,6,103,102,97,107,74,56,40,0,230,150,209,139,14,246,2,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,246,2,6,112,97,114,101,110,116,1,119,6,115,106,51,120,82,67,40,0,230,150,209,139,14,246,2,8,99,104,105,108,100,114,101,110,1,119,6,104,112,106,70,101,78,33,0,230,150,209,139,14,246,2,4,100,97,116,97,1,40,0,230,150,209,139,14,246,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,246,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,104,112,106,70,101,78,0,8,0,230,150,209,139,14,235,2,1,119,6,103,102,97,107,74,56,168,230,150,209,139,14,244,2,1,119,47,123,34,99,111,108,108,97,112,115,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,51,34,125,93,125,4,0,230,150,209,139,14,245,2,1,49,161,230,150,209,139,14,251,2,1,132,230,150,209,139,14,129,3,1,50,161,230,150,209,139,14,130,3,1,132,230,150,209,139,14,131,3,1,51,161,230,150,209,139,14,132,3,1,132,230,150,209,139,14,133,3,1,51,168,230,150,209,139,14,134,3,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,51,34,125,93,125,39,0,196,148,203,38,4,6,112,112,49,122,122,76,2,33,0,196,148,203,38,1,6,49,112,69,74,83,110,1,0,7,33,0,196,148,203,38,3,6,55,53,120,75,111,69,1,129,230,150,209,139,14,255,2,1,39,0,196,148,203,38,4,6,69,89,89,101,73,97,2,39,0,196,148,203,38,1,6,53,73,97,85,112,119,1,40,0,230,150,209,139,14,149,3,2,105,100,1,119,6,53,73,97,85,112,119,40,0,230,150,209,139,14,149,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,149,3,6,112,97,114,101,110,116,1,119,6,103,102,97,107,74,56,40,0,230,150,209,139,14,149,3,8,99,104,105,108,100,114,101,110,1,119,6,97,118,100,122,99,120,33,0,230,150,209,139,14,149,3,4,100,97,116,97,1,40,0,230,150,209,139,14,149,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,149,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,97,118,100,122,99,120,0,8,0,230,150,209,139,14,254,2,1,119,6,53,73,97,85,112,119,4,0,230,150,209,139,14,148,3,1,51,161,230,150,209,139,14,154,3,1,132,230,150,209,139,14,159,3,1,50,161,230,150,209,139,14,160,3,1,132,230,150,209,139,14,161,3,1,49,168,230,150,209,139,14,162,3,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,50,49,34,125,93,125,39,0,196,148,203,38,4,6,45,71,114,111,55,97,2,33,0,196,148,203,38,1,6,86,52,66,50,115,90,1,0,7,33,0,196,148,203,38,3,6,77,54,103,66,71,77,1,129,230,150,209,139,14,158,3,1,39,0,196,148,203,38,4,6,65,71,102,55,65,110,2,33,0,196,148,203,38,1,6,74,87,105,89,112,50,1,0,7,33,0,196,148,203,38,3,6,49,86,56,87,104,113,1,129,230,150,209,139,14,175,3,1,39,0,196,148,203,38,4,6,88,116,53,71,97,50,2,33,0,196,148,203,38,1,6,115,76,114,115,90,118,1,0,7,33,0,196,148,203,38,3,6,97,113,55,117,111,77,1,129,230,150,209,139,14,147,3,1,39,0,196,148,203,38,4,6,87,109,86,51,97,97,2,33,0,196,148,203,38,1,6,48,85,79,89,119,97,1,0,7,33,0,196,148,203,38,3,6,52,119,71,102,45,122,1,129,230,150,209,139,14,223,2,1,39,0,196,148,203,38,4,6,78,116,76,65,67,112,2,33,0,196,148,203,38,1,6,68,65,117,54,49,114,1,0,7,33,0,196,148,203,38,3,6,81,112,115,98,120,66,1,129,230,150,209,139,14,197,3,1,39,0,196,148,203,38,4,6,85,75,78,70,53,53,2,33,0,196,148,203,38,1,6,80,111,100,107,78,98,1,0,7,33,0,196,148,203,38,3,6,113,66,65,113,81,87,1,129,230,150,209,139,14,208,3,1,39,0,196,148,203,38,1,6,70,45,78,106,49,118,1,40,0,230,150,209,139,14,231,3,2,105,100,1,119,6,70,45,78,106,49,118,40,0,230,150,209,139,14,231,3,2,116,121,1,119,5,105,109,97,103,101,40,0,230,150,209,139,14,231,3,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,231,3,8,99,104,105,108,100,114,101,110,1,119,6,65,121,108,69,98,88,33,0,230,150,209,139,14,231,3,4,100,97,116,97,1,40,0,230,150,209,139,14,231,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,231,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,65,121,108,69,98,88,0,200,230,150,209,139,14,208,3,230,150,209,139,14,230,3,1,119,6,70,45,78,106,49,118,39,0,196,148,203,38,4,6,54,113,56,86,101,76,2,33,0,196,148,203,38,1,6,82,100,68,97,117,119,1,0,7,33,0,196,148,203,38,3,6,111,117,122,65,90,71,1,129,230,150,209,139,14,230,3,1,168,230,150,209,139,14,236,3,1,119,212,1,123,34,97,108,105,103,110,34,58,34,99,101,110,116,101,114,34,44,34,117,114,108,34,58,34,104,116,116,112,115,58,47,47,105,109,97,103,101,115,46,117,110,115,112,108,97,115,104,46,99,111,109,47,112,104,111,116,111,45,49,55,49,53,51,57,48,51,50,49,50,49,51,45,99,56,100,56,56,98,51,101,48,50,52,97,63,99,114,111,112,61,101,110,116,114,111,112,121,38,99,115,61,116,105,110,121,115,114,103,98,38,102,105,116,61,109,97,120,38,102,109,61,106,112,103,38,105,120,105,100,61,77,51,119,49,77,84,69,49,77,122,100,56,77,72,119,120,102,72,74,104,98,109,82,118,98,88,120,56,102,72,120,56,102,72,120,56,102,68,69,51,77,84,89,48,78,68,99,49,78,122,100,56,38,105,120,108,105,98,61,114,98,45,52,46,48,46,51,38,113,61,56,48,38,119,61,49,48,56,48,34,125,39,0,196,148,203,38,4,6,85,57,76,71,106,107,2,39,0,196,148,203,38,4,6,114,87,117,84,54,65,2,39,0,196,148,203,38,4,6,66,106,53,104,119,48,2,39,0,196,148,203,38,4,6,111,88,109,81,73,90,2,33,0,196,148,203,38,1,6,116,56,115,72,75,74,1,0,7,33,0,196,148,203,38,3,6,52,113,115,55,118,84,1,65,230,150,209,139,14,22,1,39,0,196,148,203,38,4,6,52,66,101,119,114,104,2,39,0,196,148,203,38,1,6,45,45,112,51,53,121,1,40,0,230,150,209,139,14,140,4,2,105,100,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,140,4,2,116,121,1,119,5,116,97,98,108,101,40,0,230,150,209,139,14,140,4,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,140,4,8,99,104,105,108,100,114,101,110,1,119,6,82,73,74,99,48,98,33,0,230,150,209,139,14,140,4,4,100,97,116,97,1,40,0,230,150,209,139,14,140,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,140,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,82,73,74,99,48,98,0,200,230,150,209,139,14,230,3,230,150,209,139,14,251,3,1,119,6,45,45,112,51,53,121,39,0,196,148,203,38,1,6,78,95,121,106,84,95,1,40,0,230,150,209,139,14,150,4,2,105,100,1,119,6,78,95,121,106,84,95,40,0,230,150,209,139,14,150,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,150,4,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,150,4,8,99,104,105,108,100,114,101,110,1,119,6,73,76,68,100,48,55,33,0,230,150,209,139,14,150,4,4,100,97,116,97,1,40,0,230,150,209,139,14,150,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,150,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,73,76,68,100,48,55,0,8,0,230,150,209,139,14,148,4,1,119,6,78,95,121,106,84,95,39,0,196,148,203,38,1,6,80,80,120,80,86,55,1,40,0,230,150,209,139,14,160,4,2,105,100,1,119,6,80,80,120,80,86,55,40,0,230,150,209,139,14,160,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,160,4,6,112,97,114,101,110,116,1,119,6,78,95,121,106,84,95,40,0,230,150,209,139,14,160,4,8,99,104,105,108,100,114,101,110,1,119,6,67,82,84,77,83,108,33,0,230,150,209,139,14,160,4,4,100,97,116,97,1,40,0,230,150,209,139,14,160,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,160,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,67,82,84,77,83,108,0,8,0,230,150,209,139,14,158,4,1,119,6,80,80,120,80,86,55,39,0,196,148,203,38,1,6,111,57,69,90,109,75,1,40,0,230,150,209,139,14,170,4,2,105,100,1,119,6,111,57,69,90,109,75,40,0,230,150,209,139,14,170,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,170,4,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,170,4,8,99,104,105,108,100,114,101,110,1,119,6,118,97,67,119,70,45,33,0,230,150,209,139,14,170,4,4,100,97,116,97,1,40,0,230,150,209,139,14,170,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,170,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,118,97,67,119,70,45,0,136,230,150,209,139,14,159,4,1,119,6,111,57,69,90,109,75,39,0,196,148,203,38,1,6,95,114,49,111,86,55,1,40,0,230,150,209,139,14,180,4,2,105,100,1,119,6,95,114,49,111,86,55,40,0,230,150,209,139,14,180,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,180,4,6,112,97,114,101,110,116,1,119,6,111,57,69,90,109,75,40,0,230,150,209,139,14,180,4,8,99,104,105,108,100,114,101,110,1,119,6,97,80,74,89,49,98,33,0,230,150,209,139,14,180,4,4,100,97,116,97,1,40,0,230,150,209,139,14,180,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,180,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,97,80,74,89,49,98,0,8,0,230,150,209,139,14,178,4,1,119,6,95,114,49,111,86,55,39,0,196,148,203,38,1,6,120,118,83,84,69,100,1,40,0,230,150,209,139,14,190,4,2,105,100,1,119,6,120,118,83,84,69,100,40,0,230,150,209,139,14,190,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,190,4,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,190,4,8,99,104,105,108,100,114,101,110,1,119,6,106,68,100,121,83,101,33,0,230,150,209,139,14,190,4,4,100,97,116,97,1,40,0,230,150,209,139,14,190,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,190,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,106,68,100,121,83,101,0,136,230,150,209,139,14,179,4,1,119,6,120,118,83,84,69,100,39,0,196,148,203,38,1,6,116,69,111,81,110,97,1,40,0,230,150,209,139,14,200,4,2,105,100,1,119,6,116,69,111,81,110,97,40,0,230,150,209,139,14,200,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,200,4,6,112,97,114,101,110,116,1,119,6,120,118,83,84,69,100,40,0,230,150,209,139,14,200,4,8,99,104,105,108,100,114,101,110,1,119,6,103,106,77,67,117,55,33,0,230,150,209,139,14,200,4,4,100,97,116,97,1,40,0,230,150,209,139,14,200,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,200,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,103,106,77,67,117,55,0,8,0,230,150,209,139,14,198,4,1,119,6,116,69,111,81,110,97,39,0,196,148,203,38,1,6,76,112,106,89,74,119,1,40,0,230,150,209,139,14,210,4,2,105,100,1,119,6,76,112,106,89,74,119,40,0,230,150,209,139,14,210,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,210,4,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,210,4,8,99,104,105,108,100,114,101,110,1,119,6,113,68,56,99,76,101,33,0,230,150,209,139,14,210,4,4,100,97,116,97,1,40,0,230,150,209,139,14,210,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,210,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,113,68,56,99,76,101,0,136,230,150,209,139,14,199,4,1,119,6,76,112,106,89,74,119,39,0,196,148,203,38,1,6,83,50,85,85,71,53,1,40,0,230,150,209,139,14,220,4,2,105,100,1,119,6,83,50,85,85,71,53,40,0,230,150,209,139,14,220,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,220,4,6,112,97,114,101,110,116,1,119,6,76,112,106,89,74,119,40,0,230,150,209,139,14,220,4,8,99,104,105,108,100,114,101,110,1,119,6,57,51,116,87,52,111,33,0,230,150,209,139,14,220,4,4,100,97,116,97,1,40,0,230,150,209,139,14,220,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,220,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,57,51,116,87,52,111,0,8,0,230,150,209,139,14,218,4,1,119,6,83,50,85,85,71,53,4,0,230,150,209,139,14,253,3,1,53,161,230,150,209,139,14,165,4,1,132,230,150,209,139,14,230,4,1,53,161,230,150,209,139,14,231,4,1,132,230,150,209,139,14,232,4,1,53,168,230,150,209,139,14,233,4,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,53,53,53,34,125,93,125,39,0,196,148,203,38,4,6,67,99,84,107,50,83,2,39,0,196,148,203,38,4,6,55,75,51,73,100,102,2,161,230,150,209,139,14,195,4,1,161,230,150,209,139,14,215,4,1,39,0,196,148,203,38,1,6,84,82,74,113,85,51,1,40,0,230,150,209,139,14,240,4,2,105,100,1,119,6,84,82,74,113,85,51,40,0,230,150,209,139,14,240,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,240,4,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,240,4,8,99,104,105,108,100,114,101,110,1,119,6,112,97,86,50,73,50,33,0,230,150,209,139,14,240,4,4,100,97,116,97,1,40,0,230,150,209,139,14,240,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,240,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,112,97,86,50,73,50,0,200,230,150,209,139,14,179,4,230,150,209,139,14,199,4,1,119,6,84,82,74,113,85,51,39,0,196,148,203,38,1,6,69,52,67,51,90,84,1,40,0,230,150,209,139,14,250,4,2,105,100,1,119,6,69,52,67,51,90,84,40,0,230,150,209,139,14,250,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,250,4,6,112,97,114,101,110,116,1,119,6,84,82,74,113,85,51,40,0,230,150,209,139,14,250,4,8,99,104,105,108,100,114,101,110,1,119,6,110,54,120,99,83,88,33,0,230,150,209,139,14,250,4,4,100,97,116,97,1,40,0,230,150,209,139,14,250,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,250,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,110,54,120,99,83,88,0,8,0,230,150,209,139,14,248,4,1,119,6,69,52,67,51,90,84,39,0,196,148,203,38,1,6,100,100,76,78,115,71,1,40,0,230,150,209,139,14,132,5,2,105,100,1,119,6,100,100,76,78,115,71,40,0,230,150,209,139,14,132,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,132,5,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,132,5,8,99,104,105,108,100,114,101,110,1,119,6,77,72,104,98,74,67,33,0,230,150,209,139,14,132,5,4,100,97,116,97,1,40,0,230,150,209,139,14,132,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,132,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,77,72,104,98,74,67,0,200,230,150,209,139,14,249,4,230,150,209,139,14,199,4,1,119,6,100,100,76,78,115,71,39,0,196,148,203,38,1,6,84,100,49,45,100,117,1,40,0,230,150,209,139,14,142,5,2,105,100,1,119,6,84,100,49,45,100,117,40,0,230,150,209,139,14,142,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,142,5,6,112,97,114,101,110,116,1,119,6,100,100,76,78,115,71,40,0,230,150,209,139,14,142,5,8,99,104,105,108,100,114,101,110,1,119,6,98,90,70,75,49,119,33,0,230,150,209,139,14,142,5,4,100,97,116,97,1,40,0,230,150,209,139,14,142,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,142,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,98,90,70,75,49,119,0,8,0,230,150,209,139,14,140,5,1,119,6,84,100,49,45,100,117,161,230,150,209,139,14,145,4,1,4,0,230,150,209,139,14,236,4,1,57,161,230,150,209,139,14,255,4,1,132,230,150,209,139,14,153,5,1,57,161,230,150,209,139,14,154,5,1,132,230,150,209,139,14,155,5,1,57,168,230,150,209,139,14,156,5,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,57,57,57,34,125,93,125,4,0,230,150,209,139,14,128,4,1,51,161,230,150,209,139,14,205,4,1,132,230,150,209,139,14,159,5,1,51,161,230,150,209,139,14,160,5,1,132,230,150,209,139,14,161,5,1,51,168,230,150,209,139,14,162,5,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,51,51,34,125,93,125,4,0,230,150,209,139,14,237,4,1,56,161,230,150,209,139,14,147,5,1,132,230,150,209,139,14,165,5,1,53,168,230,150,209,139,14,166,5,1,119,27,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,56,53,34,125,93,125,4,0,230,150,209,139,14,254,3,1,49,161,230,150,209,139,14,185,4,1,132,230,150,209,139,14,169,5,1,50,168,230,150,209,139,14,170,5,1,119,27,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,34,125,93,125,4,0,230,150,209,139,14,139,4,1,52,161,230,150,209,139,14,225,4,1,132,230,150,209,139,14,173,5,1,54,168,230,150,209,139,14,174,5,1,119,27,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,52,54,34,125,93,125,39,0,196,148,203,38,4,6,81,110,48,86,56,77,2,39,0,196,148,203,38,4,6,95,88,68,53,76,66,2,39,0,196,148,203,38,4,6,55,111,66,57,53,51,2,161,230,150,209,139,14,152,5,3,39,0,196,148,203,38,1,6,69,87,51,110,90,107,1,40,0,230,150,209,139,14,183,5,2,105,100,1,119,6,69,87,51,110,90,107,40,0,230,150,209,139,14,183,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,183,5,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,183,5,8,99,104,105,108,100,114,101,110,1,119,6,99,119,105,70,65,119,33,0,230,150,209,139,14,183,5,4,100,97,116,97,1,40,0,230,150,209,139,14,183,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,183,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,99,119,105,70,65,119,0,200,230,150,209,139,14,179,4,230,150,209,139,14,249,4,1,119,6,69,87,51,110,90,107,39,0,196,148,203,38,1,6,77,109,56,115,79,50,1,40,0,230,150,209,139,14,193,5,2,105,100,1,119,6,77,109,56,115,79,50,40,0,230,150,209,139,14,193,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,193,5,6,112,97,114,101,110,116,1,119,6,69,87,51,110,90,107,40,0,230,150,209,139,14,193,5,8,99,104,105,108,100,114,101,110,1,119,6,101,70,65,80,56,102,33,0,230,150,209,139,14,193,5,4,100,97,116,97,1,40,0,230,150,209,139,14,193,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,193,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,101,70,65,80,56,102,0,8,0,230,150,209,139,14,191,5,1,119,6,77,109,56,115,79,50,39,0,196,148,203,38,1,6,87,78,105,110,55,95,1,40,0,230,150,209,139,14,203,5,2,105,100,1,119,6,87,78,105,110,55,95,40,0,230,150,209,139,14,203,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,203,5,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,203,5,8,99,104,105,108,100,114,101,110,1,119,6,102,104,97,84,95,74,33,0,230,150,209,139,14,203,5,4,100,97,116,97,1,40,0,230,150,209,139,14,203,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,203,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,102,104,97,84,95,74,0,200,230,150,209,139,14,141,5,230,150,209,139,14,199,4,1,119,6,87,78,105,110,55,95,39,0,196,148,203,38,1,6,86,69,105,86,107,114,1,40,0,230,150,209,139,14,213,5,2,105,100,1,119,6,86,69,105,86,107,114,40,0,230,150,209,139,14,213,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,213,5,6,112,97,114,101,110,116,1,119,6,87,78,105,110,55,95,40,0,230,150,209,139,14,213,5,8,99,104,105,108,100,114,101,110,1,119,6,101,119,80,54,101,102,33,0,230,150,209,139,14,213,5,4,100,97,116,97,1,40,0,230,150,209,139,14,213,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,213,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,101,119,80,54,101,102,0,8,0,230,150,209,139,14,211,5,1,119,6,86,69,105,86,107,114,39,0,196,148,203,38,1,6,75,81,106,70,66,89,1,40,0,230,150,209,139,14,223,5,2,105,100,1,119,6,75,81,106,70,66,89,40,0,230,150,209,139,14,223,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,230,150,209,139,14,223,5,6,112,97,114,101,110,116,1,119,6,45,45,112,51,53,121,40,0,230,150,209,139,14,223,5,8,99,104,105,108,100,114,101,110,1,119,6,55,71,56,98,84,78,33,0,230,150,209,139,14,223,5,4,100,97,116,97,1,40,0,230,150,209,139,14,223,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,223,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,55,71,56,98,84,78,0,136,230,150,209,139,14,219,4,1,119,6,75,81,106,70,66,89,39,0,196,148,203,38,1,6,103,115,109,113,111,48,1,40,0,230,150,209,139,14,233,5,2,105,100,1,119,6,103,115,109,113,111,48,40,0,230,150,209,139,14,233,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,233,5,6,112,97,114,101,110,116,1,119,6,75,81,106,70,66,89,40,0,230,150,209,139,14,233,5,8,99,104,105,108,100,114,101,110,1,119,6,77,54,56,53,90,83,33,0,230,150,209,139,14,233,5,4,100,97,116,97,1,40,0,230,150,209,139,14,233,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,233,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,77,54,56,53,90,83,0,8,0,230,150,209,139,14,231,5,1,119,6,103,115,109,113,111,48,4,0,230,150,209,139,14,178,5,1,57,161,230,150,209,139,14,218,5,1,132,230,150,209,139,14,243,5,1,57,168,230,150,209,139,14,244,5,1,119,27,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,57,57,34,125,93,125,4,0,230,150,209,139,14,177,5,1,50,161,230,150,209,139,14,198,5,1,132,230,150,209,139,14,247,5,1,50,168,230,150,209,139,14,248,5,1,119,27,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,50,50,34,125,93,125,4,0,230,150,209,139,14,179,5,1,52,161,230,150,209,139,14,238,5,1,132,230,150,209,139,14,251,5,1,52,168,230,150,209,139,14,252,5,1,119,27,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,52,52,34,125,93,125,39,0,196,148,203,38,4,6,84,81,118,97,82,53,2,39,0,196,148,203,38,1,6,53,90,85,81,98,56,1,40,0,230,150,209,139,14,128,6,2,105,100,1,119,6,53,90,85,81,98,56,40,0,230,150,209,139,14,128,6,2,116,121,1,119,7,99,97,108,108,111,117,116,40,0,230,150,209,139,14,128,6,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,128,6,8,99,104,105,108,100,114,101,110,1,119,6,105,84,113,54,95,110,33,0,230,150,209,139,14,128,6,4,100,97,116,97,1,40,0,230,150,209,139,14,128,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,128,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,105,84,113,54,95,110,0,136,230,150,209,139,14,251,3,1,119,6,53,90,85,81,98,56,4,0,230,150,209,139,14,255,5,1,100,161,230,150,209,139,14,133,6,1,132,230,150,209,139,14,138,6,1,100,161,230,150,209,139,14,139,6,1,132,230,150,209,139,14,140,6,1,100,161,230,150,209,139,14,141,6,1,132,230,150,209,139,14,142,6,1,115,161,230,150,209,139,14,143,6,1,132,230,150,209,139,14,144,6,1,97,161,230,150,209,139,14,145,6,1,168,230,150,209,139,14,155,4,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,125,168,230,150,209,139,14,245,4,1,119,60,123,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,119,105,100,116,104,34,58,56,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,44,34,104,101,105,103,104,116,34,58,51,55,46,48,125,168,230,150,209,139,14,238,4,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,125,161,230,150,209,139,14,182,5,1,168,230,150,209,139,14,175,4,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,44,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,125,168,230,150,209,139,14,137,5,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,125,168,230,150,209,139,14,239,4,1,119,60,123,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,56,48,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,125,161,230,150,209,139,14,151,6,1,168,230,150,209,139,14,188,5,1,119,60,123,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,44,34,119,105,100,116,104,34,58,56,48,46,48,44,34,104,101,105,103,104,116,34,58,51,55,46,48,125,168,230,150,209,139,14,208,5,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,125,168,230,150,209,139,14,228,5,1,119,60,123,34,104,101,105,103,104,116,34,58,51,55,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,56,48,46,48,125,161,230,150,209,139,14,155,6,1,168,230,150,209,139,14,159,6,1,119,114,123,34,99,111,108,77,105,110,105,109,117,109,87,105,100,116,104,34,58,52,48,46,48,44,34,99,111,108,115,72,101,105,103,104,116,34,58,49,49,57,46,48,44,34,99,111,108,115,76,101,110,34,58,51,44,34,114,111,119,115,76,101,110,34,58,51,44,34,114,111,119,68,101,102,97,117,108,116,72,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,68,101,102,97,117,108,116,87,105,100,116,104,34,58,56,48,46,48,125,39,0,196,148,203,38,4,6,68,98,116,65,114,106,2,4,0,230,150,209,139,14,161,6,6,100,100,100,115,97,50,161,230,150,209,139,14,147,6,1,132,230,150,209,139,14,167,6,1,50,168,230,150,209,139,14,168,6,1,119,69,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,100,100,100,115,97,50,50,34,125,93,44,34,105,99,111,110,34,58,34,240,159,147,140,34,44,34,98,103,67,111,108,111,114,34,58,34,48,120,102,102,102,50,102,50,102,50,34,125,39,0,196,148,203,38,4,6,66,116,102,84,86,95,2,39,0,196,148,203,38,1,6,103,73,113,80,112,117,1,40,0,230,150,209,139,14,172,6,2,105,100,1,119,6,103,73,113,80,112,117,40,0,230,150,209,139,14,172,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,172,6,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,172,6,8,99,104,105,108,100,114,101,110,1,119,6,108,52,49,118,71,70,40,0,230,150,209,139,14,172,6,4,100,97,116,97,1,119,12,123,34,100,101,108,116,97,34,58,91,93,125,40,0,230,150,209,139,14,172,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,172,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,108,52,49,118,71,70,0,200,230,150,209,139,14,251,3,230,150,209,139,14,137,6,1,119,6,103,73,113,80,112,117,39,0,196,148,203,38,4,6,86,52,45,51,122,45,2,39,0,196,148,203,38,1,6,119,122,102,78,72,69,1,40,0,230,150,209,139,14,183,6,2,105,100,1,119,6,119,122,102,78,72,69,40,0,230,150,209,139,14,183,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,230,150,209,139,14,183,6,6,112,97,114,101,110,116,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,230,150,209,139,14,183,6,8,99,104,105,108,100,114,101,110,1,119,6,100,110,56,106,114,112,40,0,230,150,209,139,14,183,6,4,100,97,116,97,1,119,12,123,34,100,101,108,116,97,34,58,91,93,125,40,0,230,150,209,139,14,183,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,230,150,209,139,14,183,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,6,100,110,56,106,114,112,0,200,230,150,209,139,14,230,3,230,150,209,139,14,149,4,1,119,6,119,122,102,78,72,69,9,248,208,217,159,7,0,0,2,0,1,0,3,0,1,0,3,0,1,0,3,0,1,0,1,1,211,142,141,147,5,0,161,226,250,246,177,3,16,8,1,226,250,246,177,3,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,17,2,167,238,246,72,0,161,211,142,141,147,5,7,85,168,167,238,246,72,84,1,122,0,0,0,0,102,78,252,249,22,196,148,203,38,0,39,1,4,100,97,116,97,8,100,111,99,117,109,101,110,116,1,39,0,196,148,203,38,0,6,98,108,111,99,107,115,1,39,0,196,148,203,38,0,4,109,101,116,97,1,39,0,196,148,203,38,2,12,99,104,105,108,100,114,101,110,95,109,97,112,1,39,0,196,148,203,38,2,8,116,101,120,116,95,109,97,112,1,40,0,196,148,203,38,0,7,112,97,103,101,95,105,100,1,119,10,74,118,87,74,108,105,53,79,117,84,39,0,196,148,203,38,1,10,74,118,87,74,108,105,53,79,117,84,1,40,0,196,148,203,38,6,2,105,100,1,119,10,74,118,87,74,108,105,53,79,117,84,40,0,196,148,203,38,6,2,116,121,1,119,4,112,97,103,101,40,0,196,148,203,38,6,6,112,97,114,101,110,116,1,119,0,40,0,196,148,203,38,6,8,99,104,105,108,100,114,101,110,1,119,10,50,121,100,104,90,109,56,81,67,117,40,0,196,148,203,38,6,4,100,97,116,97,1,119,2,123,125,40,0,196,148,203,38,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,196,148,203,38,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,196,148,203,38,3,10,50,121,100,104,90,109,56,81,67,117,0,33,0,196,148,203,38,1,10,69,115,119,105,88,82,80,121,106,72,1,0,5,0,1,0,1,33,0,196,148,203,38,3,10,76,119,103,107,118,65,79,53,66,103,1,1,0,196,148,203,38,14,1,33,0,196,148,203,38,4,10,104,115,108,107,104,97,102,49,51,111,1,6,248,208,217,159,7,1,0,16,226,250,246,177,3,1,0,17,211,142,141,147,5,1,0,8,196,148,203,38,1,15,11,230,150,209,139,14,121,0,8,18,1,24,10,36,1,38,1,40,1,42,1,49,1,55,1,57,1,59,1,61,1,68,1,74,11,89,19,109,1,111,1,118,1,124,1,126,1,128,1,1,130,1,10,141,1,9,151,1,1,158,1,1,164,1,1,166,1,1,170,1,10,181,1,1,183,1,1,190,1,1,196,1,1,198,1,1,200,1,1,207,1,1,214,1,1,216,1,1,220,1,10,236,1,1,242,1,1,244,1,1,248,1,10,136,2,1,142,2,1,144,2,1,148,2,10,159,2,13,173,2,10,184,2,10,195,2,1,202,2,1,208,2,1,210,2,1,214,2,10,225,2,1,232,2,1,238,2,1,240,2,1,242,2,1,244,2,1,251,2,1,130,3,1,132,3,1,134,3,1,138,3,10,154,3,1,160,3,1,162,3,1,166,3,10,177,3,10,188,3,10,199,3,10,210,3,10,221,3,10,236,3,1,242,3,10,129,4,10,145,4,1,155,4,1,165,4,1,175,4,1,185,4,1,195,4,1,205,4,1,215,4,1,225,4,1,231,4,1,233,4,1,238,4,2,245,4,1,255,4,1,137,5,1,147,5,1,152,5,1,154,5,1,156,5,1,160,5,1,162,5,1,166,5,1,170,5,1,174,5,1,180,5,3,188,5,1,198,5,1,208,5,1,218,5,1,228,5,1,238,5,1,244,5,1,248,5,1,252,5,1,133,6,1,139,6,1,141,6,1,143,6,1,145,6,1,147,6,1,151,6,1,155,6,1,159,6,1,168,6,1,167,238,246,72,1,0,85],"version":0,"object_id":"f56bdf0f-90c8-53fb-97d9-ad5860d2b7a0"},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/folder.json b/frontend/appflowy_web_app/cypress/fixtures/folder.json new file mode 100644 index 0000000000..472ad9157d --- /dev/null +++ b/frontend/appflowy_web_app/cypress/fixtures/folder.json @@ -0,0 +1 @@ +{"data":{"state_vector":[157,1,128,252,161,128,4,33,130,180,254,251,6,18,135,232,133,203,9,15,135,240,136,178,10,45,137,226,192,199,6,20,138,202,240,189,2,134,1,139,240,196,145,14,138,2,139,152,215,249,10,34,141,216,158,150,1,3,142,130,192,134,11,3,143,184,153,180,6,6,140,228,230,243,1,2,145,190,137,224,10,2,145,144,146,185,5,12,140,152,206,145,6,165,1,135,166,246,235,6,3,147,206,229,235,1,3,137,164,190,210,1,39,152,158,185,230,10,7,153,130,203,161,6,97,152,252,186,192,1,2,154,244,246,165,8,198,1,156,148,170,169,10,16,157,240,144,231,2,3,158,156,181,152,10,49,158,182,250,251,9,15,160,192,253,131,5,3,161,178,132,150,11,101,159,156,204,250,6,27,163,236,177,169,4,12,164,188,201,172,1,3,158,184,218,165,3,38,162,238,198,212,7,3,170,140,240,234,9,31,171,204,155,217,8,3,171,142,166,254,1,6,173,252,148,184,13,64,176,154,159,227,1,20,178,162,190,217,10,3,179,252,154,44,3,180,230,210,212,13,7,182,172,247,194,5,3,183,226,184,158,8,8,195,242,227,194,8,3,196,154,250,183,6,62,197,254,154,201,10,3,200,142,208,241,4,157,1,202,160,246,212,1,6,203,184,221,173,11,37,206,220,129,131,4,21,207,228,238,162,8,50,209,250,203,254,15,3,210,228,153,221,12,3,211,202,217,232,12,7,211,166,203,229,4,195,1,214,168,149,214,3,15,225,248,138,176,2,49,226,212,179,248,2,15,229,154,128,197,12,24,234,182,182,157,9,8,235,178,165,206,5,72,241,130,161,205,7,12,244,226,228,149,2,30,245,220,194,52,39,247,200,243,247,14,100,248,136,168,181,1,3,248,210,237,129,13,2,250,198,166,187,7,2,248,196,187,185,10,27,252,218,241,167,14,3,255,140,248,220,6,3,128,211,179,216,2,10,133,159,138,205,12,131,1,135,167,156,250,14,16,135,193,208,135,7,16,141,245,194,142,11,7,141,205,220,149,4,3,143,131,148,152,6,15,141,171,170,217,4,2,145,159,164,217,14,3,149,129,169,191,12,16,149,249,242,175,4,31,149,189,189,215,8,3,149,161,132,184,14,221,2,154,243,157,196,14,12,154,193,208,134,10,9,155,165,205,152,11,3,154,235,215,240,4,13,155,159,180,195,15,6,157,207,243,216,6,2,161,239,241,154,13,106,162,159,252,196,11,3,164,155,139,169,7,35,165,139,157,171,15,103,164,203,250,235,13,7,167,131,133,162,9,11,166,201,221,141,13,72,169,197,188,221,3,3,170,255,211,105,38,166,203,155,46,6,173,187,245,170,14,46,174,151,139,93,179,2,175,225,172,150,8,11,175,147,217,214,1,33,177,161,136,243,11,10,178,203,205,182,4,1,175,205,156,228,6,10,180,205,189,133,13,20,181,175,219,209,12,10,182,143,233,195,4,111,177,219,160,167,7,4,184,201,188,172,10,3,184,231,170,67,6,186,197,166,179,15,7,187,173,214,176,15,3,188,171,136,250,8,21,188,237,223,145,6,26,190,139,191,155,1,2,191,157,147,233,9,32,193,249,142,142,4,17,198,189,216,175,6,23,200,205,214,172,10,30,201,129,238,197,4,84,201,191,159,147,14,17,200,203,236,184,2,35,200,159,185,206,9,8,205,149,231,236,11,68,213,161,242,209,13,35,214,139,213,136,8,66,213,255,156,145,1,2,219,227,140,137,6,34,221,147,167,147,15,177,2,222,205,223,235,7,31,223,209,193,147,11,81,227,209,197,253,2,14,229,153,197,202,7,241,6,231,139,244,188,8,13,232,207,157,148,2,2,233,165,139,246,14,43,233,247,183,159,1,4,235,225,184,133,10,3,234,153,236,158,4,73,234,187,164,181,1,24,231,189,134,196,8,77,239,199,189,146,3,24,240,149,229,225,6,15,241,155,213,233,1,52,240,253,240,229,1,79,243,239,182,181,13,30,236,229,225,232,8,116,246,185,174,192,6,90,248,153,216,10,3,251,189,220,155,14,3,252,163,130,200,6,30,253,205,145,137,11,10,252,171,209,175,15,4,255,255,147,249,10,3],"doc_state":[157,1,3,209,250,203,254,15,0,161,226,212,179,248,2,9,1,161,226,212,179,248,2,10,1,136,174,151,139,93,249,1,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,246,78,2,155,159,180,195,15,0,161,198,189,216,175,6,22,1,161,253,205,145,137,11,9,5,7,186,197,166,179,15,0,161,161,178,132,150,11,98,1,161,161,178,132,150,11,99,1,129,161,178,132,150,11,100,1,161,161,178,132,150,11,97,1,161,161,178,132,150,11,94,1,161,161,178,132,150,11,95,1,129,186,197,166,179,15,2,1,3,187,173,214,176,15,0,168,244,226,228,149,2,27,1,122,4,56,115,160,190,64,16,0,168,244,226,228,149,2,28,1,122,0,0,0,0,102,32,153,171,136,248,153,216,10,2,1,118,2,2,105,100,119,36,48,53,51,51,50,98,97,52,45,97,54,57,48,45,52,50,57,51,45,57,56,54,54,45,56,52,100,97,99,55,102,101,50,97,101,97,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,32,153,171,1,252,171,209,175,15,0,161,128,211,179,216,2,9,4,103,165,139,157,171,15,0,8,0,201,129,238,197,4,52,1,118,1,2,105,100,119,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,168,201,129,238,197,4,51,1,122,0,0,0,0,102,74,244,14,161,170,140,240,234,9,22,1,39,0,203,184,221,173,11,1,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,1,40,0,165,139,157,171,15,3,2,105,100,1,119,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,40,0,165,139,157,171,15,3,4,110,97,109,101,1,119,14,66,111,97,114,100,32,99,104,101,99,107,98,111,120,40,0,165,139,157,171,15,3,3,98,105,100,1,119,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,40,0,165,139,157,171,15,3,4,100,101,115,99,1,119,0,40,0,165,139,157,171,15,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,33,0,165,139,157,171,15,3,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,0,40,0,165,139,157,171,15,3,4,105,99,111,110,1,119,0,40,0,165,139,157,171,15,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,165,139,157,171,15,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,165,139,157,171,15,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,170,140,240,234,9,21,1,161,165,139,157,171,15,2,1,129,159,156,204,250,6,26,1,136,225,248,138,176,2,17,1,118,1,2,105,100,119,36,49,98,48,101,51,50,50,100,45,52,57,48,57,45,52,99,54,51,45,57,49,52,97,45,100,48,51,52,102,99,51,54,51,48,57,55,161,225,248,138,176,2,18,1,161,193,249,142,142,4,8,1,39,0,203,184,221,173,11,1,36,49,98,48,101,51,50,50,100,45,52,57,48,57,45,52,99,54,51,45,57,49,52,97,45,100,48,51,52,102,99,51,54,51,48,57,55,1,40,0,165,139,157,171,15,21,2,105,100,1,119,36,49,98,48,101,51,50,50,100,45,52,57,48,57,45,52,99,54,51,45,57,49,52,97,45,100,48,51,52,102,99,51,54,51,48,57,55,40,0,165,139,157,171,15,21,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,165,139,157,171,15,21,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,165,139,157,171,15,21,4,100,101,115,99,1,119,0,40,0,165,139,157,171,15,21,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,33,0,165,139,157,171,15,21,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,49,98,48,101,51,50,50,100,45,52,57,48,57,45,52,99,54,51,45,57,49,52,97,45,100,48,51,52,102,99,51,54,51,48,57,55,0,40,0,165,139,157,171,15,21,4,105,99,111,110,1,119,0,40,0,165,139,157,171,15,21,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,165,139,157,171,15,21,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,165,139,157,171,15,21,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,193,249,142,142,4,13,1,161,165,139,157,171,15,32,1,161,165,139,157,171,15,31,1,129,165,139,157,171,15,17,1,8,0,165,139,157,171,15,28,1,118,1,2,105,100,119,36,51,53,48,102,52,50,53,98,45,98,54,55,49,45,52,101,50,100,45,56,49,56,50,45,53,57,57,56,97,54,101,54,50,57,50,52,168,165,139,157,171,15,27,1,122,0,0,0,0,102,74,246,67,161,165,139,157,171,15,35,1,39,0,203,184,221,173,11,1,36,51,53,48,102,52,50,53,98,45,98,54,55,49,45,52,101,50,100,45,56,49,56,50,45,53,57,57,56,97,54,101,54,50,57,50,52,1,40,0,165,139,157,171,15,40,2,105,100,1,119,36,51,53,48,102,52,50,53,98,45,98,54,55,49,45,52,101,50,100,45,56,49,56,50,45,53,57,57,56,97,54,101,54,50,57,50,52,40,0,165,139,157,171,15,40,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,165,139,157,171,15,40,3,98,105,100,1,119,36,49,98,48,101,51,50,50,100,45,52,57,48,57,45,52,99,54,51,45,57,49,52,97,45,100,48,51,52,102,99,51,54,51,48,57,55,40,0,165,139,157,171,15,40,4,100,101,115,99,1,119,0,40,0,165,139,157,171,15,40,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,165,139,157,171,15,40,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,74,246,67,39,0,203,184,221,173,11,4,36,51,53,48,102,52,50,53,98,45,98,54,55,49,45,52,101,50,100,45,56,49,56,50,45,53,57,57,56,97,54,101,54,50,57,50,52,0,40,0,165,139,157,171,15,40,4,105,99,111,110,1,119,0,40,0,165,139,157,171,15,40,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,165,139,157,171,15,40,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,102,74,246,67,40,0,165,139,157,171,15,40,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,161,165,139,157,171,15,34,1,161,165,139,157,171,15,39,1,129,165,139,157,171,15,36,1,161,176,154,159,227,1,17,1,161,176,154,159,227,1,18,1,40,0,176,154,159,227,1,4,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,165,139,157,171,15,55,1,161,165,139,157,171,15,56,1,129,165,139,157,171,15,54,1,161,165,139,157,171,15,52,1,161,165,139,157,171,15,53,1,129,165,139,157,171,15,60,1,161,165,139,157,171,15,61,1,161,165,139,157,171,15,62,1,129,165,139,157,171,15,63,1,161,165,139,157,171,15,64,1,161,165,139,157,171,15,65,1,129,165,139,157,171,15,66,1,8,0,225,248,138,176,2,27,1,118,1,2,105,100,119,36,57,49,101,97,55,99,48,56,45,102,54,98,51,45,52,98,56,49,45,97,97,49,101,45,100,51,54,54,52,54,56,54,49,56,54,102,168,225,248,138,176,2,26,1,122,0,0,0,0,102,74,248,249,161,225,248,138,176,2,40,1,39,0,203,184,221,173,11,1,36,57,49,101,97,55,99,48,56,45,102,54,98,51,45,52,98,56,49,45,97,97,49,101,45,100,51,54,54,52,54,56,54,49,56,54,102,1,40,0,165,139,157,171,15,73,2,105,100,1,119,36,57,49,101,97,55,99,48,56,45,102,54,98,51,45,52,98,56,49,45,97,97,49,101,45,100,51,54,54,52,54,56,54,49,56,54,102,40,0,165,139,157,171,15,73,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,165,139,157,171,15,73,3,98,105,100,1,119,36,50,99,49,101,101,57,53,97,45,49,98,48,57,45,52,97,49,102,45,56,100,53,101,45,53,48,49,98,99,52,56,54,49,97,57,100,40,0,165,139,157,171,15,73,4,100,101,115,99,1,119,0,40,0,165,139,157,171,15,73,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,40,0,165,139,157,171,15,73,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,74,248,249,39,0,203,184,221,173,11,4,36,57,49,101,97,55,99,48,56,45,102,54,98,51,45,52,98,56,49,45,97,97,49,101,45,100,51,54,54,52,54,56,54,49,56,54,102,0,40,0,165,139,157,171,15,73,4,105,99,111,110,1,119,0,40,0,165,139,157,171,15,73,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,165,139,157,171,15,73,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,102,74,248,249,40,0,165,139,157,171,15,73,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,161,225,248,138,176,2,39,1,161,165,139,157,171,15,72,1,129,165,139,157,171,15,69,1,161,165,139,157,171,15,67,1,161,165,139,157,171,15,68,1,129,165,139,157,171,15,87,1,161,165,139,157,171,15,85,1,161,165,139,157,171,15,86,1,129,165,139,157,171,15,90,1,161,159,156,204,250,6,24,1,161,159,156,204,250,6,25,1,129,165,139,157,171,15,93,1,161,165,139,157,171,15,15,1,161,165,139,157,171,15,16,1,129,165,139,157,171,15,96,1,161,165,139,157,171,15,97,1,161,165,139,157,171,15,98,1,129,165,139,157,171,15,99,1,1,221,147,167,147,15,0,161,139,240,196,145,14,137,2,177,2,1,135,167,156,250,14,0,161,188,237,223,145,6,21,16,100,247,200,243,247,14,0,136,140,152,206,145,6,100,1,118,1,2,105,100,119,36,55,57,100,48,54,51,50,100,45,97,53,97,56,45,52,53,52,48,45,97,100,99,100,45,54,101,101,57,50,50,100,56,54,55,101,100,168,140,152,206,145,6,101,1,122,0,0,0,0,102,86,193,79,161,245,220,194,52,7,1,39,0,203,184,221,173,11,1,36,55,57,100,48,54,51,50,100,45,97,53,97,56,45,52,53,52,48,45,97,100,99,100,45,54,101,101,57,50,50,100,56,54,55,101,100,1,40,0,247,200,243,247,14,3,2,105,100,1,119,36,55,57,100,48,54,51,50,100,45,97,53,97,56,45,52,53,52,48,45,97,100,99,100,45,54,101,101,57,50,50,100,56,54,55,101,100,33,0,247,200,243,247,14,3,4,110,97,109,101,1,40,0,247,200,243,247,14,3,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,247,200,243,247,14,3,4,100,101,115,99,1,119,0,40,0,247,200,243,247,14,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,247,200,243,247,14,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,86,193,79,39,0,203,184,221,173,11,4,36,55,57,100,48,54,51,50,100,45,97,53,97,56,45,52,53,52,48,45,97,100,99,100,45,54,101,101,57,50,50,100,56,54,55,101,100,0,40,0,247,200,243,247,14,3,4,105,99,111,110,1,119,0,40,0,247,200,243,247,14,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,247,200,243,247,14,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,247,200,243,247,14,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,170,255,211,105,34,1,161,247,200,243,247,14,14,1,161,247,200,243,247,14,13,1,129,135,166,246,235,6,2,1,161,247,200,243,247,14,16,1,161,247,200,243,247,14,17,1,40,0,247,200,243,247,14,3,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,247,200,243,247,14,19,1,161,247,200,243,247,14,20,1,161,247,200,243,247,14,5,1,161,247,200,243,247,14,22,1,161,247,200,243,247,14,23,1,161,247,200,243,247,14,24,1,161,247,200,243,247,14,25,1,161,247,200,243,247,14,26,1,161,247,200,243,247,14,27,1,161,247,200,243,247,14,28,1,161,247,200,243,247,14,29,1,161,247,200,243,247,14,30,1,161,247,200,243,247,14,31,1,161,247,200,243,247,14,32,1,161,247,200,243,247,14,33,1,161,247,200,243,247,14,34,1,161,247,200,243,247,14,35,1,161,247,200,243,247,14,36,1,161,247,200,243,247,14,37,1,161,247,200,243,247,14,38,1,161,247,200,243,247,14,39,1,161,247,200,243,247,14,40,1,161,247,200,243,247,14,41,1,161,247,200,243,247,14,42,1,161,247,200,243,247,14,43,1,161,247,200,243,247,14,44,1,161,247,200,243,247,14,45,1,161,247,200,243,247,14,46,1,161,247,200,243,247,14,47,1,161,247,200,243,247,14,48,1,161,247,200,243,247,14,49,1,161,247,200,243,247,14,50,1,168,247,200,243,247,14,51,1,119,10,116,101,115,116,32,101,118,101,110,116,168,247,200,243,247,14,52,1,122,4,56,115,160,190,64,16,0,168,247,200,243,247,14,53,1,122,0,0,0,0,102,87,4,29,136,247,200,243,247,14,18,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,87,4,29,2,105,100,119,36,55,57,100,48,54,51,50,100,45,97,53,97,56,45,52,53,52,48,45,97,100,99,100,45,54,101,101,57,50,50,100,56,54,55,101,100,161,166,201,221,141,13,41,1,161,166,201,221,141,13,42,1,161,166,201,221,141,13,43,1,161,247,200,243,247,14,58,1,161,247,200,243,247,14,59,1,161,247,200,243,247,14,60,1,161,247,200,243,247,14,61,1,161,247,200,243,247,14,62,1,161,247,200,243,247,14,63,1,161,247,200,243,247,14,64,1,161,247,200,243,247,14,65,1,161,247,200,243,247,14,66,1,161,247,200,243,247,14,67,1,161,247,200,243,247,14,68,1,161,247,200,243,247,14,69,1,161,247,200,243,247,14,70,1,161,247,200,243,247,14,71,1,161,247,200,243,247,14,72,1,161,247,200,243,247,14,73,1,161,247,200,243,247,14,74,1,161,247,200,243,247,14,75,1,161,247,200,243,247,14,76,1,161,247,200,243,247,14,77,1,161,247,200,243,247,14,78,1,161,247,200,243,247,14,79,1,161,247,200,243,247,14,80,1,161,247,200,243,247,14,81,1,161,247,200,243,247,14,82,1,161,247,200,243,247,14,83,1,161,247,200,243,247,14,84,1,161,247,200,243,247,14,85,1,161,247,200,243,247,14,86,1,161,247,200,243,247,14,87,1,161,247,200,243,247,14,88,1,161,247,200,243,247,14,89,1,161,247,200,243,247,14,90,1,161,247,200,243,247,14,91,1,161,247,200,243,247,14,92,1,161,247,200,243,247,14,93,1,168,247,200,243,247,14,94,1,122,4,56,115,160,190,64,16,0,168,247,200,243,247,14,95,1,122,0,0,0,0,102,87,4,247,168,247,200,243,247,14,96,1,119,145,1,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,103,114,97,100,105,101,110,116,34,44,34,118,97,108,117,101,34,58,34,97,112,112,102,108,111,119,121,95,116,104,101,109,95,99,111,108,111,114,95,103,114,97,100,105,101,110,116,55,34,125,44,34,102,111,110,116,95,108,97,121,111,117,116,34,58,34,110,111,114,109,97,108,34,44,34,108,105,110,101,95,104,101,105,103,104,116,95,108,97,121,111,117,116,34,58,34,110,111,114,109,97,108,34,44,34,102,111,110,116,34,58,34,65,68,76,97,77,32,68,105,115,112,108,97,121,34,125,42,233,165,139,246,14,0,161,203,184,221,173,11,34,1,161,203,184,221,173,11,33,1,39,0,203,184,221,173,11,6,18,51,48,52,49,50,48,49,48,57,48,55,49,51,51,57,53,50,48,0,1,0,233,165,139,246,14,2,1,161,233,165,139,246,14,0,1,161,233,165,139,246,14,1,1,129,233,165,139,246,14,3,1,72,203,184,221,173,11,16,1,118,1,2,105,100,119,36,99,97,49,50,50,99,48,52,45,100,55,98,51,45,52,102,55,48,45,57,57,53,49,45,57,54,98,102,100,97,57,98,54,98,50,52,161,203,184,221,173,11,21,1,161,203,184,221,173,11,22,1,39,0,203,184,221,173,11,1,36,99,97,49,50,50,99,48,52,45,100,55,98,51,45,52,102,55,48,45,57,57,53,49,45,57,54,98,102,100,97,57,98,54,98,50,52,1,40,0,233,165,139,246,14,10,2,105,100,1,119,36,99,97,49,50,50,99,48,52,45,100,55,98,51,45,52,102,55,48,45,57,57,53,49,45,57,54,98,102,100,97,57,98,54,98,50,52,40,0,233,165,139,246,14,10,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,233,165,139,246,14,10,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,233,165,139,246,14,10,4,100,101,115,99,1,119,0,40,0,233,165,139,246,14,10,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,233,165,139,246,14,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,120,204,39,0,203,184,221,173,11,4,36,99,97,49,50,50,99,48,52,45,100,55,98,51,45,52,102,55,48,45,57,57,53,49,45,57,54,98,102,100,97,57,98,54,98,50,52,0,40,0,233,165,139,246,14,10,4,105,99,111,110,1,119,0,40,0,233,165,139,246,14,10,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,233,165,139,246,14,10,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,233,165,139,246,14,10,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,233,165,139,246,14,20,1,129,233,165,139,246,14,6,1,161,233,165,139,246,14,22,1,161,233,165,139,246,14,23,1,129,233,165,139,246,14,24,1,161,233,165,139,246,14,25,1,161,233,165,139,246,14,26,1,129,233,165,139,246,14,27,1,161,233,165,139,246,14,28,1,161,233,165,139,246,14,29,1,129,233,165,139,246,14,30,1,161,233,165,139,246,14,31,1,161,233,165,139,246,14,32,1,129,233,165,139,246,14,33,1,161,233,165,139,246,14,34,1,161,233,165,139,246,14,35,1,129,233,165,139,246,14,36,1,161,233,165,139,246,14,37,1,161,233,165,139,246,14,38,1,129,233,165,139,246,14,39,1,3,145,159,164,217,14,0,161,135,232,133,203,9,12,1,161,135,232,133,203,9,13,1,129,135,232,133,203,9,14,1,12,154,243,157,196,14,0,161,145,159,164,217,14,0,1,161,145,159,164,217,14,1,1,129,145,159,164,217,14,2,1,161,154,243,157,196,14,0,1,161,154,243,157,196,14,1,1,129,154,243,157,196,14,2,1,161,154,243,157,196,14,3,1,161,154,243,157,196,14,4,1,129,154,243,157,196,14,5,1,161,154,243,157,196,14,6,1,161,154,243,157,196,14,7,1,129,154,243,157,196,14,8,1,2,149,161,132,184,14,0,161,235,178,165,206,5,68,219,2,161,149,161,132,184,14,218,2,2,1,173,187,245,170,14,0,161,164,203,250,235,13,6,46,3,252,218,241,167,14,0,161,251,189,220,155,14,0,1,161,251,189,220,155,14,1,1,168,251,189,220,155,14,2,1,119,9,231,186,170,229,191,181,231,137,136,3,251,189,220,155,14,0,161,210,228,153,221,12,0,1,161,210,228,153,221,12,1,1,161,210,228,153,221,12,2,1,17,201,191,159,147,14,0,161,149,189,189,215,8,0,1,161,149,189,189,215,8,1,1,129,149,189,189,215,8,2,1,161,213,161,242,209,13,31,1,161,133,159,138,205,12,124,1,161,133,159,138,205,12,125,1,129,201,191,159,147,14,2,1,161,201,191,159,147,14,4,1,161,201,191,159,147,14,5,1,129,201,191,159,147,14,6,1,161,201,191,159,147,14,0,1,161,201,191,159,147,14,1,1,129,201,191,159,147,14,9,1,161,201,191,159,147,14,3,1,161,201,191,159,147,14,10,1,161,201,191,159,147,14,11,1,129,201,191,159,147,14,12,1,1,139,240,196,145,14,0,161,200,203,236,184,2,34,138,2,1,164,203,250,235,13,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,7,7,180,230,210,212,13,0,161,175,225,172,150,8,8,1,161,175,225,172,150,8,9,1,136,175,225,172,150,8,10,1,118,2,2,105,100,119,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,41,200,235,161,175,225,172,150,8,7,1,161,175,225,172,150,8,4,1,161,175,225,172,150,8,5,1,129,180,230,210,212,13,2,1,34,213,161,242,209,13,0,161,133,159,138,205,12,128,1,1,161,133,159,138,205,12,129,1,1,129,133,159,138,205,12,130,1,1,136,133,159,138,205,12,108,1,118,1,2,105,100,119,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,161,133,159,138,205,12,109,1,161,213,161,242,209,13,1,1,39,0,203,184,221,173,11,1,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,1,40,0,213,161,242,209,13,6,2,105,100,1,119,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,33,0,213,161,242,209,13,6,4,110,97,109,101,1,40,0,213,161,242,209,13,6,3,98,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,213,161,242,209,13,6,4,100,101,115,99,1,119,0,40,0,213,161,242,209,13,6,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,213,161,242,209,13,6,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,178,5,39,0,203,184,221,173,11,4,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,0,40,0,213,161,242,209,13,6,4,105,99,111,110,1,119,0,40,0,213,161,242,209,13,6,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,213,161,242,209,13,6,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,213,161,242,209,13,6,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,213,161,242,209,13,16,1,161,213,161,242,209,13,8,1,161,213,161,242,209,13,18,1,161,213,161,242,209,13,19,1,168,213,161,242,209,13,20,1,119,4,71,114,105,100,168,213,161,242,209,13,21,1,122,4,56,115,160,190,64,16,0,168,213,161,242,209,13,22,1,122,0,0,0,0,102,48,178,16,136,152,158,185,230,10,6,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,48,178,16,2,105,100,119,36,55,101,98,54,57,55,99,100,45,54,97,53,53,45,52,48,98,98,45,57,54,97,99,45,48,100,52,97,51,98,99,57,50,52,98,50,161,133,159,138,205,12,127,1,161,133,159,138,205,12,53,1,161,133,159,138,205,12,58,1,129,213,161,242,209,13,2,1,161,213,161,242,209,13,27,1,161,213,161,242,209,13,0,1,161,213,161,242,209,13,5,1,129,213,161,242,209,13,30,1,64,173,252,148,184,13,0,161,156,148,170,169,10,12,1,161,156,148,170,169,10,9,1,161,156,148,170,169,10,10,1,129,156,148,170,169,10,15,1,161,173,252,148,184,13,0,1,161,164,155,139,169,7,0,1,161,164,155,139,169,7,1,1,129,164,155,139,169,7,34,1,161,173,252,148,184,13,4,1,161,161,178,132,150,11,58,1,161,161,178,132,150,11,59,1,129,173,252,148,184,13,7,1,161,173,252,148,184,13,8,1,161,164,155,139,169,7,32,1,161,164,155,139,169,7,33,1,129,173,252,148,184,13,11,1,161,173,252,148,184,13,12,1,161,164,155,139,169,7,8,1,161,164,155,139,169,7,9,1,129,173,252,148,184,13,15,1,161,173,252,148,184,13,16,1,161,173,252,148,184,13,13,1,161,173,252,148,184,13,14,1,129,173,252,148,184,13,19,1,161,173,252,148,184,13,20,1,161,173,252,148,184,13,9,1,161,173,252,148,184,13,10,1,129,173,252,148,184,13,23,1,161,173,252,148,184,13,24,1,161,173,252,148,184,13,21,1,161,173,252,148,184,13,22,1,129,173,252,148,184,13,27,1,161,173,252,148,184,13,28,1,161,164,155,139,169,7,28,1,161,164,155,139,169,7,29,1,129,173,252,148,184,13,31,1,161,173,252,148,184,13,32,1,161,173,252,148,184,13,29,1,161,173,252,148,184,13,30,1,129,173,252,148,184,13,35,1,136,207,228,238,162,8,22,1,118,1,2,105,100,119,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,161,173,252,148,184,13,33,1,161,173,252,148,184,13,34,1,168,130,180,254,251,6,6,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,161,173,252,148,184,13,36,1,161,173,252,148,184,13,41,1,161,173,252,148,184,13,42,1,129,173,252,148,184,13,39,1,161,173,252,148,184,13,44,1,161,173,252,148,184,13,37,1,161,173,252,148,184,13,38,1,129,173,252,148,184,13,47,1,161,173,252,148,184,13,48,1,161,173,252,148,184,13,25,1,161,173,252,148,184,13,26,1,129,173,252,148,184,13,51,1,161,173,252,148,184,13,52,1,161,173,252,148,184,13,49,1,161,173,252,148,184,13,50,1,129,173,252,148,184,13,55,1,161,173,252,148,184,13,56,1,161,173,252,148,184,13,5,1,161,173,252,148,184,13,6,1,129,173,252,148,184,13,59,1,30,243,239,182,181,13,0,136,240,149,229,225,6,0,1,118,1,2,105,100,119,36,53,54,54,56,57,101,52,50,45,49,102,101,56,45,52,97,97,102,45,56,50,99,53,45,99,51,100,99,98,102,99,51,98,50,53,52,161,240,149,229,225,6,1,1,161,240,149,229,225,6,2,1,39,0,203,184,221,173,11,1,36,53,54,54,56,57,101,52,50,45,49,102,101,56,45,52,97,97,102,45,56,50,99,53,45,99,51,100,99,98,102,99,51,98,50,53,52,1,40,0,243,239,182,181,13,3,2,105,100,1,119,36,53,54,54,56,57,101,52,50,45,49,102,101,56,45,52,97,97,102,45,56,50,99,53,45,99,51,100,99,98,102,99,51,98,50,53,52,40,0,243,239,182,181,13,3,4,110,97,109,101,1,119,0,40,0,243,239,182,181,13,3,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,243,239,182,181,13,3,4,100,101,115,99,1,119,0,40,0,243,239,182,181,13,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,243,239,182,181,13,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,141,103,39,0,203,184,221,173,11,4,36,53,54,54,56,57,101,52,50,45,49,102,101,56,45,52,97,97,102,45,56,50,99,53,45,99,51,100,99,98,102,99,51,98,50,53,52,0,40,0,243,239,182,181,13,3,4,105,99,111,110,1,119,0,40,0,243,239,182,181,13,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,243,239,182,181,13,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,101,241,141,103,40,0,243,239,182,181,13,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,136,243,239,182,181,13,0,1,118,1,2,105,100,119,36,51,53,100,51,57,57,98,57,45,49,57,55,101,45,52,57,99,54,45,97,98,102,56,45,101,51,57,51,49,101,48,97,55,51,49,51,161,243,239,182,181,13,1,1,161,243,239,182,181,13,2,1,39,0,203,184,221,173,11,1,36,51,53,100,51,57,57,98,57,45,49,57,55,101,45,52,57,99,54,45,97,98,102,56,45,101,51,57,51,49,101,48,97,55,51,49,51,1,40,0,243,239,182,181,13,18,2,105,100,1,119,36,51,53,100,51,57,57,98,57,45,49,57,55,101,45,52,57,99,54,45,97,98,102,56,45,101,51,57,51,49,101,48,97,55,51,49,51,40,0,243,239,182,181,13,18,4,110,97,109,101,1,119,0,40,0,243,239,182,181,13,18,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,243,239,182,181,13,18,4,100,101,115,99,1,119,0,40,0,243,239,182,181,13,18,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,243,239,182,181,13,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,141,156,39,0,203,184,221,173,11,4,36,51,53,100,51,57,57,98,57,45,49,57,55,101,45,52,57,99,54,45,97,98,102,56,45,101,51,57,51,49,101,48,97,55,51,49,51,0,40,0,243,239,182,181,13,18,4,105,99,111,110,1,119,0,40,0,243,239,182,181,13,18,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,243,239,182,181,13,18,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,101,241,141,156,40,0,243,239,182,181,13,18,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,1,161,239,241,154,13,0,161,158,184,218,165,3,37,106,72,166,201,221,141,13,0,161,182,172,247,194,5,0,1,161,182,172,247,194,5,1,1,129,182,172,247,194,5,2,1,161,170,255,211,105,34,1,161,245,220,194,52,9,1,161,245,220,194,52,10,1,136,166,201,221,141,13,2,1,118,2,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,132,208,161,166,201,221,141,13,4,1,161,166,201,221,141,13,5,1,136,166,201,221,141,13,6,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,132,209,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,166,201,221,141,13,7,1,161,166,201,221,141,13,8,1,136,166,201,221,141,13,9,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,134,151,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,166,201,221,141,13,10,1,161,166,201,221,141,13,11,1,136,166,201,221,141,13,12,1,118,2,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,134,152,39,0,203,184,221,173,11,1,36,98,98,101,55,102,100,54,99,45,99,99,56,102,45,53,48,55,57,45,98,48,52,53,45,54,49,57,55,52,99,48,57,57,98,54,100,1,40,0,166,201,221,141,13,16,2,105,100,1,119,36,98,98,101,55,102,100,54,99,45,99,99,56,102,45,53,48,55,57,45,98,48,52,53,45,54,49,57,55,52,99,48,57,57,98,54,100,40,0,166,201,221,141,13,16,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,166,201,221,141,13,16,3,98,105,100,1,119,36,98,98,101,55,102,100,54,99,45,99,99,56,102,45,53,48,55,57,45,98,48,52,53,45,54,49,57,55,52,99,48,57,57,98,54,100,40,0,166,201,221,141,13,16,4,100,101,115,99,1,119,0,40,0,166,201,221,141,13,16,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,166,201,221,141,13,16,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,85,140,82,39,0,203,184,221,173,11,4,36,98,98,101,55,102,100,54,99,45,99,99,56,102,45,53,48,55,57,45,98,48,52,53,45,54,49,57,55,52,99,48,57,57,98,54,100,0,40,0,166,201,221,141,13,16,4,105,99,111,110,1,119,0,40,0,166,201,221,141,13,16,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,166,201,221,141,13,16,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,166,201,221,141,13,16,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,166,201,221,141,13,27,1,122,4,56,115,160,190,64,16,0,168,166,201,221,141,13,26,1,122,0,0,0,0,102,85,140,82,40,0,166,201,221,141,13,16,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,166,201,221,141,13,0,1,161,166,201,221,141,13,1,1,136,166,201,221,141,13,15,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,167,96,2,105,100,119,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,161,166,201,221,141,13,3,1,161,166,201,221,141,13,31,1,161,166,201,221,141,13,32,1,136,166,201,221,141,13,33,1,118,2,2,105,100,119,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,167,97,161,166,201,221,141,13,35,1,161,166,201,221,141,13,36,1,161,245,220,194,52,38,1,161,166,201,221,141,13,38,1,161,166,201,221,141,13,39,1,161,166,201,221,141,13,40,1,136,140,152,206,145,6,100,1,118,1,2,105,100,119,36,50,97,54,101,53,101,50,49,45,97,57,51,56,45,52,53,97,53,45,97,52,52,53,45,100,48,98,55,49,52,57,53,98,48,55,55,161,140,152,206,145,6,101,1,161,245,220,194,52,7,1,39,0,203,184,221,173,11,1,36,50,97,54,101,53,101,50,49,45,97,57,51,56,45,52,53,97,53,45,97,52,52,53,45,100,48,98,55,49,52,57,53,98,48,55,55,1,40,0,166,201,221,141,13,47,2,105,100,1,119,36,50,97,54,101,53,101,50,49,45,97,57,51,56,45,52,53,97,53,45,97,52,52,53,45,100,48,98,55,49,52,57,53,98,48,55,55,40,0,166,201,221,141,13,47,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,166,201,221,141,13,47,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,166,201,221,141,13,47,4,100,101,115,99,1,119,0,40,0,166,201,221,141,13,47,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,166,201,221,141,13,47,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,86,193,40,39,0,203,184,221,173,11,4,36,50,97,54,101,53,101,50,49,45,97,57,51,56,45,52,53,97,53,45,97,52,52,53,45,100,48,98,55,49,52,57,53,98,48,55,55,0,40,0,166,201,221,141,13,47,4,105,99,111,110,1,119,0,40,0,166,201,221,141,13,47,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,166,201,221,141,13,47,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,166,201,221,141,13,47,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,166,201,221,141,13,34,1,161,166,201,221,141,13,58,1,161,166,201,221,141,13,57,1,129,166,201,221,141,13,37,1,161,166,201,221,141,13,60,1,161,166,201,221,141,13,61,1,129,166,201,221,141,13,62,1,161,166,201,221,141,13,63,1,161,166,201,221,141,13,64,1,40,0,166,201,221,141,13,47,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,166,201,221,141,13,66,1,161,166,201,221,141,13,67,1,129,166,201,221,141,13,65,1,2,180,205,189,133,13,0,161,200,142,208,241,4,152,1,16,161,180,205,189,133,13,15,4,1,248,210,237,129,13,0,161,223,209,193,147,11,80,2,7,211,202,217,232,12,0,161,141,245,194,142,11,4,1,161,141,245,194,142,11,5,1,129,141,245,194,142,11,6,1,161,141,245,194,142,11,3,1,161,141,245,194,142,11,0,1,161,141,245,194,142,11,1,1,129,211,202,217,232,12,2,1,3,210,228,153,221,12,0,161,202,160,246,212,1,3,1,161,202,160,246,212,1,4,1,161,202,160,246,212,1,5,1,1,181,175,219,209,12,0,161,200,159,185,206,9,7,10,131,1,133,159,138,205,12,0,161,255,140,248,220,6,0,1,161,255,140,248,220,6,1,1,129,255,140,248,220,6,2,1,161,180,230,210,212,13,3,1,161,161,178,132,150,11,34,1,161,161,178,132,150,11,35,1,129,133,159,138,205,12,2,1,8,0,229,154,128,197,12,16,1,118,1,2,105,100,119,36,98,54,51,52,55,97,99,98,45,51,49,55,52,45,52,102,48,101,45,57,56,101,57,45,100,99,99,101,48,55,101,53,100,98,102,55,168,229,154,128,197,12,15,1,122,0,0,0,0,102,48,108,125,161,180,230,210,212,13,1,1,39,0,203,184,221,173,11,1,36,98,54,51,52,55,97,99,98,45,51,49,55,52,45,52,102,48,101,45,57,56,101,57,45,100,99,99,101,48,55,101,53,100,98,102,55,1,40,0,133,159,138,205,12,10,2,105,100,1,119,36,98,54,51,52,55,97,99,98,45,51,49,55,52,45,52,102,48,101,45,57,56,101,57,45,100,99,99,101,48,55,101,53,100,98,102,55,40,0,133,159,138,205,12,10,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,133,159,138,205,12,10,3,98,105,100,1,119,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,40,0,133,159,138,205,12,10,4,100,101,115,99,1,119,0,40,0,133,159,138,205,12,10,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,133,159,138,205,12,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,125,39,0,203,184,221,173,11,4,36,98,54,51,52,55,97,99,98,45,51,49,55,52,45,52,102,48,101,45,57,56,101,57,45,100,99,99,101,48,55,101,53,100,98,102,55,0,40,0,133,159,138,205,12,10,4,105,99,111,110,1,119,0,40,0,133,159,138,205,12,10,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,133,159,138,205,12,10,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,133,159,138,205,12,10,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,133,159,138,205,12,3,1,161,133,159,138,205,12,21,1,161,133,159,138,205,12,20,1,129,133,159,138,205,12,6,1,161,133,159,138,205,12,23,1,161,133,159,138,205,12,24,1,129,133,159,138,205,12,25,1,72,229,154,128,197,12,6,1,118,1,2,105,100,119,36,102,51,53,50,55,48,99,55,45,99,54,54,99,45,52,54,99,101,45,56,101,49,97,45,51,102,54,51,57,102,55,98,48,48,48,100,168,229,154,128,197,12,7,1,122,0,0,0,0,102,48,108,128,168,229,154,128,197,12,8,1,122,0,0,0,0,102,48,108,128,39,0,203,184,221,173,11,1,36,102,51,53,50,55,48,99,55,45,99,54,54,99,45,52,54,99,101,45,56,101,49,97,45,51,102,54,51,57,102,55,98,48,48,48,100,1,40,0,133,159,138,205,12,32,2,105,100,1,119,36,102,51,53,50,55,48,99,55,45,99,54,54,99,45,52,54,99,101,45,56,101,49,97,45,51,102,54,51,57,102,55,98,48,48,48,100,40,0,133,159,138,205,12,32,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,133,159,138,205,12,32,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,133,159,138,205,12,32,4,100,101,115,99,1,119,0,40,0,133,159,138,205,12,32,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,133,159,138,205,12,32,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,108,128,39,0,203,184,221,173,11,4,36,102,51,53,50,55,48,99,55,45,99,54,54,99,45,52,54,99,101,45,56,101,49,97,45,51,102,54,51,57,102,55,98,48,48,48,100,0,40,0,133,159,138,205,12,32,4,105,99,111,110,1,119,0,40,0,133,159,138,205,12,32,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,133,159,138,205,12,32,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,133,159,138,205,12,32,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,133,159,138,205,12,22,1,161,133,159,138,205,12,43,1,161,133,159,138,205,12,42,1,129,133,159,138,205,12,28,1,161,133,159,138,205,12,44,1,161,133,159,138,205,12,26,1,161,133,159,138,205,12,27,1,129,133,159,138,205,12,47,1,161,133,159,138,205,12,48,1,161,133,159,138,205,12,0,1,161,133,159,138,205,12,1,1,129,133,159,138,205,12,51,1,136,173,252,148,184,13,40,1,118,1,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,207,228,238,162,8,23,1,161,133,159,138,205,12,54,1,39,0,203,184,221,173,11,1,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,1,40,0,133,159,138,205,12,59,2,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,33,0,133,159,138,205,12,59,4,110,97,109,101,1,40,0,133,159,138,205,12,59,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,133,159,138,205,12,59,4,100,101,115,99,1,119,0,40,0,133,159,138,205,12,59,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,33,0,133,159,138,205,12,59,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,0,33,0,133,159,138,205,12,59,4,105,99,111,110,1,40,0,133,159,138,205,12,59,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,133,159,138,205,12,59,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,133,159,138,205,12,59,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,133,159,138,205,12,52,1,161,133,159,138,205,12,70,1,161,133,159,138,205,12,69,1,129,133,159,138,205,12,55,1,161,133,159,138,205,12,72,1,161,133,159,138,205,12,73,1,129,133,159,138,205,12,74,1,161,133,159,138,205,12,75,1,161,133,159,138,205,12,76,1,161,133,159,138,205,12,61,1,161,133,159,138,205,12,78,1,161,133,159,138,205,12,79,1,161,133,159,138,205,12,80,1,161,201,129,238,197,4,27,1,161,201,129,238,197,4,28,1,168,133,159,138,205,12,67,1,119,23,123,34,116,121,34,58,48,44,34,118,97,108,117,101,34,58,34,240,159,141,182,34,125,161,133,159,138,205,12,84,1,161,133,159,138,205,12,85,1,161,133,159,138,205,12,83,1,161,133,159,138,205,12,87,1,161,133,159,138,205,12,88,1,161,133,159,138,205,12,89,1,8,0,133,159,138,205,12,66,1,118,1,2,105,100,119,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,161,133,159,138,205,12,65,1,161,133,159,138,205,12,91,1,39,0,203,184,221,173,11,1,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,1,40,0,133,159,138,205,12,96,2,105,100,1,119,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,40,0,133,159,138,205,12,96,4,110,97,109,101,1,119,5,66,111,97,114,100,40,0,133,159,138,205,12,96,3,98,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,133,159,138,205,12,96,4,100,101,115,99,1,119,0,40,0,133,159,138,205,12,96,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,40,0,133,159,138,205,12,96,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,177,159,39,0,203,184,221,173,11,4,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,0,40,0,133,159,138,205,12,96,4,105,99,111,110,1,119,0,40,0,133,159,138,205,12,96,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,133,159,138,205,12,96,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,133,159,138,205,12,96,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,136,133,159,138,205,12,93,1,118,1,2,105,100,119,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,161,133,159,138,205,12,94,1,161,133,159,138,205,12,95,1,39,0,203,184,221,173,11,1,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,1,40,0,133,159,138,205,12,111,2,105,100,1,119,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,40,0,133,159,138,205,12,111,4,110,97,109,101,1,119,8,67,97,108,101,110,100,97,114,40,0,133,159,138,205,12,111,3,98,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,133,159,138,205,12,111,4,100,101,115,99,1,119,0,40,0,133,159,138,205,12,111,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,3,40,0,133,159,138,205,12,111,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,48,177,162,39,0,203,184,221,173,11,4,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,0,40,0,133,159,138,205,12,111,4,105,99,111,110,1,119,0,40,0,133,159,138,205,12,111,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,133,159,138,205,12,111,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,133,159,138,205,12,111,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,133,159,138,205,12,71,1,161,133,159,138,205,12,4,1,161,133,159,138,205,12,5,1,129,201,129,238,197,4,29,1,161,133,159,138,205,12,123,1,161,133,159,138,205,12,90,1,161,133,159,138,205,12,110,1,129,133,159,138,205,12,126,1,23,229,154,128,197,12,0,161,248,153,216,10,0,1,161,248,153,216,10,1,1,129,248,153,216,10,2,1,161,229,154,128,197,12,0,1,161,229,154,128,197,12,1,1,129,229,154,128,197,12,2,1,72,158,156,181,152,10,6,1,118,1,2,105,100,119,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,161,176,154,159,227,1,2,1,161,176,154,159,227,1,3,1,39,0,203,184,221,173,11,1,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,1,40,0,229,154,128,197,12,9,2,105,100,1,119,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,40,0,229,154,128,197,12,9,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,229,154,128,197,12,9,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,229,154,128,197,12,9,4,100,101,115,99,1,119,0,40,0,229,154,128,197,12,9,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,33,0,229,154,128,197,12,9,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,0,40,0,229,154,128,197,12,9,4,105,99,111,110,1,119,0,40,0,229,154,128,197,12,9,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,229,154,128,197,12,9,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,229,154,128,197,12,9,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,229,154,128,197,12,19,1,129,229,154,128,197,12,5,1,16,149,129,169,191,12,0,161,186,197,166,179,15,3,1,161,188,171,136,250,8,0,1,161,188,171,136,250,8,1,1,129,188,171,136,250,8,2,1,161,149,129,169,191,12,0,1,161,200,205,214,172,10,27,1,161,200,205,214,172,10,28,1,129,149,129,169,191,12,3,1,161,149,129,169,191,12,4,1,161,149,129,169,191,12,1,1,161,149,129,169,191,12,2,1,129,149,129,169,191,12,7,1,161,149,129,169,191,12,8,1,161,186,197,166,179,15,0,1,161,186,197,166,179,15,1,1,129,149,129,169,191,12,11,1,10,177,161,136,243,11,0,161,241,155,213,233,1,49,1,161,241,155,213,233,1,50,1,129,214,139,213,136,8,65,1,161,214,139,213,136,8,63,1,161,214,139,213,136,8,64,1,129,177,161,136,243,11,2,1,161,241,155,213,233,1,21,1,161,177,161,136,243,11,3,1,161,177,161,136,243,11,4,1,129,177,161,136,243,11,5,1,1,205,149,231,236,11,0,161,175,147,217,214,1,32,68,3,162,159,252,196,11,0,161,233,247,183,159,1,1,1,161,233,247,183,159,1,2,1,129,233,247,183,159,1,3,1,37,203,184,221,173,11,0,39,1,4,100,97,116,97,6,102,111,108,100,101,114,1,39,0,203,184,221,173,11,0,5,118,105,101,119,115,1,39,0,203,184,221,173,11,0,7,115,101,99,116,105,111,110,1,39,0,203,184,221,173,11,0,4,109,101,116,97,1,39,0,203,184,221,173,11,0,8,114,101,108,97,116,105,111,110,1,39,0,203,184,221,173,11,2,8,102,97,118,111,114,105,116,101,1,39,0,203,184,221,173,11,2,6,114,101,99,101,110,116,1,39,0,203,184,221,173,11,2,5,116,114,97,115,104,1,39,0,203,184,221,173,11,1,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,1,40,0,203,184,221,173,11,8,2,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,203,184,221,173,11,8,4,110,97,109,101,1,119,9,87,111,114,107,115,112,97,99,101,40,0,203,184,221,173,11,8,3,98,105,100,1,119,0,40,0,203,184,221,173,11,8,4,100,101,115,99,1,119,0,40,0,203,184,221,173,11,8,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,33,0,203,184,221,173,11,8,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,0,8,0,203,184,221,173,11,15,1,118,1,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,203,184,221,173,11,8,4,105,99,111,110,1,119,0,40,0,203,184,221,173,11,8,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,203,184,221,173,11,8,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,40,0,203,184,221,173,11,8,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,161,203,184,221,173,11,14,1,161,203,184,221,173,11,19,1,39,0,203,184,221,173,11,1,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,1,40,0,203,184,221,173,11,23,2,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,203,184,221,173,11,23,4,110,97,109,101,1,119,15,71,101,116,116,105,110,103,32,115,116,97,114,116,101,100,40,0,203,184,221,173,11,23,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,203,184,221,173,11,23,4,100,101,115,99,1,119,0,40,0,203,184,221,173,11,23,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,33,0,203,184,221,173,11,23,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,0,40,0,203,184,221,173,11,23,4,105,99,111,110,1,119,25,123,34,116,121,34,58,48,44,34,118,97,108,117,101,34,58,34,226,173,144,239,184,143,34,125,40,0,203,184,221,173,11,23,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,203,184,221,173,11,23,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,203,184,221,173,11,23,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,40,0,203,184,221,173,11,3,17,99,117,114,114,101,110,116,95,119,111,114,107,115,112,97,99,101,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,33,0,203,184,221,173,11,3,12,99,117,114,114,101,110,116,95,118,105,101,119,1,3,155,165,205,152,11,0,161,179,252,154,44,0,1,161,179,252,154,44,1,1,129,179,252,154,44,2,1,101,161,178,132,150,11,0,161,167,131,133,162,9,8,1,161,167,131,133,162,9,9,1,129,167,131,133,162,9,10,1,161,167,131,133,162,9,7,1,161,252,218,241,167,14,0,1,161,252,218,241,167,14,1,1,129,161,178,132,150,11,2,1,161,161,178,132,150,11,3,1,161,161,178,132,150,11,0,1,161,161,178,132,150,11,1,1,129,161,178,132,150,11,6,1,161,161,178,132,150,11,7,1,161,130,180,254,251,6,15,1,161,130,180,254,251,6,16,1,129,161,178,132,150,11,10,1,8,0,130,180,254,251,6,10,1,118,1,2,105,100,119,36,52,56,99,53,50,99,102,55,45,98,102,57,56,45,52,51,102,97,45,57,54,97,100,45,98,51,49,97,97,100,101,57,98,48,55,49,168,130,180,254,251,6,9,1,122,0,0,0,0,102,32,220,196,161,161,178,132,150,11,13,1,39,0,203,184,221,173,11,1,36,52,56,99,53,50,99,102,55,45,98,102,57,56,45,52,51,102,97,45,57,54,97,100,45,98,51,49,97,97,100,101,57,98,48,55,49,1,40,0,161,178,132,150,11,18,2,105,100,1,119,36,52,56,99,53,50,99,102,55,45,98,102,57,56,45,52,51,102,97,45,57,54,97,100,45,98,51,49,97,97,100,101,57,98,48,55,49,40,0,161,178,132,150,11,18,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,161,178,132,150,11,18,3,98,105,100,1,119,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,40,0,161,178,132,150,11,18,4,100,101,115,99,1,119,0,40,0,161,178,132,150,11,18,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,161,178,132,150,11,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,32,220,196,39,0,203,184,221,173,11,4,36,52,56,99,53,50,99,102,55,45,98,102,57,56,45,52,51,102,97,45,57,54,97,100,45,98,51,49,97,97,100,101,57,98,48,55,49,0,40,0,161,178,132,150,11,18,4,105,99,111,110,1,119,0,40,0,161,178,132,150,11,18,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,161,178,132,150,11,18,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,161,178,132,150,11,18,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,161,178,132,150,11,11,1,161,161,178,132,150,11,29,1,161,161,178,132,150,11,28,1,129,161,178,132,150,11,14,1,161,161,178,132,150,11,31,1,161,161,178,132,150,11,32,1,129,161,178,132,150,11,33,1,161,161,178,132,150,11,30,1,161,161,178,132,150,11,8,1,161,161,178,132,150,11,9,1,129,161,178,132,150,11,36,1,161,161,178,132,150,11,37,1,161,167,131,133,162,9,4,1,161,167,131,133,162,9,5,1,129,161,178,132,150,11,40,1,161,161,178,132,150,11,41,1,161,161,178,132,150,11,38,1,161,161,178,132,150,11,39,1,129,161,178,132,150,11,44,1,161,161,178,132,150,11,45,1,161,161,178,132,150,11,42,1,161,161,178,132,150,11,43,1,129,161,178,132,150,11,48,1,161,161,178,132,150,11,49,1,161,161,178,132,150,11,46,1,161,161,178,132,150,11,47,1,129,161,178,132,150,11,52,1,161,161,178,132,150,11,53,1,161,161,178,132,150,11,4,1,161,161,178,132,150,11,5,1,129,161,178,132,150,11,56,1,161,161,178,132,150,11,57,1,161,161,178,132,150,11,54,1,161,161,178,132,150,11,55,1,129,161,178,132,150,11,60,1,161,161,178,132,150,11,61,1,161,161,178,132,150,11,50,1,161,161,178,132,150,11,51,1,129,161,178,132,150,11,64,1,161,161,178,132,150,11,65,1,161,161,178,132,150,11,62,1,161,161,178,132,150,11,63,1,129,161,178,132,150,11,68,1,161,161,178,132,150,11,69,1,161,161,178,132,150,11,66,1,161,161,178,132,150,11,67,1,129,161,178,132,150,11,72,1,161,161,178,132,150,11,73,1,161,161,178,132,150,11,70,1,161,161,178,132,150,11,71,1,129,161,178,132,150,11,76,1,161,161,178,132,150,11,77,1,161,161,178,132,150,11,74,1,161,161,178,132,150,11,75,1,129,161,178,132,150,11,80,1,161,161,178,132,150,11,81,1,161,161,178,132,150,11,78,1,161,161,178,132,150,11,79,1,129,161,178,132,150,11,84,1,161,161,178,132,150,11,85,1,161,161,178,132,150,11,82,1,161,161,178,132,150,11,83,1,136,161,178,132,150,11,88,1,118,2,2,105,100,119,36,99,97,49,50,50,99,48,52,45,100,55,98,51,45,52,102,55,48,45,57,57,53,49,45,57,54,98,102,100,97,57,98,54,98,50,52,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,33,243,102,161,161,178,132,150,11,89,1,161,161,178,132,150,11,86,1,161,161,178,132,150,11,87,1,129,161,178,132,150,11,92,1,161,161,178,132,150,11,93,1,161,167,131,133,162,9,0,1,161,167,131,133,162,9,1,1,129,161,178,132,150,11,96,1,1,223,209,193,147,11,0,161,213,255,156,145,1,1,81,7,141,245,194,142,11,0,161,158,182,250,251,9,12,1,161,158,182,250,251,9,13,1,129,158,182,250,251,9,14,1,161,158,182,250,251,9,11,1,161,158,182,250,251,9,8,1,161,158,182,250,251,9,9,1,129,141,245,194,142,11,2,1,3,253,205,145,137,11,0,161,180,205,189,133,13,15,1,161,180,205,189,133,13,19,5,161,253,205,145,137,11,5,4,3,142,130,192,134,11,0,161,207,228,238,162,8,47,1,161,207,228,238,162,8,48,1,161,207,228,238,162,8,46,1,1,139,152,215,249,10,0,161,231,189,134,196,8,76,34,1,255,255,147,249,10,0,161,182,143,233,195,4,110,3,2,152,158,185,230,10,0,39,0,203,184,221,173,11,7,18,51,48,52,49,50,48,49,48,57,48,55,49,51,51,57,53,50,48,0,8,0,152,158,185,230,10,0,6,118,2,2,105,100,119,36,101,48,102,101,54,56,54,55,45,50,48,56,102,45,52,51,57,57,45,97,56,56,97,45,101,57,98,97,102,52,56,97,99,48,53,101,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,241,153,125,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,241,153,129,2,105,100,119,36,53,54,54,56,57,101,52,50,45,49,102,101,56,45,52,97,97,102,45,56,50,99,53,45,99,51,100,99,98,102,99,51,98,50,53,52,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,241,153,131,2,105,100,119,36,51,53,100,51,57,57,98,57,45,49,57,55,101,45,52,57,99,54,45,97,98,102,56,45,101,51,57,51,49,101,48,97,55,51,49,51,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,241,153,133,2,105,100,119,36,50,57,55,48,52,49,52,101,45,99,99,50,48,45,52,51,50,102,45,97,100,49,54,45,52,50,101,99,55,49,55,51,54,100,53,57,118,2,2,105,100,119,36,102,57,101,48,48,54,53,49,45,49,53,48,101,45,52,50,56,56,45,56,48,55,57,45,50,50,100,48,54,97,50,55,54,97,55,49,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,241,153,136,118,2,2,105,100,119,36,56,54,54,57,52,102,97,100,45,54,55,52,97,45,52,54,55,52,45,56,52,100,48,45,51,50,99,52,56,54,97,55,55,48,98,52,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,241,153,140,1,145,190,137,224,10,0,161,155,159,180,195,15,5,2,3,178,162,190,217,10,0,161,184,201,188,172,10,0,1,161,184,201,188,172,10,1,1,161,184,201,188,172,10,2,1,3,197,254,154,201,10,0,161,244,226,228,149,2,1,1,161,244,226,228,149,2,2,1,129,244,226,228,149,2,29,1,2,248,196,187,185,10,0,161,252,171,209,175,15,3,26,168,248,196,187,185,10,25,1,122,0,0,0,0,102,88,52,95,1,135,240,136,178,10,0,161,184,231,170,67,5,45,30,200,205,214,172,10,0,161,161,178,132,150,11,12,1,161,161,178,132,150,11,17,1,129,186,197,166,179,15,6,1,161,200,205,214,172,10,0,1,161,200,205,214,172,10,1,1,129,200,205,214,172,10,2,1,161,186,197,166,179,15,4,1,161,186,197,166,179,15,5,1,129,200,205,214,172,10,5,1,161,200,205,214,172,10,3,1,161,200,205,214,172,10,4,1,129,200,205,214,172,10,8,1,161,200,205,214,172,10,9,1,161,200,205,214,172,10,10,1,129,200,205,214,172,10,11,1,161,200,205,214,172,10,6,1,161,200,205,214,172,10,7,1,129,200,205,214,172,10,14,1,161,200,205,214,172,10,12,1,161,200,205,214,172,10,13,1,129,200,205,214,172,10,17,1,161,200,205,214,172,10,15,1,161,200,205,214,172,10,16,1,129,200,205,214,172,10,20,1,161,200,205,214,172,10,18,1,161,200,205,214,172,10,19,1,129,200,205,214,172,10,23,1,161,200,205,214,172,10,21,1,161,200,205,214,172,10,22,1,129,200,205,214,172,10,26,1,3,184,201,188,172,10,0,161,142,130,192,134,11,0,1,161,142,130,192,134,11,1,1,161,142,130,192,134,11,2,1,16,156,148,170,169,10,0,161,211,202,217,232,12,3,1,161,211,202,217,232,12,0,1,161,211,202,217,232,12,1,1,129,211,202,217,232,12,6,1,161,156,148,170,169,10,0,1,161,252,218,241,167,14,0,1,161,252,218,241,167,14,1,1,129,156,148,170,169,10,3,1,161,156,148,170,169,10,4,1,161,156,148,170,169,10,1,1,161,156,148,170,169,10,2,1,129,156,148,170,169,10,7,1,161,156,148,170,169,10,8,1,161,167,131,133,162,9,0,1,161,167,131,133,162,9,1,1,129,156,148,170,169,10,11,1,48,158,156,181,152,10,0,161,206,220,129,131,4,18,1,161,206,220,129,131,4,19,1,129,206,220,129,131,4,20,1,161,206,220,129,131,4,0,1,161,206,220,129,131,4,1,1,129,158,156,181,152,10,2,1,72,206,220,129,131,4,3,1,118,1,2,105,100,119,36,100,49,52,50,51,57,101,57,45,50,98,102,55,45,52,56,50,52,45,57,51,101,99,45,52,102,51,99,99,53,54,49,54,55,50,48,161,206,220,129,131,4,4,1,161,206,220,129,131,4,5,1,39,0,203,184,221,173,11,1,36,100,49,52,50,51,57,101,57,45,50,98,102,55,45,52,56,50,52,45,57,51,101,99,45,52,102,51,99,99,53,54,49,54,55,50,48,1,40,0,158,156,181,152,10,9,2,105,100,1,119,36,100,49,52,50,51,57,101,57,45,50,98,102,55,45,52,56,50,52,45,57,51,101,99,45,52,102,51,99,99,53,54,49,54,55,50,48,40,0,158,156,181,152,10,9,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,158,156,181,152,10,9,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,158,156,181,152,10,9,4,100,101,115,99,1,119,0,40,0,158,156,181,152,10,9,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,33,0,158,156,181,152,10,9,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,100,49,52,50,51,57,101,57,45,50,98,102,55,45,52,56,50,52,45,57,51,101,99,45,52,102,51,99,99,53,54,49,54,55,50,48,0,40,0,158,156,181,152,10,9,4,105,99,111,110,1,119,0,40,0,158,156,181,152,10,9,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,158,156,181,152,10,9,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,158,156,181,152,10,9,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,158,156,181,152,10,19,1,129,158,156,181,152,10,5,1,161,233,165,139,246,14,4,1,161,233,165,139,246,14,5,1,129,158,156,181,152,10,23,1,8,0,203,184,221,173,11,30,1,118,1,2,105,100,119,36,98,53,56,48,55,51,52,53,45,53,100,97,55,45,52,53,98,100,45,97,56,97,101,45,101,97,53,54,56,99,55,99,57,49,49,97,161,203,184,221,173,11,29,1,161,158,156,181,152,10,25,1,39,0,203,184,221,173,11,1,36,98,53,56,48,55,51,52,53,45,53,100,97,55,45,52,53,98,100,45,97,56,97,101,45,101,97,53,54,56,99,55,99,57,49,49,97,1,40,0,158,156,181,152,10,30,2,105,100,1,119,36,98,53,56,48,55,51,52,53,45,53,100,97,55,45,52,53,98,100,45,97,56,97,101,45,101,97,53,54,56,99,55,99,57,49,49,97,33,0,158,156,181,152,10,30,4,110,97,109,101,1,40,0,158,156,181,152,10,30,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,158,156,181,152,10,30,4,100,101,115,99,1,119,0,40,0,158,156,181,152,10,30,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,158,156,181,152,10,30,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,129,30,39,0,203,184,221,173,11,4,36,98,53,56,48,55,51,52,53,45,53,100,97,55,45,52,53,98,100,45,97,56,97,101,45,101,97,53,54,56,99,55,99,57,49,49,97,0,40,0,158,156,181,152,10,30,4,105,99,111,110,1,119,0,40,0,158,156,181,152,10,30,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,158,156,181,152,10,30,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,158,156,181,152,10,30,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,203,184,221,173,11,36,1,161,158,156,181,152,10,41,1,161,158,156,181,152,10,40,1,129,158,156,181,152,10,26,1,161,158,156,181,152,10,43,1,161,158,156,181,152,10,44,1,129,158,156,181,152,10,45,1,9,154,193,208,134,10,0,161,229,154,128,197,12,3,1,161,229,154,128,197,12,4,1,129,162,159,252,196,11,2,1,161,154,193,208,134,10,0,1,161,154,193,208,134,10,1,1,129,154,193,208,134,10,2,1,161,154,193,208,134,10,3,1,161,154,193,208,134,10,4,1,129,154,193,208,134,10,5,1,3,235,225,184,133,10,0,161,233,165,139,246,14,40,1,161,233,165,139,246,14,41,1,129,233,165,139,246,14,42,1,15,158,182,250,251,9,0,161,229,154,128,197,12,3,1,161,229,154,128,197,12,4,1,129,162,159,252,196,11,2,1,161,233,247,183,159,1,0,1,161,158,156,181,152,10,3,1,161,158,156,181,152,10,4,1,129,158,182,250,251,9,2,1,161,158,182,250,251,9,3,1,161,158,182,250,251,9,0,1,161,158,182,250,251,9,1,1,129,158,182,250,251,9,6,1,161,158,182,250,251,9,7,1,161,171,204,155,217,8,0,1,161,171,204,155,217,8,1,1,129,158,182,250,251,9,10,1,31,170,140,240,234,9,0,161,201,191,159,147,14,14,1,161,201,191,159,147,14,15,1,129,201,191,159,147,14,16,1,161,201,191,159,147,14,13,1,161,201,191,159,147,14,7,1,161,201,191,159,147,14,8,1,129,170,140,240,234,9,2,1,161,170,140,240,234,9,4,1,161,170,140,240,234,9,5,1,129,170,140,240,234,9,6,1,161,170,140,240,234,9,0,1,161,170,140,240,234,9,1,1,129,170,140,240,234,9,9,1,161,170,140,240,234,9,3,1,161,170,140,240,234,9,10,1,161,170,140,240,234,9,11,1,129,170,140,240,234,9,12,1,161,201,129,238,197,4,56,1,161,201,129,238,197,4,55,1,129,170,140,240,234,9,16,1,161,170,140,240,234,9,13,1,161,170,140,240,234,9,17,1,161,170,140,240,234,9,18,1,129,170,140,240,234,9,19,1,161,170,140,240,234,9,14,1,161,170,140,240,234,9,15,1,129,170,140,240,234,9,23,1,161,170,140,240,234,9,20,1,161,170,140,240,234,9,24,1,161,170,140,240,234,9,25,1,129,170,140,240,234,9,26,1,1,191,157,147,233,9,0,161,190,139,191,155,1,1,32,1,200,159,185,206,9,0,161,231,139,244,188,8,12,8,15,135,232,133,203,9,0,161,248,136,168,181,1,0,1,161,248,136,168,181,1,1,1,129,248,136,168,181,1,2,1,161,135,232,133,203,9,0,1,161,135,232,133,203,9,1,1,129,135,232,133,203,9,2,1,161,135,232,133,203,9,3,1,161,135,232,133,203,9,4,1,129,135,232,133,203,9,5,1,161,135,232,133,203,9,6,1,161,135,232,133,203,9,7,1,129,135,232,133,203,9,8,1,161,135,232,133,203,9,9,1,161,135,232,133,203,9,10,1,129,135,232,133,203,9,11,1,11,167,131,133,162,9,0,161,211,202,217,232,12,4,1,161,211,202,217,232,12,5,1,129,141,205,220,149,4,2,1,161,211,202,217,232,12,3,1,161,158,182,250,251,9,4,1,161,158,182,250,251,9,5,1,129,167,131,133,162,9,2,1,161,167,131,133,162,9,3,1,161,214,168,149,214,3,8,1,161,214,168,149,214,3,9,1,129,167,131,133,162,9,6,1,1,234,182,182,157,9,0,161,161,239,241,154,13,105,8,21,188,171,136,250,8,0,161,200,205,214,172,10,24,1,161,200,205,214,172,10,25,1,129,200,205,214,172,10,29,1,161,188,171,136,250,8,0,1,161,188,171,136,250,8,1,1,129,188,171,136,250,8,2,1,161,164,155,139,169,7,4,1,161,164,155,139,169,7,5,1,129,164,155,139,169,7,6,1,161,164,155,139,169,7,12,1,161,164,155,139,169,7,13,1,129,164,155,139,169,7,14,1,161,188,171,136,250,8,9,1,161,188,171,136,250,8,10,1,129,188,171,136,250,8,11,1,161,188,171,136,250,8,12,1,161,188,171,136,250,8,13,1,129,188,171,136,250,8,14,1,161,164,155,139,169,7,16,1,161,164,155,139,169,7,17,1,129,164,155,139,169,7,18,1,1,236,229,225,232,8,0,161,219,227,140,137,6,33,116,3,171,204,155,217,8,0,161,229,154,128,197,12,21,1,161,229,154,128,197,12,22,1,129,229,154,128,197,12,23,1,3,149,189,189,215,8,0,161,160,192,253,131,5,0,1,161,160,192,253,131,5,1,1,129,160,192,253,131,5,2,1,1,231,189,134,196,8,0,161,153,130,203,161,6,96,77,3,195,242,227,194,8,0,161,155,165,205,152,11,0,1,161,155,165,205,152,11,1,1,129,155,165,205,152,11,2,1,1,231,139,244,188,8,0,161,128,252,161,128,4,32,13,198,1,154,244,246,165,8,0,161,174,151,139,93,176,2,1,161,174,151,139,93,177,2,1,129,174,151,139,93,178,2,1,161,174,151,139,93,140,2,1,161,174,151,139,93,141,2,1,129,154,244,246,165,8,2,1,161,174,151,139,93,175,2,1,161,154,244,246,165,8,3,1,161,154,244,246,165,8,4,1,129,154,244,246,165,8,5,1,161,154,244,246,165,8,0,1,161,154,244,246,165,8,1,1,129,154,244,246,165,8,9,1,161,154,244,246,165,8,6,1,161,154,244,246,165,8,10,1,161,154,244,246,165,8,11,1,129,154,244,246,165,8,12,1,161,154,244,246,165,8,7,1,161,154,244,246,165,8,8,1,129,154,244,246,165,8,16,1,161,154,244,246,165,8,13,1,161,154,244,246,165,8,17,1,161,154,244,246,165,8,18,1,129,154,244,246,165,8,19,1,136,213,161,242,209,13,3,1,118,1,2,105,100,119,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,168,213,161,242,209,13,4,1,122,0,0,0,0,102,79,7,13,161,154,244,246,165,8,15,1,39,0,203,184,221,173,11,1,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,1,40,0,154,244,246,165,8,27,2,105,100,1,119,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,40,0,154,244,246,165,8,27,4,110,97,109,101,1,119,12,86,105,101,119,32,111,102,32,71,114,105,100,40,0,154,244,246,165,8,27,3,98,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,154,244,246,165,8,27,4,100,101,115,99,1,119,0,40,0,154,244,246,165,8,27,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,154,244,246,165,8,27,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,79,7,13,39,0,203,184,221,173,11,4,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,0,40,0,154,244,246,165,8,27,4,105,99,111,110,1,119,0,40,0,154,244,246,165,8,27,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,154,244,246,165,8,27,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,154,244,246,165,8,27,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,8,0,165,139,157,171,15,10,1,118,1,2,105,100,119,36,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,168,165,139,157,171,15,9,1,122,0,0,0,0,102,79,7,25,168,174,151,139,93,170,2,1,122,0,0,0,0,102,79,7,25,39,0,203,184,221,173,11,1,36,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,1,40,0,154,244,246,165,8,42,2,105,100,1,119,36,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,40,0,154,244,246,165,8,42,4,110,97,109,101,1,119,22,86,105,101,119,32,111,102,32,66,111,97,114,100,32,99,104,101,99,107,98,111,120,40,0,154,244,246,165,8,42,3,98,105,100,1,119,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,40,0,154,244,246,165,8,42,4,100,101,115,99,1,119,0,40,0,154,244,246,165,8,42,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,40,0,154,244,246,165,8,42,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,79,7,25,39,0,203,184,221,173,11,4,36,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,0,40,0,154,244,246,165,8,42,4,105,99,111,110,1,119,0,40,0,154,244,246,165,8,42,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,154,244,246,165,8,42,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,102,79,7,25,40,0,154,244,246,165,8,42,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,8,0,201,129,238,197,4,67,1,118,1,2,105,100,119,36,97,54,97,102,51,49,49,102,45,99,98,99,56,45,52,50,99,50,45,98,56,48,49,45,55,49,49,53,54,49,57,99,51,55,55,54,168,201,129,238,197,4,66,1,122,0,0,0,0,102,79,7,32,161,174,151,139,93,106,1,39,0,203,184,221,173,11,1,36,97,54,97,102,51,49,49,102,45,99,98,99,56,45,52,50,99,50,45,98,56,48,49,45,55,49,49,53,54,49,57,99,51,55,55,54,1,40,0,154,244,246,165,8,57,2,105,100,1,119,36,97,54,97,102,51,49,49,102,45,99,98,99,56,45,52,50,99,50,45,98,56,48,49,45,55,49,49,53,54,49,57,99,51,55,55,54,40,0,154,244,246,165,8,57,4,110,97,109,101,1,119,16,86,105,101,119,32,111,102,32,67,97,108,101,110,100,97,114,40,0,154,244,246,165,8,57,3,98,105,100,1,119,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,40,0,154,244,246,165,8,57,4,100,101,115,99,1,119,0,40,0,154,244,246,165,8,57,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,3,40,0,154,244,246,165,8,57,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,79,7,32,39,0,203,184,221,173,11,4,36,97,54,97,102,51,49,49,102,45,99,98,99,56,45,52,50,99,50,45,98,56,48,49,45,55,49,49,53,54,49,57,99,51,55,55,54,0,40,0,154,244,246,165,8,57,4,105,99,111,110,1,119,0,40,0,154,244,246,165,8,57,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,154,244,246,165,8,57,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,102,79,7,32,40,0,154,244,246,165,8,57,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,136,174,151,139,93,177,1,1,118,1,2,105,100,119,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,168,174,151,139,93,178,1,1,122,0,0,0,0,102,79,7,50,161,174,151,139,93,179,1,1,39,0,203,184,221,173,11,1,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,1,40,0,154,244,246,165,8,72,2,105,100,1,119,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,40,0,154,244,246,165,8,72,4,110,97,109,101,1,119,16,86,105,101,119,32,111,102,32,67,97,108,101,110,100,97,114,40,0,154,244,246,165,8,72,3,98,105,100,1,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,40,0,154,244,246,165,8,72,4,100,101,115,99,1,119,0,40,0,154,244,246,165,8,72,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,3,40,0,154,244,246,165,8,72,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,79,7,50,39,0,203,184,221,173,11,4,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,0,40,0,154,244,246,165,8,72,4,105,99,111,110,1,119,0,40,0,154,244,246,165,8,72,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,154,244,246,165,8,72,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,154,244,246,165,8,72,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,154,244,246,165,8,20,1,168,154,244,246,165,8,83,1,122,4,56,115,160,190,64,16,0,168,154,244,246,165,8,82,1,122,0,0,0,0,102,79,23,79,136,154,244,246,165,8,23,1,118,2,2,105,100,119,36,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,79,23,79,161,154,244,246,165,8,84,1,161,174,151,139,93,174,1,1,161,154,244,246,165,8,71,1,129,154,244,246,165,8,87,1,161,154,244,246,165,8,89,1,161,154,244,246,165,8,90,1,129,154,244,246,165,8,91,1,161,154,244,246,165,8,21,1,161,154,244,246,165,8,22,1,129,154,244,246,165,8,94,1,161,154,244,246,165,8,88,1,161,154,244,246,165,8,95,1,161,154,244,246,165,8,96,1,129,154,244,246,165,8,97,1,161,154,244,246,165,8,98,1,161,154,244,246,165,8,38,1,161,154,244,246,165,8,37,1,129,154,244,246,165,8,101,1,161,154,244,246,165,8,14,1,161,154,244,246,165,8,26,1,129,154,244,246,165,8,105,1,161,154,244,246,165,8,102,1,161,154,244,246,165,8,106,1,161,154,244,246,165,8,107,1,129,154,244,246,165,8,108,1,161,154,244,246,165,8,99,1,161,154,244,246,165,8,100,1,129,154,244,246,165,8,112,1,161,154,244,246,165,8,109,1,161,154,244,246,165,8,113,1,161,154,244,246,165,8,114,1,129,154,244,246,165,8,115,1,161,154,244,246,165,8,103,1,161,154,244,246,165,8,104,1,129,154,244,246,165,8,119,1,161,154,244,246,165,8,116,1,168,154,244,246,165,8,120,1,122,4,56,115,160,190,64,16,0,168,154,244,246,165,8,121,1,122,0,0,0,0,102,79,28,199,136,154,244,246,165,8,122,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,79,28,199,2,105,100,119,36,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,161,154,244,246,165,8,123,1,161,174,151,139,93,105,1,161,154,244,246,165,8,56,1,129,154,244,246,165,8,126,1,161,154,244,246,165,8,128,1,1,161,154,244,246,165,8,129,1,1,129,154,244,246,165,8,130,1,1,161,154,244,246,165,8,92,1,161,154,244,246,165,8,93,1,129,154,244,246,165,8,133,1,1,161,154,244,246,165,8,127,1,161,154,244,246,165,8,134,1,1,161,154,244,246,165,8,135,1,1,129,154,244,246,165,8,136,1,1,161,154,244,246,165,8,131,1,1,161,154,244,246,165,8,132,1,1,129,154,244,246,165,8,140,1,1,161,154,244,246,165,8,137,1,1,168,154,244,246,165,8,141,1,1,122,4,56,115,160,190,64,16,0,168,154,244,246,165,8,142,1,1,122,0,0,0,0,102,80,7,127,136,154,244,246,165,8,143,1,1,118,2,2,105,100,119,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,80,7,127,161,154,244,246,165,8,138,1,1,161,154,244,246,165,8,139,1,1,129,154,244,246,165,8,147,1,1,161,154,244,246,165,8,144,1,1,161,154,244,246,165,8,148,1,1,161,154,244,246,165,8,149,1,1,129,154,244,246,165,8,150,1,1,161,154,244,246,165,8,110,1,161,154,244,246,165,8,111,1,129,154,244,246,165,8,154,1,1,161,154,244,246,165,8,151,1,1,161,154,244,246,165,8,155,1,1,161,154,244,246,165,8,156,1,1,129,154,244,246,165,8,157,1,1,161,174,151,139,93,153,1,1,161,174,151,139,93,154,1,1,129,154,244,246,165,8,161,1,1,161,154,244,246,165,8,158,1,1,161,154,244,246,165,8,162,1,1,161,154,244,246,165,8,163,1,1,129,154,244,246,165,8,164,1,1,161,154,244,246,165,8,152,1,1,161,154,244,246,165,8,153,1,1,129,154,244,246,165,8,168,1,1,161,154,244,246,165,8,165,1,1,161,154,244,246,165,8,169,1,1,161,154,244,246,165,8,170,1,1,129,154,244,246,165,8,171,1,1,161,154,244,246,165,8,117,1,161,154,244,246,165,8,118,1,129,154,244,246,165,8,175,1,1,161,154,244,246,165,8,172,1,1,161,154,244,246,165,8,176,1,1,161,154,244,246,165,8,177,1,1,129,154,244,246,165,8,178,1,1,39,0,203,184,221,173,11,1,36,53,55,98,56,49,55,55,100,45,57,100,52,50,45,53,49,55,56,45,56,99,98,50,45,102,99,53,101,54,57,51,48,102,51,48,97,1,40,0,154,244,246,165,8,183,1,2,105,100,1,119,36,53,55,98,56,49,55,55,100,45,57,100,52,50,45,53,49,55,56,45,56,99,98,50,45,102,99,53,101,54,57,51,48,102,51,48,97,40,0,154,244,246,165,8,183,1,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,154,244,246,165,8,183,1,3,98,105,100,1,119,36,53,55,98,56,49,55,55,100,45,57,100,52,50,45,53,49,55,56,45,56,99,98,50,45,102,99,53,101,54,57,51,48,102,51,48,97,40,0,154,244,246,165,8,183,1,4,100,101,115,99,1,119,0,40,0,154,244,246,165,8,183,1,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,154,244,246,165,8,183,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,80,7,153,39,0,203,184,221,173,11,4,36,53,55,98,56,49,55,55,100,45,57,100,52,50,45,53,49,55,56,45,56,99,98,50,45,102,99,53,101,54,57,51,48,102,51,48,97,0,40,0,154,244,246,165,8,183,1,4,105,99,111,110,1,119,0,40,0,154,244,246,165,8,183,1,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,154,244,246,165,8,183,1,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,154,244,246,165,8,183,1,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,154,244,246,165,8,194,1,1,122,4,56,115,160,190,64,16,0,168,154,244,246,165,8,193,1,1,122,0,0,0,0,102,80,7,153,40,0,154,244,246,165,8,183,1,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,50,207,228,238,162,8,0,136,158,156,181,152,10,27,1,118,1,2,105,100,119,36,100,97,53,54,102,102,97,48,45,53,51,53,54,45,52,50,56,99,45,98,54,49,98,45,53,55,52,97,49,49,57,99,54,57,57,101,161,158,156,181,152,10,28,1,161,158,156,181,152,10,29,1,39,0,203,184,221,173,11,1,36,100,97,53,54,102,102,97,48,45,53,51,53,54,45,52,50,56,99,45,98,54,49,98,45,53,55,52,97,49,49,57,99,54,57,57,101,1,40,0,207,228,238,162,8,3,2,105,100,1,119,36,100,97,53,54,102,102,97,48,45,53,51,53,54,45,52,50,56,99,45,98,54,49,98,45,53,55,52,97,49,49,57,99,54,57,57,101,40,0,207,228,238,162,8,3,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,207,228,238,162,8,3,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,207,228,238,162,8,3,4,100,101,115,99,1,119,0,40,0,207,228,238,162,8,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,207,228,238,162,8,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,242,129,194,39,0,203,184,221,173,11,4,36,100,97,53,54,102,102,97,48,45,53,51,53,54,45,52,50,56,99,45,98,54,49,98,45,53,55,52,97,49,49,57,99,54,57,57,101,0,40,0,207,228,238,162,8,3,4,105,99,111,110,1,119,0,40,0,207,228,238,162,8,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,207,228,238,162,8,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,207,228,238,162,8,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,158,156,181,152,10,42,1,161,207,228,238,162,8,14,1,161,207,228,238,162,8,13,1,129,158,156,181,152,10,48,1,161,207,228,238,162,8,16,1,161,207,228,238,162,8,17,1,129,207,228,238,162,8,18,1,136,207,228,238,162,8,0,1,118,1,2,105,100,119,36,52,52,51,53,101,53,55,98,45,99,50,54,51,45,52,101,55,102,45,97,52,51,53,45,50,48,56,55,57,97,54,50,101,54,100,97,161,207,228,238,162,8,1,1,161,207,228,238,162,8,2,1,39,0,203,184,221,173,11,1,36,52,52,51,53,101,53,55,98,45,99,50,54,51,45,52,101,55,102,45,97,52,51,53,45,50,48,56,55,57,97,54,50,101,54,100,97,1,40,0,207,228,238,162,8,25,2,105,100,1,119,36,52,52,51,53,101,53,55,98,45,99,50,54,51,45,52,101,55,102,45,97,52,51,53,45,50,48,56,55,57,97,54,50,101,54,100,97,40,0,207,228,238,162,8,25,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,207,228,238,162,8,25,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,207,228,238,162,8,25,4,100,101,115,99,1,119,0,40,0,207,228,238,162,8,25,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,207,228,238,162,8,25,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,242,129,219,39,0,203,184,221,173,11,4,36,52,52,51,53,101,53,55,98,45,99,50,54,51,45,52,101,55,102,45,97,52,51,53,45,50,48,56,55,57,97,54,50,101,54,100,97,0,40,0,207,228,238,162,8,25,4,105,99,111,110,1,119,0,40,0,207,228,238,162,8,25,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,207,228,238,162,8,25,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,207,228,238,162,8,25,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,207,228,238,162,8,15,1,161,207,228,238,162,8,36,1,161,207,228,238,162,8,35,1,129,207,228,238,162,8,21,1,161,207,228,238,162,8,38,1,161,207,228,238,162,8,39,1,129,207,228,238,162,8,40,1,161,158,156,181,152,10,46,1,161,158,156,181,152,10,47,1,161,158,156,181,152,10,32,1,161,207,228,238,162,8,44,1,161,207,228,238,162,8,45,1,129,207,228,238,162,8,43,1,1,183,226,184,158,8,0,161,240,253,240,229,1,78,8,11,175,225,172,150,8,0,161,173,252,148,184,13,61,1,161,173,252,148,184,13,62,1,129,173,252,148,184,13,63,1,161,173,252,148,184,13,60,1,161,173,252,148,184,13,57,1,161,173,252,148,184,13,58,1,129,175,225,172,150,8,2,1,161,175,225,172,150,8,3,1,161,175,225,172,150,8,0,1,161,175,225,172,150,8,1,1,136,175,225,172,150,8,6,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,41,200,233,2,105,100,119,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,66,214,139,213,136,8,0,161,201,129,238,197,4,9,1,161,201,129,238,197,4,10,1,136,149,249,242,175,4,13,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,7,2,105,100,119,36,102,51,53,50,55,48,99,55,45,99,54,54,99,45,52,54,99,101,45,56,101,49,97,45,51,102,54,51,57,102,55,98,48,48,48,100,168,214,139,213,136,8,0,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,1,1,122,0,0,0,0,102,77,78,7,161,180,230,210,212,13,0,1,161,133,159,138,205,12,9,1,136,214,139,213,136,8,2,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,9,2,105,100,119,36,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,168,214,139,213,136,8,5,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,6,1,122,0,0,0,0,102,77,78,9,161,201,129,238,197,4,12,1,161,201,129,238,197,4,13,1,136,214,139,213,136,8,7,1,118,2,2,105,100,119,36,100,49,52,50,51,57,101,57,45,50,98,102,55,45,52,56,50,52,45,57,51,101,99,45,52,102,51,99,99,53,54,49,54,55,50,48,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,10,168,214,139,213,136,8,10,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,11,1,122,0,0,0,0,102,77,78,10,161,158,156,181,152,10,0,1,161,158,156,181,152,10,1,1,136,214,139,213,136,8,12,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,11,2,105,100,119,36,99,55,52,55,53,49,50,51,45,56,50,51,57,45,52,98,98,49,45,56,100,102,53,45,54,56,49,52,56,48,102,101,57,53,52,99,168,214,139,213,136,8,15,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,16,1,122,0,0,0,0,102,77,78,12,161,161,178,132,150,11,90,1,161,161,178,132,150,11,91,1,136,214,139,213,136,8,17,1,118,2,2,105,100,119,36,99,97,49,50,50,99,48,52,45,100,55,98,51,45,52,102,55,48,45,57,57,53,49,45,57,54,98,102,100,97,57,98,54,98,50,52,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,12,168,214,139,213,136,8,20,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,21,1,122,0,0,0,0,102,77,78,12,161,222,205,223,235,7,7,1,161,222,205,223,235,7,8,1,136,214,139,213,136,8,22,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,29,2,105,100,119,36,98,53,56,48,55,51,52,53,45,53,100,97,55,45,52,53,98,100,45,97,56,97,101,45,101,97,53,54,56,99,55,99,57,49,49,97,168,214,139,213,136,8,25,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,26,1,122,0,0,0,0,102,77,78,30,161,207,228,238,162,8,19,1,161,207,228,238,162,8,20,1,136,214,139,213,136,8,27,1,118,2,2,105,100,119,36,100,97,53,54,102,102,97,48,45,53,51,53,54,45,52,50,56,99,45,98,54,49,98,45,53,55,52,97,49,49,57,99,54,57,57,101,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,30,168,214,139,213,136,8,30,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,31,1,122,0,0,0,0,102,77,78,30,161,173,252,148,184,13,17,1,161,173,252,148,184,13,18,1,136,214,139,213,136,8,32,1,118,2,2,105,100,119,36,52,52,51,53,101,53,55,98,45,99,50,54,51,45,52,101,55,102,45,97,52,51,53,45,50,48,56,55,57,97,54,50,101,54,100,97,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,31,168,214,139,213,136,8,35,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,36,1,122,0,0,0,0,102,77,78,31,161,225,248,138,176,2,7,1,161,225,248,138,176,2,8,1,136,214,139,213,136,8,37,1,118,2,2,105,100,119,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,41,168,214,139,213,136,8,40,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,41,1,122,0,0,0,0,102,77,78,41,161,165,139,157,171,15,91,1,161,165,139,157,171,15,92,1,136,214,139,213,136,8,42,1,118,2,2,105,100,119,36,50,99,49,101,101,57,53,97,45,49,98,48,57,45,52,97,49,102,45,56,100,53,101,45,53,48,49,98,99,52,56,54,49,97,57,100,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,44,168,214,139,213,136,8,45,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,46,1,122,0,0,0,0,102,77,78,44,161,234,153,236,158,4,3,1,161,234,153,236,158,4,4,1,136,214,139,213,136,8,47,1,118,2,2,105,100,119,36,49,98,48,101,51,50,50,100,45,52,57,48,57,45,52,99,54,51,45,57,49,52,97,45,100,48,51,52,102,99,51,54,51,48,57,55,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,45,168,214,139,213,136,8,50,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,51,1,122,0,0,0,0,102,77,78,45,161,165,139,157,171,15,58,1,161,165,139,157,171,15,59,1,136,214,139,213,136,8,52,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,77,78,49,2,105,100,119,36,54,53,98,48,54,100,98,56,45,55,48,54,49,45,52,98,102,54,45,98,51,49,53,45,55,53,56,99,48,100,100,50,53,99,100,102,168,214,139,213,136,8,55,1,122,4,56,115,160,190,64,16,0,168,214,139,213,136,8,56,1,122,0,0,0,0,102,77,78,49,161,241,155,213,233,1,0,1,161,241,155,213,233,1,1,1,129,241,155,213,233,1,24,1,161,214,139,213,136,8,60,1,161,214,139,213,136,8,61,1,129,214,139,213,136,8,62,1,31,222,205,223,235,7,0,161,137,226,192,199,6,17,1,161,137,226,192,199,6,18,1,129,137,226,192,199,6,19,1,161,201,129,238,197,4,39,1,161,201,129,238,197,4,40,1,129,222,205,223,235,7,2,1,161,137,226,192,199,6,13,1,161,222,205,223,235,7,3,1,161,222,205,223,235,7,4,1,136,222,205,223,235,7,5,1,118,2,2,105,100,119,36,98,53,56,48,55,51,52,53,45,53,100,97,55,45,52,53,98,100,45,97,56,97,101,45,101,97,53,54,56,99,55,99,57,49,49,97,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,67,55,119,161,222,205,223,235,7,0,1,161,222,205,223,235,7,1,1,129,222,205,223,235,7,9,1,161,222,205,223,235,7,6,1,161,222,205,223,235,7,10,1,161,222,205,223,235,7,11,1,129,222,205,223,235,7,12,1,161,137,226,192,199,6,7,1,161,137,226,192,199,6,8,1,129,222,205,223,235,7,16,1,161,222,205,223,235,7,13,1,161,222,205,223,235,7,17,1,161,222,205,223,235,7,18,1,129,222,205,223,235,7,19,1,161,222,205,223,235,7,14,1,161,222,205,223,235,7,15,1,129,222,205,223,235,7,23,1,161,222,205,223,235,7,20,1,161,222,205,223,235,7,24,1,161,222,205,223,235,7,25,1,129,222,205,223,235,7,26,1,3,162,238,198,212,7,0,161,245,220,194,52,6,1,161,247,200,243,247,14,2,1,136,247,200,243,247,14,57,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,87,58,53,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,12,241,130,161,205,7,0,161,226,212,179,248,2,12,1,161,226,212,179,248,2,13,1,129,226,212,179,248,2,14,1,161,234,153,236,158,4,61,1,161,234,153,236,158,4,62,1,129,241,130,161,205,7,2,1,161,241,130,161,205,7,0,1,161,241,130,161,205,7,1,1,129,241,130,161,205,7,5,1,168,234,153,236,158,4,39,1,122,4,56,115,160,190,64,16,0,168,234,153,236,158,4,38,1,122,0,0,0,0,102,78,192,25,136,174,151,139,93,243,1,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,78,192,25,2,105,100,119,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,1,229,153,197,202,7,0,161,239,199,189,146,3,23,241,6,1,250,198,166,187,7,0,161,152,252,186,192,1,1,2,35,164,155,139,169,7,0,161,149,129,169,191,12,13,1,161,149,129,169,191,12,14,1,129,149,129,169,191,12,15,1,161,149,129,169,191,12,12,1,161,149,129,169,191,12,9,1,161,149,129,169,191,12,10,1,129,164,155,139,169,7,2,1,161,164,155,139,169,7,3,1,161,207,228,238,162,8,41,1,161,207,228,238,162,8,42,1,129,188,171,136,250,8,8,1,161,164,155,139,169,7,7,1,161,188,171,136,250,8,6,1,161,188,171,136,250,8,7,1,129,164,155,139,169,7,10,1,161,164,155,139,169,7,11,1,161,149,129,169,191,12,5,1,161,149,129,169,191,12,6,1,129,188,171,136,250,8,17,1,161,164,155,139,169,7,15,1,161,188,171,136,250,8,15,1,161,188,171,136,250,8,16,1,129,164,155,139,169,7,18,1,161,164,155,139,169,7,19,1,161,164,155,139,169,7,16,1,161,164,155,139,169,7,17,1,129,164,155,139,169,7,22,1,161,164,155,139,169,7,23,1,161,164,155,139,169,7,20,1,161,164,155,139,169,7,21,1,129,188,171,136,250,8,20,1,161,164,155,139,169,7,27,1,161,188,171,136,250,8,18,1,161,188,171,136,250,8,19,1,129,164,155,139,169,7,30,1,1,177,219,160,167,7,0,161,135,240,136,178,10,44,4,2,135,193,208,135,7,0,161,135,167,156,250,14,15,12,161,135,193,208,135,7,11,4,17,130,180,254,251,6,0,129,252,163,130,200,6,15,1,161,252,163,130,200,6,16,1,161,252,163,130,200,6,17,1,39,0,203,184,221,173,11,1,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,1,40,0,130,180,254,251,6,3,2,105,100,1,119,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,33,0,130,180,254,251,6,3,4,110,97,109,101,1,33,0,130,180,254,251,6,3,3,98,105,100,1,40,0,130,180,254,251,6,3,4,100,101,115,99,1,119,0,40,0,130,180,254,251,6,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,33,0,130,180,254,251,6,3,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,0,40,0,130,180,254,251,6,3,4,105,99,111,110,1,119,0,40,0,130,180,254,251,6,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,130,180,254,251,6,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,130,180,254,251,6,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,130,180,254,251,6,13,1,168,130,180,254,251,6,5,1,119,5,110,105,115,104,105,27,159,156,204,250,6,0,161,149,249,242,175,4,28,1,161,149,249,242,175,4,29,1,129,149,249,242,175,4,30,1,161,159,156,204,250,6,0,1,161,159,156,204,250,6,1,1,129,159,156,204,250,6,2,1,161,143,184,153,180,6,3,1,161,143,184,153,180,6,4,1,129,143,184,153,180,6,5,1,161,159,156,204,250,6,6,1,161,159,156,204,250,6,7,1,129,159,156,204,250,6,8,1,161,159,156,204,250,6,9,1,161,159,156,204,250,6,10,1,129,159,156,204,250,6,11,1,161,159,156,204,250,6,12,1,161,159,156,204,250,6,13,1,129,159,156,204,250,6,14,1,161,159,156,204,250,6,15,1,161,159,156,204,250,6,16,1,129,159,156,204,250,6,17,1,161,159,156,204,250,6,18,1,161,159,156,204,250,6,19,1,129,159,156,204,250,6,20,1,161,159,156,204,250,6,21,1,161,159,156,204,250,6,22,1,129,159,156,204,250,6,23,1,3,135,166,246,235,6,0,161,245,220,194,52,36,1,161,245,220,194,52,37,1,136,245,220,194,52,32,1,118,2,2,105,100,119,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,85,170,119,1,175,205,156,228,6,0,161,183,226,184,158,8,7,10,15,240,149,229,225,6,0,136,203,184,221,173,11,16,1,118,1,2,105,100,119,36,101,48,102,101,54,56,54,55,45,50,48,56,102,45,52,51,57,57,45,97,56,56,97,45,101,57,98,97,102,52,56,97,99,48,53,101,161,158,156,181,152,10,7,1,161,158,156,181,152,10,8,1,39,0,203,184,221,173,11,1,36,101,48,102,101,54,56,54,55,45,50,48,56,102,45,52,51,57,57,45,97,56,56,97,45,101,57,98,97,102,52,56,97,99,48,53,101,1,40,0,240,149,229,225,6,3,2,105,100,1,119,36,101,48,102,101,54,56,54,55,45,50,48,56,102,45,52,51,57,57,45,97,56,56,97,45,101,57,98,97,102,52,56,97,99,48,53,101,40,0,240,149,229,225,6,3,4,110,97,109,101,1,119,0,40,0,240,149,229,225,6,3,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,240,149,229,225,6,3,4,100,101,115,99,1,119,0,40,0,240,149,229,225,6,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,240,149,229,225,6,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,138,214,39,0,203,184,221,173,11,4,36,101,48,102,101,54,56,54,55,45,50,48,56,102,45,52,51,57,57,45,97,56,56,97,45,101,57,98,97,102,52,56,97,99,48,53,101,0,40,0,240,149,229,225,6,3,4,105,99,111,110,1,119,0,40,0,240,149,229,225,6,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,240,149,229,225,6,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,101,241,138,214,40,0,240,149,229,225,6,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,3,255,140,248,220,6,0,161,180,230,210,212,13,4,1,161,180,230,210,212,13,5,1,129,180,230,210,212,13,6,1,1,157,207,243,216,6,0,161,145,190,137,224,10,1,2,30,252,163,130,200,6,0,136,143,131,148,152,6,0,1,118,1,2,105,100,119,36,102,57,101,48,48,54,53,49,45,49,53,48,101,45,52,50,56,56,45,56,48,55,57,45,50,50,100,48,54,97,50,55,54,97,55,49,161,143,131,148,152,6,1,1,161,143,131,148,152,6,2,1,39,0,203,184,221,173,11,1,36,102,57,101,48,48,54,53,49,45,49,53,48,101,45,52,50,56,56,45,56,48,55,57,45,50,50,100,48,54,97,50,55,54,97,55,49,1,40,0,252,163,130,200,6,3,2,105,100,1,119,36,102,57,101,48,48,54,53,49,45,49,53,48,101,45,52,50,56,56,45,56,48,55,57,45,50,50,100,48,54,97,50,55,54,97,55,49,40,0,252,163,130,200,6,3,4,110,97,109,101,1,119,0,40,0,252,163,130,200,6,3,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,252,163,130,200,6,3,4,100,101,115,99,1,119,0,40,0,252,163,130,200,6,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,252,163,130,200,6,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,149,3,39,0,203,184,221,173,11,4,36,102,57,101,48,48,54,53,49,45,49,53,48,101,45,52,50,56,56,45,56,48,55,57,45,50,50,100,48,54,97,50,55,54,97,55,49,0,40,0,252,163,130,200,6,3,4,105,99,111,110,1,119,0,40,0,252,163,130,200,6,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,252,163,130,200,6,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,101,241,149,3,40,0,252,163,130,200,6,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,136,252,163,130,200,6,0,1,118,1,2,105,100,119,36,56,54,54,57,52,102,97,100,45,54,55,52,97,45,52,54,55,52,45,56,52,100,48,45,51,50,99,52,56,54,97,55,55,48,98,52,161,252,163,130,200,6,1,1,161,252,163,130,200,6,2,1,39,0,203,184,221,173,11,1,36,56,54,54,57,52,102,97,100,45,54,55,52,97,45,52,54,55,52,45,56,52,100,48,45,51,50,99,52,56,54,97,55,55,48,98,52,1,40,0,252,163,130,200,6,18,2,105,100,1,119,36,56,54,54,57,52,102,97,100,45,54,55,52,97,45,52,54,55,52,45,56,52,100,48,45,51,50,99,52,56,54,97,55,55,48,98,52,40,0,252,163,130,200,6,18,4,110,97,109,101,1,119,0,40,0,252,163,130,200,6,18,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,252,163,130,200,6,18,4,100,101,115,99,1,119,0,40,0,252,163,130,200,6,18,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,252,163,130,200,6,18,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,149,31,39,0,203,184,221,173,11,4,36,56,54,54,57,52,102,97,100,45,54,55,52,97,45,52,54,55,52,45,56,52,100,48,45,51,50,99,52,56,54,97,55,55,48,98,52,0,40,0,252,163,130,200,6,18,4,105,99,111,110,1,119,0,40,0,252,163,130,200,6,18,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,252,163,130,200,6,18,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,101,241,149,31,40,0,252,163,130,200,6,18,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,20,137,226,192,199,6,0,161,170,140,240,234,9,28,1,161,170,140,240,234,9,29,1,129,170,140,240,234,9,30,1,161,213,161,242,209,13,28,1,161,213,161,242,209,13,29,1,129,137,226,192,199,6,2,1,161,170,140,240,234,9,27,1,161,137,226,192,199,6,3,1,161,137,226,192,199,6,4,1,129,137,226,192,199,6,5,1,161,137,226,192,199,6,0,1,161,137,226,192,199,6,1,1,129,137,226,192,199,6,9,1,161,137,226,192,199,6,6,1,161,137,226,192,199,6,10,1,161,137,226,192,199,6,11,1,129,137,226,192,199,6,12,1,161,137,226,192,199,6,14,1,161,137,226,192,199,6,15,1,129,137,226,192,199,6,16,1,3,246,185,174,192,6,0,161,135,193,208,135,7,11,1,161,135,193,208,135,7,15,87,161,246,185,174,192,6,87,2,2,196,154,250,183,6,0,161,149,161,132,184,14,218,2,1,161,149,161,132,184,14,220,2,61,6,143,184,153,180,6,0,161,164,188,201,172,1,0,1,161,164,188,201,172,1,1,1,129,164,188,201,172,1,2,1,161,143,184,153,180,6,0,1,161,143,184,153,180,6,1,1,129,143,184,153,180,6,2,1,1,198,189,216,175,6,0,161,234,187,164,181,1,23,23,1,153,130,203,161,6,0,161,248,210,237,129,13,1,97,15,143,131,148,152,6,0,136,243,239,182,181,13,15,1,118,1,2,105,100,119,36,50,57,55,48,52,49,52,101,45,99,99,50,48,45,52,51,50,102,45,97,100,49,54,45,52,50,101,99,55,49,55,51,54,100,53,57,161,243,239,182,181,13,16,1,161,243,239,182,181,13,17,1,39,0,203,184,221,173,11,1,36,50,57,55,48,52,49,52,101,45,99,99,50,48,45,52,51,50,102,45,97,100,49,54,45,52,50,101,99,55,49,55,51,54,100,53,57,1,40,0,143,131,148,152,6,3,2,105,100,1,119,36,50,57,55,48,52,49,52,101,45,99,99,50,48,45,52,51,50,102,45,97,100,49,54,45,52,50,101,99,55,49,55,51,54,100,53,57,40,0,143,131,148,152,6,3,4,110,97,109,101,1,119,0,40,0,143,131,148,152,6,3,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,143,131,148,152,6,3,4,100,101,115,99,1,119,0,40,0,143,131,148,152,6,3,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,143,131,148,152,6,3,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,143,252,39,0,203,184,221,173,11,4,36,50,57,55,48,52,49,52,101,45,99,99,50,48,45,52,51,50,102,45,97,100,49,54,45,52,50,101,99,55,49,55,51,54,100,53,57,0,40,0,143,131,148,152,6,3,4,105,99,111,110,1,119,0,40,0,143,131,148,152,6,3,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,143,131,148,152,6,3,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,101,241,143,252,40,0,143,131,148,152,6,3,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,1,188,237,223,145,6,0,161,221,147,167,147,15,176,2,26,165,1,140,152,206,145,6,0,161,154,244,246,165,8,180,1,1,161,154,244,246,165,8,181,1,1,129,154,244,246,165,8,182,1,1,161,140,152,206,145,6,0,1,161,140,152,206,145,6,1,1,129,140,152,206,145,6,2,1,161,140,152,206,145,6,3,1,161,140,152,206,145,6,4,1,129,140,152,206,145,6,5,1,161,154,244,246,165,8,159,1,1,161,154,244,246,165,8,160,1,1,129,140,152,206,145,6,8,1,161,154,244,246,165,8,179,1,1,161,140,152,206,145,6,9,1,161,140,152,206,145,6,10,1,129,140,152,206,145,6,11,1,161,140,152,206,145,6,12,1,161,140,152,206,145,6,6,1,161,140,152,206,145,6,7,1,129,140,152,206,145,6,15,1,161,140,152,206,145,6,17,1,161,140,152,206,145,6,18,1,129,140,152,206,145,6,19,1,161,140,152,206,145,6,20,1,161,140,152,206,145,6,21,1,129,140,152,206,145,6,22,1,161,154,244,246,165,8,166,1,1,161,154,244,246,165,8,167,1,1,129,140,152,206,145,6,25,1,161,140,152,206,145,6,16,1,161,140,152,206,145,6,26,1,161,140,152,206,145,6,27,1,129,140,152,206,145,6,28,1,161,154,244,246,165,8,173,1,1,161,154,244,246,165,8,174,1,1,129,140,152,206,145,6,32,1,161,140,152,206,145,6,29,1,161,140,152,206,145,6,33,1,161,140,152,206,145,6,34,1,129,140,152,206,145,6,35,1,161,140,152,206,145,6,13,1,161,140,152,206,145,6,14,1,129,140,152,206,145,6,39,1,161,140,152,206,145,6,36,1,161,140,152,206,145,6,40,1,161,140,152,206,145,6,41,1,136,140,152,206,145,6,42,1,118,2,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,80,85,80,161,140,152,206,145,6,43,1,161,140,152,206,145,6,23,1,161,140,152,206,145,6,24,1,129,140,152,206,145,6,46,1,161,140,152,206,145,6,48,1,161,140,152,206,145,6,49,1,129,140,152,206,145,6,50,1,161,140,152,206,145,6,44,1,161,140,152,206,145,6,45,1,136,140,152,206,145,6,53,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,230,246,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,140,152,206,145,6,47,1,161,140,152,206,145,6,54,1,161,140,152,206,145,6,55,1,136,140,152,206,145,6,56,1,118,2,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,230,246,161,140,152,206,145,6,51,1,161,140,152,206,145,6,52,1,129,140,152,206,145,6,60,1,161,140,152,206,145,6,57,1,161,140,152,206,145,6,61,1,161,140,152,206,145,6,62,1,129,140,152,206,145,6,63,1,161,140,152,206,145,6,65,1,161,140,152,206,145,6,66,1,161,149,249,242,175,4,2,1,161,140,152,206,145,6,68,1,161,140,152,206,145,6,69,1,161,140,152,206,145,6,70,1,161,140,152,206,145,6,71,1,161,140,152,206,145,6,72,1,161,140,152,206,145,6,73,1,161,140,152,206,145,6,74,1,161,140,152,206,145,6,75,1,161,140,152,206,145,6,76,1,161,140,152,206,145,6,77,1,161,140,152,206,145,6,78,1,161,140,152,206,145,6,79,1,161,140,152,206,145,6,58,1,161,140,152,206,145,6,59,1,136,140,152,206,145,6,67,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,241,108,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,140,152,206,145,6,64,1,161,140,152,206,145,6,83,1,161,140,152,206,145,6,84,1,136,140,152,206,145,6,85,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,241,109,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,140,152,206,145,6,86,1,161,140,152,206,145,6,80,1,161,140,152,206,145,6,81,1,136,140,152,206,145,6,89,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,241,110,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,161,140,152,206,145,6,91,1,161,140,152,206,145,6,92,1,136,140,152,206,145,6,93,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,241,111,161,140,152,206,145,6,94,1,161,140,152,206,145,6,95,1,161,140,152,206,145,6,82,1,136,241,155,213,233,1,6,1,118,1,2,105,100,119,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,161,241,155,213,233,1,7,1,161,140,152,206,145,6,98,1,39,0,203,184,221,173,11,1,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,1,40,0,140,152,206,145,6,103,2,105,100,1,119,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,33,0,140,152,206,145,6,103,4,110,97,109,101,1,40,0,140,152,206,145,6,103,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,140,152,206,145,6,103,4,100,101,115,99,1,119,0,40,0,140,152,206,145,6,103,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,140,152,206,145,6,103,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,83,241,173,39,0,203,184,221,173,11,4,36,48,101,55,99,100,101,102,50,45,49,48,99,50,45,52,52,101,99,45,56,98,54,49,45,49,97,100,101,48,98,102,53,100,51,102,102,0,33,0,140,152,206,145,6,103,4,105,99,111,110,1,40,0,140,152,206,145,6,103,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,140,152,206,145,6,103,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,140,152,206,145,6,103,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,140,152,206,145,6,90,1,161,140,152,206,145,6,114,1,161,140,152,206,145,6,113,1,129,140,152,206,145,6,96,1,161,140,152,206,145,6,116,1,161,140,152,206,145,6,117,1,129,140,152,206,145,6,118,1,161,140,152,206,145,6,119,1,161,140,152,206,145,6,120,1,33,0,140,152,206,145,6,103,5,101,120,116,114,97,1,161,140,152,206,145,6,122,1,161,140,152,206,145,6,123,1,129,140,152,206,145,6,121,1,161,140,152,206,145,6,125,1,161,140,152,206,145,6,126,1,161,140,152,206,145,6,105,1,161,140,152,206,145,6,128,1,1,161,140,152,206,145,6,129,1,1,168,140,152,206,145,6,130,1,1,119,2,104,105,161,140,152,206,145,6,131,1,1,161,140,152,206,145,6,132,1,1,161,140,152,206,145,6,124,1,161,140,152,206,145,6,134,1,1,161,140,152,206,145,6,135,1,1,161,140,152,206,145,6,136,1,1,161,140,152,206,145,6,137,1,1,161,140,152,206,145,6,138,1,1,161,140,152,206,145,6,139,1,1,161,140,152,206,145,6,140,1,1,161,140,152,206,145,6,141,1,1,161,140,152,206,145,6,142,1,1,161,140,152,206,145,6,143,1,1,161,140,152,206,145,6,144,1,1,161,140,152,206,145,6,145,1,1,161,140,152,206,145,6,146,1,1,161,140,152,206,145,6,147,1,1,161,140,152,206,145,6,148,1,1,161,140,152,206,145,6,149,1,1,161,140,152,206,145,6,150,1,1,168,140,152,206,145,6,111,1,119,23,123,34,116,121,34,58,48,44,34,118,97,108,117,101,34,58,34,240,159,154,184,34,125,161,140,152,206,145,6,97,1,161,140,152,206,145,6,102,1,136,140,152,206,145,6,127,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,244,231,161,140,152,206,145,6,115,1,161,140,152,206,145,6,155,1,1,161,140,152,206,145,6,156,1,1,136,140,152,206,145,6,157,1,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,244,231,161,140,152,206,145,6,159,1,1,161,140,152,206,145,6,160,1,1,168,140,152,206,145,6,99,1,119,225,1,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,117,110,115,112,108,97,115,104,34,44,34,118,97,108,117,101,34,58,34,104,116,116,112,115,58,47,47,105,109,97,103,101,115,46,117,110,115,112,108,97,115,104,46,99,111,109,47,112,104,111,116,111,45,49,55,49,52,53,48,56,56,54,50,55,56,56,45,52,52,101,52,53,99,52,51,49,53,100,48,63,99,114,111,112,61,101,110,116,114,111,112,121,38,99,115,61,116,105,110,121,115,114,103,98,38,102,105,116,61,109,97,120,38,102,109,61,106,112,103,38,105,120,105,100,61,77,51,119,49,77,84,69,49,77,122,100,56,77,72,119,120,102,72,74,104,98,109,82,118,98,88,120,56,102,72,120,56,102,72,120,56,102,68,69,51,77,84,89,51,78,122,103,121,77,84,108,56,38,105,120,108,105,98,61,114,98,45,52,46,48,46,51,38,113,61,56,48,38,119,61,49,48,56,48,34,125,125,1,219,227,140,137,6,0,161,140,228,230,243,1,1,34,1,235,178,165,206,5,0,161,255,255,147,249,10,2,72,3,182,172,247,194,5,0,161,245,220,194,52,30,1,161,245,220,194,52,31,1,129,245,220,194,52,32,1,1,145,144,146,185,5,0,161,175,205,156,228,6,9,12,3,160,192,253,131,5,0,161,195,242,227,194,8,0,1,161,195,242,227,194,8,1,1,129,195,242,227,194,8,2,1,1,200,142,208,241,4,0,161,196,154,250,183,6,61,157,1,1,154,235,215,240,4,0,161,173,187,245,170,14,45,13,1,211,166,203,229,4,0,161,234,182,182,157,9,7,195,1,1,141,171,170,217,4,0,161,191,157,147,233,9,31,2,84,201,129,238,197,4,0,161,161,178,132,150,11,34,1,161,161,178,132,150,11,35,1,129,173,252,148,184,13,51,1,161,133,159,138,205,12,49,1,161,133,159,138,205,12,50,1,129,133,159,138,205,12,77,1,168,201,129,238,197,4,3,1,122,4,56,115,160,190,64,16,0,168,201,129,238,197,4,4,1,122,0,0,0,0,102,48,111,8,136,201,129,238,197,4,5,1,118,2,2,105,100,119,36,98,54,51,52,55,97,99,98,45,51,49,55,52,45,52,102,48,101,45,57,56,101,57,45,100,99,99,101,48,55,101,53,100,98,102,55,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,48,111,8,161,133,159,138,205,12,45,1,161,133,159,138,205,12,46,1,129,201,129,238,197,4,8,1,161,158,156,181,152,10,21,1,161,244,226,228,149,2,6,1,129,201,129,238,197,4,11,1,161,133,159,138,205,12,81,1,161,133,159,138,205,12,82,1,129,201,129,238,197,4,14,1,161,201,129,238,197,4,15,1,161,201,129,238,197,4,16,1,129,201,129,238,197,4,17,1,161,201,129,238,197,4,18,1,161,201,129,238,197,4,19,1,129,201,129,238,197,4,20,1,161,201,129,238,197,4,21,1,161,201,129,238,197,4,22,1,129,201,129,238,197,4,23,1,161,201,129,238,197,4,24,1,161,201,129,238,197,4,25,1,129,201,129,238,197,4,26,1,161,201,129,238,197,4,27,1,161,201,129,238,197,4,28,1,129,201,129,238,197,4,29,1,161,133,159,138,205,12,90,1,161,133,159,138,205,12,91,1,129,201,129,238,197,4,32,1,161,201,129,238,197,4,33,1,161,201,129,238,197,4,34,1,129,201,129,238,197,4,35,1,161,173,252,148,184,13,53,1,161,173,252,148,184,13,54,1,129,201,129,238,197,4,38,1,8,0,133,159,138,205,12,66,1,118,1,2,105,100,119,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,161,133,159,138,205,12,65,1,161,201,129,238,197,4,37,1,39,0,203,184,221,173,11,1,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,1,40,0,201,129,238,197,4,45,2,105,100,1,119,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,40,0,201,129,238,197,4,45,4,110,97,109,101,1,119,5,66,111,97,114,100,40,0,201,129,238,197,4,45,3,98,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,201,129,238,197,4,45,4,100,101,115,99,1,119,0,40,0,201,129,238,197,4,45,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,33,0,201,129,238,197,4,45,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,0,40,0,201,129,238,197,4,45,4,105,99,111,110,1,119,0,40,0,201,129,238,197,4,45,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,201,129,238,197,4,45,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,201,129,238,197,4,45,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,136,201,129,238,197,4,42,1,118,1,2,105,100,119,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,161,201,129,238,197,4,43,1,161,201,129,238,197,4,44,1,39,0,203,184,221,173,11,1,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,1,40,0,201,129,238,197,4,60,2,105,100,1,119,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,40,0,201,129,238,197,4,60,4,110,97,109,101,1,119,8,67,97,108,101,110,100,97,114,40,0,201,129,238,197,4,60,3,98,105,100,1,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,40,0,201,129,238,197,4,60,4,100,101,115,99,1,119,0,40,0,201,129,238,197,4,60,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,3,33,0,201,129,238,197,4,60,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,50,49,52,51,101,57,53,100,45,53,100,99,98,45,52,101,48,102,45,98,98,50,99,45,53,48,57,52,52,101,54,101,48,49,57,102,0,40,0,201,129,238,197,4,60,4,105,99,111,110,1,119,0,40,0,201,129,238,197,4,60,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,201,129,238,197,4,60,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,201,129,238,197,4,60,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,201,129,238,197,4,36,1,161,201,129,238,197,4,59,1,161,133,159,138,205,12,92,1,161,201,129,238,197,4,72,1,161,201,129,238,197,4,73,1,161,201,129,238,197,4,74,1,161,201,129,238,197,4,75,1,161,201,129,238,197,4,76,1,161,201,129,238,197,4,77,1,161,201,129,238,197,4,78,1,161,201,129,238,197,4,79,1,168,201,129,238,197,4,80,1,119,4,71,114,105,100,1,182,143,233,195,4,0,161,205,149,231,236,11,67,111,1,178,203,205,182,4,0,161,227,209,197,253,2,13,1,31,149,249,242,175,4,0,161,213,161,242,209,13,28,1,161,213,161,242,209,13,29,1,33,0,203,184,221,173,11,23,5,101,120,116,114,97,1,161,149,249,242,175,4,0,1,161,149,249,242,175,4,1,1,129,201,191,159,147,14,2,1,161,133,159,138,205,12,122,1,161,133,159,138,205,12,121,1,136,213,161,242,209,13,26,1,118,2,2,105,100,119,36,102,48,99,53,57,57,50,49,45,48,52,101,101,45,52,57,55,49,45,57,57,53,99,45,55,57,98,55,102,100,56,99,48,48,101,50,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,60,201,181,168,149,249,242,175,4,6,1,122,4,56,115,160,190,64,16,0,168,149,249,242,175,4,7,1,122,0,0,0,0,102,60,201,181,161,133,159,138,205,12,107,1,161,133,159,138,205,12,106,1,136,149,249,242,175,4,8,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,60,201,183,2,105,100,119,36,101,57,55,56,55,55,102,53,45,99,51,54,53,45,52,48,50,53,45,57,101,54,97,45,101,53,57,48,99,52,98,49,57,100,98,98,168,149,249,242,175,4,11,1,122,4,56,115,160,190,64,16,0,168,149,249,242,175,4,12,1,122,0,0,0,0,102,60,201,183,161,201,191,159,147,14,0,1,161,201,191,159,147,14,1,1,129,149,249,242,175,4,5,1,161,149,249,242,175,4,16,1,161,149,249,242,175,4,17,1,129,149,249,242,175,4,18,1,161,149,249,242,175,4,19,1,161,149,249,242,175,4,20,1,129,149,249,242,175,4,21,1,161,149,249,242,175,4,22,1,161,149,249,242,175,4,23,1,129,149,249,242,175,4,24,1,161,149,249,242,175,4,25,1,161,149,249,242,175,4,26,1,129,149,249,242,175,4,27,1,12,163,236,177,169,4,0,161,154,243,157,196,14,9,1,161,154,243,157,196,14,10,1,129,154,243,157,196,14,11,1,161,163,236,177,169,4,0,1,161,163,236,177,169,4,1,1,129,163,236,177,169,4,2,1,161,163,236,177,169,4,3,1,161,163,236,177,169,4,4,1,129,163,236,177,169,4,5,1,161,163,236,177,169,4,6,1,161,163,236,177,169,4,7,1,129,163,236,177,169,4,8,1,73,234,153,236,158,4,0,161,165,139,157,171,15,100,1,161,165,139,157,171,15,101,1,129,165,139,157,171,15,102,1,161,165,139,157,171,15,88,1,161,165,139,157,171,15,89,1,129,234,153,236,158,4,2,1,136,165,139,157,171,15,18,1,118,1,2,105,100,119,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,161,165,139,157,171,15,19,1,161,165,139,157,171,15,20,1,39,0,203,184,221,173,11,1,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,1,40,0,234,153,236,158,4,9,2,105,100,1,119,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,33,0,234,153,236,158,4,9,4,110,97,109,101,1,40,0,234,153,236,158,4,9,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,234,153,236,158,4,9,4,100,101,115,99,1,119,0,40,0,234,153,236,158,4,9,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,2,33,0,234,153,236,158,4,9,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,0,40,0,234,153,236,158,4,9,4,105,99,111,110,1,119,0,40,0,234,153,236,158,4,9,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,234,153,236,158,4,9,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,234,153,236,158,4,9,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,165,139,157,171,15,33,1,161,234,153,236,158,4,20,1,161,234,153,236,158,4,19,1,129,234,153,236,158,4,5,1,8,0,234,153,236,158,4,16,1,118,1,2,105,100,119,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,168,234,153,236,158,4,15,1,122,0,0,0,0,102,76,39,166,161,234,153,236,158,4,23,1,39,0,203,184,221,173,11,1,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,1,40,0,234,153,236,158,4,28,2,105,100,1,119,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,40,0,234,153,236,158,4,28,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,234,153,236,158,4,28,3,98,105,100,1,119,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,40,0,234,153,236,158,4,28,4,100,101,115,99,1,119,0,40,0,234,153,236,158,4,28,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,234,153,236,158,4,28,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,76,39,166,39,0,203,184,221,173,11,4,36,101,52,99,56,57,52,50,49,45,49,50,98,50,45,52,100,48,50,45,56,54,51,100,45,50,48,57,52,57,101,101,99,57,50,55,49,0,40,0,234,153,236,158,4,28,4,105,99,111,110,1,119,0,40,0,234,153,236,158,4,28,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,234,153,236,158,4,28,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,234,153,236,158,4,28,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,234,153,236,158,4,22,1,161,234,153,236,158,4,27,1,129,234,153,236,158,4,24,1,161,234,153,236,158,4,40,1,161,234,153,236,158,4,41,1,168,234,153,236,158,4,11,1,119,14,99,104,101,99,107,98,111,120,32,98,111,97,114,100,161,234,153,236,158,4,43,1,161,234,153,236,158,4,44,1,129,234,153,236,158,4,42,1,161,234,153,236,158,4,46,1,161,234,153,236,158,4,47,1,129,234,153,236,158,4,48,1,161,234,153,236,158,4,49,1,161,234,153,236,158,4,50,1,129,234,153,236,158,4,51,1,161,165,139,157,171,15,94,1,161,165,139,157,171,15,95,1,129,234,153,236,158,4,54,1,161,234,153,236,158,4,55,1,161,234,153,236,158,4,56,1,129,234,153,236,158,4,57,1,161,234,153,236,158,4,0,1,161,234,153,236,158,4,1,1,129,234,153,236,158,4,60,1,161,234,153,236,158,4,58,1,161,234,153,236,158,4,59,1,129,234,153,236,158,4,63,1,161,234,153,236,158,4,64,1,161,234,153,236,158,4,65,1,129,234,153,236,158,4,66,1,161,234,153,236,158,4,67,1,161,234,153,236,158,4,68,1,129,234,153,236,158,4,69,1,3,141,205,220,149,4,0,161,214,168,149,214,3,12,1,161,214,168,149,214,3,13,1,129,214,168,149,214,3,14,1,17,193,249,142,142,4,0,161,141,216,158,150,1,0,1,161,141,216,158,150,1,1,1,129,141,216,158,150,1,2,1,161,225,248,138,176,2,45,1,161,222,205,223,235,7,21,1,161,225,248,138,176,2,19,1,129,193,249,142,142,4,2,1,161,193,249,142,142,4,4,1,161,193,249,142,142,4,5,1,129,193,249,142,142,4,6,1,161,193,249,142,142,4,0,1,161,193,249,142,142,4,1,1,129,193,249,142,142,4,9,1,161,193,249,142,142,4,3,1,161,193,249,142,142,4,10,1,161,193,249,142,142,4,11,1,129,193,249,142,142,4,12,1,20,206,220,129,131,4,0,161,235,225,184,133,10,0,1,161,235,225,184,133,10,1,1,129,235,225,184,133,10,2,1,72,233,165,139,246,14,7,1,118,1,2,105,100,119,36,99,55,52,55,53,49,50,51,45,56,50,51,57,45,52,98,98,49,45,56,100,102,53,45,54,56,49,52,56,48,102,101,57,53,52,99,161,233,165,139,246,14,8,1,161,233,165,139,246,14,9,1,39,0,203,184,221,173,11,1,36,99,55,52,55,53,49,50,51,45,56,50,51,57,45,52,98,98,49,45,56,100,102,53,45,54,56,49,52,56,48,102,101,57,53,52,99,1,40,0,206,220,129,131,4,6,2,105,100,1,119,36,99,55,52,55,53,49,50,51,45,56,50,51,57,45,52,98,98,49,45,56,100,102,53,45,54,56,49,52,56,48,102,101,57,53,52,99,40,0,206,220,129,131,4,6,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,206,220,129,131,4,6,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,206,220,129,131,4,6,4,100,101,115,99,1,119,0,40,0,206,220,129,131,4,6,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,206,220,129,131,4,6,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,241,122,107,39,0,203,184,221,173,11,4,36,99,55,52,55,53,49,50,51,45,56,50,51,57,45,52,98,98,49,45,56,100,102,53,45,54,56,49,52,56,48,102,101,57,53,52,99,0,40,0,206,220,129,131,4,6,4,105,99,111,110,1,119,0,40,0,206,220,129,131,4,6,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,206,220,129,131,4,6,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,206,220,129,131,4,6,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,206,220,129,131,4,16,1,129,206,220,129,131,4,2,1,1,128,252,161,128,4,0,161,232,207,157,148,2,1,33,3,169,197,188,221,3,0,161,154,193,208,134,10,3,1,161,154,193,208,134,10,4,1,129,154,193,208,134,10,5,1,15,214,168,149,214,3,0,161,169,197,188,221,3,0,1,161,169,197,188,221,3,1,1,129,169,197,188,221,3,2,1,161,233,247,183,159,1,0,1,161,158,156,181,152,10,3,1,161,158,156,181,152,10,4,1,129,154,193,208,134,10,8,1,161,214,168,149,214,3,3,1,161,154,193,208,134,10,6,1,161,154,193,208,134,10,7,1,129,214,168,149,214,3,6,1,161,214,168,149,214,3,7,1,161,171,204,155,217,8,0,1,161,171,204,155,217,8,1,1,129,214,168,149,214,3,10,1,1,158,184,218,165,3,0,161,139,152,215,249,10,33,38,1,239,199,189,146,3,0,161,154,235,215,240,4,12,24,1,227,209,197,253,2,0,161,181,175,219,209,12,9,14,15,226,212,179,248,2,0,161,214,139,213,136,8,63,1,161,214,139,213,136,8,64,1,129,214,139,213,136,8,65,1,161,226,212,179,248,2,0,1,161,226,212,179,248,2,1,1,129,226,212,179,248,2,2,1,161,226,212,179,248,2,3,1,161,226,212,179,248,2,4,1,129,226,212,179,248,2,5,1,161,193,249,142,142,4,7,1,161,241,155,213,233,1,8,1,129,226,212,179,248,2,8,1,161,226,212,179,248,2,6,1,161,226,212,179,248,2,7,1,129,226,212,179,248,2,11,1,3,157,240,144,231,2,0,161,213,161,242,209,13,32,1,161,213,161,242,209,13,33,1,129,213,161,242,209,13,34,1,1,128,211,179,216,2,0,161,236,229,225,232,8,115,10,1,138,202,240,189,2,0,161,229,153,197,202,7,240,6,134,1,1,200,203,236,184,2,0,161,138,202,240,189,2,133,1,35,49,225,248,138,176,2,0,161,171,142,166,254,1,3,1,161,171,142,166,254,1,4,1,129,171,142,166,254,1,5,1,161,222,205,223,235,7,27,1,161,173,252,148,184,13,45,1,161,173,252,148,184,13,46,1,129,225,248,138,176,2,2,1,161,225,248,138,176,2,4,1,161,225,248,138,176,2,5,1,136,225,248,138,176,2,6,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,68,43,241,2,105,100,119,36,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,161,170,140,240,234,9,7,1,161,170,140,240,234,9,8,1,136,225,248,138,176,2,9,1,118,2,2,105,100,119,36,52,56,99,53,50,99,102,55,45,98,102,57,56,45,52,51,102,97,45,57,54,97,100,45,98,51,49,97,97,100,101,57,98,48,55,49,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,68,43,243,161,225,248,138,176,2,3,1,168,225,248,138,176,2,10,1,122,4,56,115,160,190,64,16,0,168,225,248,138,176,2,11,1,122,0,0,0,0,102,68,43,244,136,225,248,138,176,2,12,1,118,2,2,105,100,119,36,52,56,99,53,50,99,102,55,45,98,102,57,56,45,52,51,102,97,45,57,54,97,100,45,98,51,49,97,97,100,101,57,98,48,55,49,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,68,43,244,136,133,159,138,205,12,56,1,118,1,2,105,100,119,36,50,99,49,101,101,57,53,97,45,49,98,48,57,45,52,97,49,102,45,56,100,53,101,45,53,48,49,98,99,52,56,54,49,97,57,100,161,133,159,138,205,12,57,1,161,222,205,223,235,7,22,1,39,0,203,184,221,173,11,1,36,50,99,49,101,101,57,53,97,45,49,98,48,57,45,52,97,49,102,45,56,100,53,101,45,53,48,49,98,99,52,56,54,49,97,57,100,1,40,0,225,248,138,176,2,20,2,105,100,1,119,36,50,99,49,101,101,57,53,97,45,49,98,48,57,45,52,97,49,102,45,56,100,53,101,45,53,48,49,98,99,52,56,54,49,97,57,100,40,0,225,248,138,176,2,20,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,225,248,138,176,2,20,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,225,248,138,176,2,20,4,100,101,115,99,1,119,0,40,0,225,248,138,176,2,20,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,33,0,225,248,138,176,2,20,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,50,99,49,101,101,57,53,97,45,49,98,48,57,45,52,97,49,102,45,56,100,53,101,45,53,48,49,98,99,52,56,54,49,97,57,100,0,40,0,225,248,138,176,2,20,4,105,99,111,110,1,119,0,40,0,225,248,138,176,2,20,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,225,248,138,176,2,20,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,225,248,138,176,2,20,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,225,248,138,176,2,13,1,161,225,248,138,176,2,31,1,161,225,248,138,176,2,30,1,129,225,248,138,176,2,16,1,161,225,248,138,176,2,33,1,161,225,248,138,176,2,34,1,129,225,248,138,176,2,35,1,161,225,248,138,176,2,36,1,161,225,248,138,176,2,37,1,129,225,248,138,176,2,38,1,161,225,248,138,176,2,0,1,161,225,248,138,176,2,1,1,129,225,248,138,176,2,41,1,161,225,248,138,176,2,32,1,161,225,248,138,176,2,42,1,161,225,248,138,176,2,43,1,129,225,248,138,176,2,44,1,29,244,226,228,149,2,0,39,0,203,184,221,173,11,2,7,112,114,105,118,97,116,101,1,161,158,156,181,152,10,24,1,161,207,228,238,162,8,24,1,129,207,228,238,162,8,49,1,8,0,158,156,181,152,10,16,1,118,1,2,105,100,119,36,48,53,51,51,50,98,97,52,45,97,54,57,48,45,52,50,57,51,45,57,56,54,54,45,56,52,100,97,99,55,102,101,50,97,101,97,168,158,156,181,152,10,15,1,122,0,0,0,0,101,251,252,70,161,158,156,181,152,10,22,1,39,0,203,184,221,173,11,1,36,48,53,51,51,50,98,97,52,45,97,54,57,48,45,52,50,57,51,45,57,56,54,54,45,56,52,100,97,99,55,102,101,50,97,101,97,1,40,0,244,226,228,149,2,7,2,105,100,1,119,36,48,53,51,51,50,98,97,52,45,97,54,57,48,45,52,50,57,51,45,57,56,54,54,45,56,52,100,97,99,55,102,101,50,97,101,97,40,0,244,226,228,149,2,7,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,244,226,228,149,2,7,3,98,105,100,1,119,36,100,49,52,50,51,57,101,57,45,50,98,102,55,45,52,56,50,52,45,57,51,101,99,45,52,102,51,99,99,53,54,49,54,55,50,48,40,0,244,226,228,149,2,7,4,100,101,115,99,1,119,0,40,0,244,226,228,149,2,7,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,244,226,228,149,2,7,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,101,251,252,70,39,0,203,184,221,173,11,4,36,48,53,51,51,50,98,97,52,45,97,54,57,48,45,52,50,57,51,45,57,56,54,54,45,56,52,100,97,99,55,102,101,50,97,101,97,0,40,0,244,226,228,149,2,7,4,105,99,111,110,1,119,0,40,0,244,226,228,149,2,7,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,244,226,228,149,2,7,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,244,226,228,149,2,7,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,2,161,244,226,228,149,2,17,1,39,0,244,226,228,149,2,0,18,51,48,52,49,50,48,49,48,57,48,55,49,51,51,57,53,50,48,0,8,0,244,226,228,149,2,21,1,118,2,2,105,100,119,36,48,53,51,51,50,98,97,52,45,97,54,57,48,45,52,50,57,51,45,57,56,54,54,45,56,52,100,97,99,55,102,101,50,97,101,97,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,101,251,252,70,161,207,228,238,162,8,37,1,161,244,226,228,149,2,19,1,161,244,226,228,149,2,20,1,129,244,226,228,149,2,3,1,161,244,226,228,149,2,24,1,161,244,226,228,149,2,25,1,129,244,226,228,149,2,26,1,1,232,207,157,148,2,0,161,141,171,170,217,4,1,2,6,171,142,166,254,1,0,161,143,184,153,180,6,3,1,161,143,184,153,180,6,4,1,129,143,184,153,180,6,5,1,161,171,142,166,254,1,0,1,161,171,142,166,254,1,1,1,129,171,142,166,254,1,2,1,1,140,228,230,243,1,0,161,250,198,166,187,7,1,2,3,147,206,229,235,1,0,161,229,154,128,197,12,3,1,161,229,154,128,197,12,4,1,129,162,159,252,196,11,2,1,52,241,155,213,233,1,0,161,234,153,236,158,4,70,1,161,234,153,236,158,4,71,1,129,234,153,236,158,4,72,1,161,234,153,236,158,4,52,1,161,234,153,236,158,4,53,1,129,241,155,213,233,1,2,1,136,234,153,236,158,4,6,1,118,1,2,105,100,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,161,234,153,236,158,4,7,1,161,234,153,236,158,4,8,1,39,0,203,184,221,173,11,1,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,1,40,0,241,155,213,233,1,9,2,105,100,1,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,33,0,241,155,213,233,1,9,4,110,97,109,101,1,40,0,241,155,213,233,1,9,3,98,105,100,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,40,0,241,155,213,233,1,9,4,100,101,115,99,1,119,0,40,0,241,155,213,233,1,9,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,3,33,0,241,155,213,233,1,9,10,99,114,101,97,116,101,100,95,97,116,1,39,0,203,184,221,173,11,4,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,0,40,0,241,155,213,233,1,9,4,105,99,111,110,1,119,0,40,0,241,155,213,233,1,9,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,241,155,213,233,1,9,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,241,155,213,233,1,9,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,234,153,236,158,4,21,1,161,241,155,213,233,1,20,1,161,241,155,213,233,1,19,1,129,241,155,213,233,1,5,1,161,241,155,213,233,1,22,1,161,241,155,213,233,1,23,1,161,241,155,213,233,1,11,1,161,241,155,213,233,1,25,1,161,241,155,213,233,1,26,1,161,241,155,213,233,1,27,1,161,241,155,213,233,1,28,1,161,241,155,213,233,1,29,1,161,241,155,213,233,1,30,1,161,241,155,213,233,1,31,1,161,241,155,213,233,1,32,1,161,241,155,213,233,1,33,1,161,241,155,213,233,1,34,1,161,241,155,213,233,1,35,1,161,241,155,213,233,1,36,1,161,241,155,213,233,1,37,1,161,241,155,213,233,1,38,1,161,241,155,213,233,1,39,1,161,241,155,213,233,1,40,1,161,241,155,213,233,1,41,1,161,241,155,213,233,1,42,1,161,241,155,213,233,1,43,1,161,241,155,213,233,1,44,1,161,241,155,213,233,1,45,1,161,241,155,213,233,1,46,1,161,241,155,213,233,1,47,1,168,241,155,213,233,1,48,1,119,8,67,97,108,101,110,100,97,114,1,240,253,240,229,1,0,161,178,203,205,182,4,0,79,20,176,154,159,227,1,0,33,0,203,184,221,173,11,2,7,112,114,105,118,97,116,101,1,136,130,180,254,251,6,0,1,118,1,2,105,100,119,36,54,53,98,48,54,100,98,56,45,55,48,54,49,45,52,98,102,54,45,98,51,49,53,45,55,53,56,99,48,100,100,50,53,99,100,102,161,130,180,254,251,6,1,1,161,130,180,254,251,6,2,1,39,0,203,184,221,173,11,1,36,54,53,98,48,54,100,98,56,45,55,48,54,49,45,52,98,102,54,45,98,51,49,53,45,55,53,56,99,48,100,100,50,53,99,100,102,1,40,0,176,154,159,227,1,4,2,105,100,1,119,36,54,53,98,48,54,100,98,56,45,55,48,54,49,45,52,98,102,54,45,98,51,49,53,45,55,53,56,99,48,100,100,50,53,99,100,102,40,0,176,154,159,227,1,4,4,110,97,109,101,1,119,0,40,0,176,154,159,227,1,4,3,98,105,100,1,119,36,57,101,101,98,101,97,48,51,45,51,101,100,53,45,52,50,57,56,45,56,54,98,50,45,97,55,102,55,55,56,53,54,100,52,56,98,40,0,176,154,159,227,1,4,4,100,101,115,99,1,119,0,40,0,176,154,159,227,1,4,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,176,154,159,227,1,4,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,12,194,112,39,0,203,184,221,173,11,4,36,54,53,98,48,54,100,98,56,45,55,48,54,49,45,52,98,102,54,45,98,51,49,53,45,55,53,56,99,48,100,100,50,53,99,100,102,0,40,0,176,154,159,227,1,4,4,105,99,111,110,1,119,0,40,0,176,154,159,227,1,4,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,176,154,159,227,1,4,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,176,154,159,227,1,4,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,161,207,228,238,162,8,37,1,161,176,154,159,227,1,15,1,161,176,154,159,227,1,14,1,129,207,228,238,162,8,49,1,2,175,147,217,214,1,0,161,246,185,174,192,6,87,1,161,246,185,174,192,6,89,32,6,202,160,246,212,1,0,161,178,162,190,217,10,0,1,161,178,162,190,217,10,1,1,161,178,162,190,217,10,2,1,161,202,160,246,212,1,0,1,161,202,160,246,212,1,1,1,161,202,160,246,212,1,2,1,39,137,164,190,210,1,0,168,166,201,221,141,13,69,1,122,4,56,115,160,190,64,16,0,168,166,201,221,141,13,70,1,122,0,0,0,0,102,86,193,57,136,166,201,221,141,13,71,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,86,193,57,2,105,100,119,36,50,97,54,101,53,101,50,49,45,97,57,51,56,45,52,53,97,53,45,97,52,52,53,45,100,48,98,55,49,52,57,53,98,48,55,55,161,174,151,139,93,254,1,1,161,174,151,139,93,255,1,1,136,162,238,198,212,7,2,1,118,2,2,105,100,119,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,87,240,30,161,247,200,243,247,14,15,1,168,137,164,190,210,1,3,1,122,4,56,115,160,190,64,16,0,168,137,164,190,210,1,4,1,122,0,0,0,0,102,87,240,30,136,137,164,190,210,1,5,1,118,2,2,105,100,119,36,101,52,49,48,55,52,55,98,45,53,102,50,102,45,52,53,97,48,45,98,50,102,55,45,56,57,48,97,100,51,48,48,49,51,53,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,87,240,30,39,0,203,184,221,173,11,1,36,48,51,50,55,98,54,57,52,45,50,100,101,51,45,53,101,48,48,45,98,51,54,56,45,57,56,99,97,49,56,50,51,48,102,97,57,1,40,0,137,164,190,210,1,10,2,105,100,1,119,36,48,51,50,55,98,54,57,52,45,50,100,101,51,45,53,101,48,48,45,98,51,54,56,45,57,56,99,97,49,56,50,51,48,102,97,57,40,0,137,164,190,210,1,10,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,137,164,190,210,1,10,3,98,105,100,1,119,36,48,51,50,55,98,54,57,52,45,50,100,101,51,45,53,101,48,48,45,98,51,54,56,45,57,56,99,97,49,56,50,51,48,102,97,57,40,0,137,164,190,210,1,10,4,100,101,115,99,1,119,0,40,0,137,164,190,210,1,10,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,137,164,190,210,1,10,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,87,240,32,39,0,203,184,221,173,11,4,36,48,51,50,55,98,54,57,52,45,50,100,101,51,45,53,101,48,48,45,98,51,54,56,45,57,56,99,97,49,56,50,51,48,102,97,57,0,40,0,137,164,190,210,1,10,4,105,99,111,110,1,119,0,40,0,137,164,190,210,1,10,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,137,164,190,210,1,10,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,137,164,190,210,1,10,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,137,164,190,210,1,21,1,122,4,56,115,160,190,64,16,0,168,137,164,190,210,1,20,1,122,0,0,0,0,102,87,240,32,40,0,137,164,190,210,1,10,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,137,164,190,210,1,6,1,161,166,201,221,141,13,13,1,161,166,201,221,141,13,14,1,136,137,164,190,210,1,9,1,118,2,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,88,24,223,168,137,164,190,210,1,26,1,122,4,56,115,160,190,64,16,0,168,137,164,190,210,1,27,1,122,0,0,0,0,102,88,24,223,136,137,164,190,210,1,28,1,118,2,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,88,24,223,161,162,238,198,212,7,0,1,161,162,238,198,212,7,1,1,136,137,164,190,210,1,31,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,88,31,80,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,168,137,164,190,210,1,25,1,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,168,137,164,190,210,1,32,1,122,4,56,115,160,190,64,16,0,168,137,164,190,210,1,33,1,122,0,0,0,0,102,88,31,80,136,137,164,190,210,1,34,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,88,31,80,1,152,252,186,192,1,0,161,211,166,203,229,4,194,1,2,3,248,136,168,181,1,0,161,197,254,154,201,10,0,1,161,197,254,154,201,10,1,1,129,197,254,154,201,10,2,1,1,234,187,164,181,1,0,161,253,205,145,137,11,5,24,3,164,188,201,172,1,0,161,222,205,223,235,7,28,1,161,222,205,223,235,7,29,1,129,222,205,223,235,7,30,1,4,233,247,183,159,1,0,161,244,226,228,149,2,23,1,161,248,153,216,10,0,1,161,248,153,216,10,1,1,129,187,173,214,176,15,2,1,1,190,139,191,155,1,0,161,157,207,243,216,6,1,2,3,141,216,158,150,1,0,161,225,248,138,176,2,46,1,161,225,248,138,176,2,47,1,129,225,248,138,176,2,48,1,1,213,255,156,145,1,0,161,177,219,160,167,7,3,2,38,170,255,211,105,0,161,140,152,206,145,6,162,1,1,161,140,152,206,145,6,163,1,1,136,140,152,206,145,6,161,1,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,246,42,161,245,220,194,52,3,1,161,245,220,194,52,4,1,129,245,220,194,52,11,1,161,140,152,206,145,6,158,1,1,161,170,255,211,105,3,1,161,170,255,211,105,4,1,129,170,255,211,105,5,1,161,140,152,206,145,6,37,1,161,140,152,206,145,6,38,1,129,170,255,211,105,9,1,161,170,255,211,105,6,1,161,170,255,211,105,10,1,161,170,255,211,105,11,1,129,170,255,211,105,12,1,161,245,220,194,52,18,1,161,245,220,194,52,19,1,129,170,255,211,105,16,1,161,170,255,211,105,13,1,161,170,255,211,105,17,1,161,170,255,211,105,18,1,129,170,255,211,105,19,1,161,170,255,211,105,14,1,161,170,255,211,105,15,1,129,170,255,211,105,23,1,161,170,255,211,105,20,1,168,170,255,211,105,24,1,122,4,56,115,160,190,64,16,0,168,170,255,211,105,25,1,122,0,0,0,0,102,83,252,197,136,170,255,211,105,26,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,252,197,2,105,100,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,161,245,220,194,52,24,1,161,245,220,194,52,25,1,129,170,255,211,105,30,1,161,170,255,211,105,27,1,161,170,255,211,105,31,1,161,170,255,211,105,32,1,129,170,255,211,105,33,1,179,2,174,151,139,93,0,161,177,161,136,243,11,7,1,161,177,161,136,243,11,8,1,129,177,161,136,243,11,9,1,161,177,161,136,243,11,0,1,161,177,161,136,243,11,1,1,129,174,151,139,93,2,1,161,177,161,136,243,11,6,1,161,174,151,139,93,3,1,161,174,151,139,93,4,1,129,174,151,139,93,5,1,161,165,139,157,171,15,14,1,161,165,139,157,171,15,13,1,129,174,151,139,93,9,1,161,174,151,139,93,6,1,161,174,151,139,93,10,1,161,174,151,139,93,11,1,129,174,151,139,93,12,1,161,174,151,139,93,13,1,161,174,151,139,93,7,1,161,174,151,139,93,8,1,129,174,151,139,93,16,1,161,174,151,139,93,18,1,161,174,151,139,93,19,1,129,174,151,139,93,20,1,161,241,155,213,233,1,3,1,161,241,155,213,233,1,4,1,129,174,151,139,93,23,1,161,174,151,139,93,17,1,161,174,151,139,93,24,1,161,174,151,139,93,25,1,129,174,151,139,93,26,1,161,174,151,139,93,21,1,161,174,151,139,93,22,1,129,174,151,139,93,30,1,161,174,151,139,93,27,1,161,174,151,139,93,31,1,161,174,151,139,93,32,1,129,174,151,139,93,33,1,161,174,151,139,93,0,1,161,174,151,139,93,1,1,129,174,151,139,93,37,1,161,174,151,139,93,34,1,161,174,151,139,93,38,1,161,174,151,139,93,39,1,129,174,151,139,93,40,1,39,0,203,184,221,173,11,1,36,102,53,54,98,100,102,48,102,45,57,48,99,56,45,53,51,102,98,45,57,55,100,57,45,97,100,53,56,54,48,100,50,98,55,97,48,1,40,0,174,151,139,93,45,2,105,100,1,119,36,102,53,54,98,100,102,48,102,45,57,48,99,56,45,53,51,102,98,45,57,55,100,57,45,97,100,53,56,54,48,100,50,98,55,97,48,40,0,174,151,139,93,45,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,174,151,139,93,45,3,98,105,100,1,119,36,102,53,54,98,100,102,48,102,45,57,48,99,56,45,53,51,102,98,45,57,55,100,57,45,97,100,53,56,54,48,100,50,98,55,97,48,40,0,174,151,139,93,45,4,100,101,115,99,1,119,0,40,0,174,151,139,93,45,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,174,151,139,93,45,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,101,46,39,0,203,184,221,173,11,4,36,102,53,54,98,100,102,48,102,45,57,48,99,56,45,53,51,102,98,45,57,55,100,57,45,97,100,53,56,54,48,100,50,98,55,97,48,0,40,0,174,151,139,93,45,4,105,99,111,110,1,119,0,40,0,174,151,139,93,45,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,174,151,139,93,45,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,174,151,139,93,45,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,174,151,139,93,56,1,122,4,56,115,160,190,64,16,0,168,174,151,139,93,55,1,122,0,0,0,0,102,77,101,47,40,0,174,151,139,93,45,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,174,151,139,93,42,1,161,174,151,139,93,43,1,129,174,151,139,93,44,1,161,174,151,139,93,60,1,161,174,151,139,93,61,1,129,174,151,139,93,62,1,161,234,153,236,158,4,61,1,161,234,153,236,158,4,62,1,129,174,151,139,93,65,1,161,174,151,139,93,41,1,161,174,151,139,93,66,1,161,174,151,139,93,67,1,129,174,151,139,93,68,1,161,174,151,139,93,63,1,161,174,151,139,93,64,1,129,174,151,139,93,72,1,161,174,151,139,93,69,1,161,174,151,139,93,73,1,161,174,151,139,93,74,1,129,174,151,139,93,75,1,161,174,151,139,93,70,1,161,174,151,139,93,71,1,129,174,151,139,93,79,1,161,174,151,139,93,76,1,161,174,151,139,93,80,1,161,174,151,139,93,81,1,129,174,151,139,93,82,1,161,174,151,139,93,83,1,161,174,151,139,93,28,1,161,174,151,139,93,29,1,129,174,151,139,93,86,1,161,174,151,139,93,87,1,161,201,129,238,197,4,71,1,161,201,129,238,197,4,70,1,129,174,151,139,93,90,1,161,174,151,139,93,88,1,161,174,151,139,93,89,1,129,174,151,139,93,94,1,161,174,151,139,93,91,1,161,174,151,139,93,35,1,161,174,151,139,93,36,1,129,174,151,139,93,97,1,161,174,151,139,93,99,1,161,174,151,139,93,100,1,129,174,151,139,93,101,1,161,174,151,139,93,92,1,161,174,151,139,93,93,1,129,174,151,139,93,104,1,161,174,151,139,93,102,1,161,174,151,139,93,103,1,129,174,151,139,93,107,1,161,174,151,139,93,108,1,161,174,151,139,93,109,1,129,174,151,139,93,110,1,39,0,203,184,221,173,11,1,36,50,49,97,100,55,99,57,48,45,98,102,53,57,45,53,100,97,56,45,57,97,98,99,45,53,98,50,50,102,56,102,102,54,99,52,101,1,40,0,174,151,139,93,114,2,105,100,1,119,36,50,49,97,100,55,99,57,48,45,98,102,53,57,45,53,100,97,56,45,57,97,98,99,45,53,98,50,50,102,56,102,102,54,99,52,101,40,0,174,151,139,93,114,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,174,151,139,93,114,3,98,105,100,1,119,36,50,49,97,100,55,99,57,48,45,98,102,53,57,45,53,100,97,56,45,57,97,98,99,45,53,98,50,50,102,56,102,102,54,99,52,101,40,0,174,151,139,93,114,4,100,101,115,99,1,119,0,40,0,174,151,139,93,114,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,174,151,139,93,114,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,101,175,39,0,203,184,221,173,11,4,36,50,49,97,100,55,99,57,48,45,98,102,53,57,45,53,100,97,56,45,57,97,98,99,45,53,98,50,50,102,56,102,102,54,99,52,101,0,40,0,174,151,139,93,114,4,105,99,111,110,1,119,0,40,0,174,151,139,93,114,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,174,151,139,93,114,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,174,151,139,93,114,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,174,151,139,93,125,1,122,4,56,115,160,190,64,16,0,168,174,151,139,93,124,1,122,0,0,0,0,102,77,101,175,40,0,174,151,139,93,114,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,174,151,139,93,111,1,161,174,151,139,93,112,1,129,174,151,139,93,113,1,161,174,151,139,93,129,1,1,161,174,151,139,93,130,1,1,129,174,151,139,93,131,1,1,161,174,151,139,93,77,1,161,174,151,139,93,78,1,129,174,151,139,93,134,1,1,161,174,151,139,93,98,1,161,174,151,139,93,135,1,1,161,174,151,139,93,136,1,1,129,174,151,139,93,137,1,1,161,174,151,139,93,132,1,1,161,174,151,139,93,133,1,1,129,174,151,139,93,141,1,1,161,174,151,139,93,138,1,1,161,174,151,139,93,142,1,1,161,174,151,139,93,143,1,1,129,174,151,139,93,144,1,1,161,174,151,139,93,95,1,161,174,151,139,93,96,1,129,174,151,139,93,148,1,1,161,174,151,139,93,145,1,1,161,174,151,139,93,149,1,1,161,174,151,139,93,150,1,1,129,174,151,139,93,151,1,1,161,174,151,139,93,146,1,1,161,174,151,139,93,147,1,1,129,174,151,139,93,155,1,1,161,174,151,139,93,152,1,1,161,174,151,139,93,156,1,1,161,174,151,139,93,157,1,1,129,174,151,139,93,158,1,1,161,174,151,139,93,139,1,1,161,174,151,139,93,140,1,1,129,174,151,139,93,162,1,1,161,174,151,139,93,159,1,1,161,174,151,139,93,163,1,1,161,174,151,139,93,164,1,1,129,174,151,139,93,165,1,1,161,174,151,139,93,160,1,1,161,174,151,139,93,161,1,1,129,174,151,139,93,169,1,1,161,174,151,139,93,166,1,1,161,174,151,139,93,170,1,1,161,174,151,139,93,171,1,1,129,174,151,139,93,172,1,1,8,0,241,155,213,233,1,16,1,118,1,2,105,100,119,36,54,54,97,54,102,51,98,99,45,99,55,56,102,45,52,102,55,52,45,97,48,57,101,45,48,56,100,52,55,49,55,98,102,49,102,100,161,241,155,213,233,1,15,1,161,174,151,139,93,175,1,1,39,0,203,184,221,173,11,1,36,54,54,97,54,102,51,98,99,45,99,55,56,102,45,52,102,55,52,45,97,48,57,101,45,48,56,100,52,55,49,55,98,102,49,102,100,1,40,0,174,151,139,93,180,1,2,105,100,1,119,36,54,54,97,54,102,51,98,99,45,99,55,56,102,45,52,102,55,52,45,97,48,57,101,45,48,56,100,52,55,49,55,98,102,49,102,100,40,0,174,151,139,93,180,1,4,110,97,109,101,1,119,4,71,114,105,100,40,0,174,151,139,93,180,1,3,98,105,100,1,119,36,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,40,0,174,151,139,93,180,1,4,100,101,115,99,1,119,0,40,0,174,151,139,93,180,1,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,1,40,0,174,151,139,93,180,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,165,65,39,0,203,184,221,173,11,4,36,54,54,97,54,102,51,98,99,45,99,55,56,102,45,52,102,55,52,45,97,48,57,101,45,48,56,100,52,55,49,55,98,102,49,102,100,0,40,0,174,151,139,93,180,1,4,105,99,111,110,1,119,0,40,0,174,151,139,93,180,1,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,40,0,174,151,139,93,180,1,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,122,0,0,0,0,102,77,165,65,40,0,174,151,139,93,180,1,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,39,0,203,184,221,173,11,1,36,49,102,98,50,53,48,49,57,45,52,51,57,52,45,53,57,54,53,45,97,49,50,98,45,49,98,48,101,52,99,57,55,55,48,55,99,1,40,0,174,151,139,93,192,1,2,105,100,1,119,36,49,102,98,50,53,48,49,57,45,52,51,57,52,45,53,57,54,53,45,97,49,50,98,45,49,98,48,101,52,99,57,55,55,48,55,99,40,0,174,151,139,93,192,1,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,174,151,139,93,192,1,3,98,105,100,1,119,36,49,102,98,50,53,48,49,57,45,52,51,57,52,45,53,57,54,53,45,97,49,50,98,45,49,98,48,101,52,99,57,55,55,48,55,99,40,0,174,151,139,93,192,1,4,100,101,115,99,1,119,0,40,0,174,151,139,93,192,1,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,174,151,139,93,192,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,166,20,39,0,203,184,221,173,11,4,36,49,102,98,50,53,48,49,57,45,52,51,57,52,45,53,57,54,53,45,97,49,50,98,45,49,98,48,101,52,99,57,55,55,48,55,99,0,40,0,174,151,139,93,192,1,4,105,99,111,110,1,119,0,40,0,174,151,139,93,192,1,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,174,151,139,93,192,1,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,174,151,139,93,192,1,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,174,151,139,93,203,1,1,122,4,56,115,160,190,64,16,0,168,174,151,139,93,202,1,1,122,0,0,0,0,102,77,166,20,40,0,174,151,139,93,192,1,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,39,0,203,184,221,173,11,1,36,54,97,102,100,54,57,56,52,45,48,51,98,52,45,53,53,57,100,45,98,49,52,54,45,52,49,100,98,97,54,49,50,49,48,98,56,1,40,0,174,151,139,93,207,1,2,105,100,1,119,36,54,97,102,100,54,57,56,52,45,48,51,98,52,45,53,53,57,100,45,98,49,52,54,45,52,49,100,98,97,54,49,50,49,48,98,56,40,0,174,151,139,93,207,1,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,174,151,139,93,207,1,3,98,105,100,1,119,36,54,97,102,100,54,57,56,52,45,48,51,98,52,45,53,53,57,100,45,98,49,52,54,45,52,49,100,98,97,54,49,50,49,48,98,56,40,0,174,151,139,93,207,1,4,100,101,115,99,1,119,0,40,0,174,151,139,93,207,1,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,174,151,139,93,207,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,183,211,39,0,203,184,221,173,11,4,36,54,97,102,100,54,57,56,52,45,48,51,98,52,45,53,53,57,100,45,98,49,52,54,45,52,49,100,98,97,54,49,50,49,48,98,56,0,40,0,174,151,139,93,207,1,4,105,99,111,110,1,119,0,40,0,174,151,139,93,207,1,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,174,151,139,93,207,1,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,174,151,139,93,207,1,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,174,151,139,93,218,1,1,122,4,56,115,160,190,64,16,0,168,174,151,139,93,217,1,1,122,0,0,0,0,102,77,183,211,40,0,174,151,139,93,207,1,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,39,0,203,184,221,173,11,1,36,53,54,53,50,101,52,54,54,45,101,52,99,101,45,53,54,57,99,45,98,49,101,54,45,102,100,56,101,48,101,55,100,99,48,100,99,1,40,0,174,151,139,93,222,1,2,105,100,1,119,36,53,54,53,50,101,52,54,54,45,101,52,99,101,45,53,54,57,99,45,98,49,101,54,45,102,100,56,101,48,101,55,100,99,48,100,99,40,0,174,151,139,93,222,1,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,174,151,139,93,222,1,3,98,105,100,1,119,36,53,54,53,50,101,52,54,54,45,101,52,99,101,45,53,54,57,99,45,98,49,101,54,45,102,100,56,101,48,101,55,100,99,48,100,99,40,0,174,151,139,93,222,1,4,100,101,115,99,1,119,0,40,0,174,151,139,93,222,1,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,174,151,139,93,222,1,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,77,187,249,39,0,203,184,221,173,11,4,36,53,54,53,50,101,52,54,54,45,101,52,99,101,45,53,54,57,99,45,98,49,101,54,45,102,100,56,101,48,101,55,100,99,48,100,99,0,40,0,174,151,139,93,222,1,4,105,99,111,110,1,119,0,40,0,174,151,139,93,222,1,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,174,151,139,93,222,1,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,174,151,139,93,222,1,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,174,151,139,93,233,1,1,122,4,56,115,160,190,64,16,0,168,174,151,139,93,232,1,1,122,0,0,0,0,102,77,187,249,40,0,174,151,139,93,222,1,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,174,151,139,93,167,1,1,161,174,151,139,93,168,1,1,129,174,151,139,93,176,1,1,161,174,151,139,93,173,1,1,161,174,151,139,93,237,1,1,161,174,151,139,93,238,1,1,129,174,151,139,93,239,1,1,161,174,151,139,93,241,1,1,161,174,151,139,93,242,1,1,129,241,130,161,205,7,11,1,161,174,151,139,93,244,1,1,161,174,151,139,93,245,1,1,129,174,151,139,93,246,1,1,161,241,130,161,205,7,3,1,161,241,130,161,205,7,4,1,129,174,151,139,93,249,1,1,161,174,151,139,93,240,1,1,161,174,151,139,93,250,1,1,161,174,151,139,93,251,1,1,129,174,151,139,93,252,1,1,161,174,151,139,93,247,1,1,161,174,151,139,93,248,1,1,129,174,151,139,93,128,2,1,161,174,151,139,93,253,1,1,161,174,151,139,93,129,2,1,161,174,151,139,93,130,2,1,129,174,151,139,93,131,2,1,161,226,212,179,248,2,9,1,161,226,212,179,248,2,10,1,129,174,151,139,93,135,2,1,161,174,151,139,93,132,2,1,161,174,151,139,93,136,2,1,161,174,151,139,93,137,2,1,129,174,151,139,93,138,2,1,161,174,151,139,93,133,2,1,161,174,151,139,93,134,2,1,129,174,151,139,93,142,2,1,161,174,151,139,93,139,2,1,161,174,151,139,93,143,2,1,161,174,151,139,93,144,2,1,129,174,151,139,93,145,2,1,39,0,203,184,221,173,11,1,36,51,50,48,102,56,48,97,100,45,50,51,52,101,45,53,49,55,50,45,97,49,55,50,45,102,55,56,52,54,52,55,50,55,98,100,97,1,40,0,174,151,139,93,150,2,2,105,100,1,119,36,51,50,48,102,56,48,97,100,45,50,51,52,101,45,53,49,55,50,45,97,49,55,50,45,102,55,56,52,54,52,55,50,55,98,100,97,40,0,174,151,139,93,150,2,4,110,97,109,101,1,119,8,85,110,116,105,116,108,101,100,40,0,174,151,139,93,150,2,3,98,105,100,1,119,36,51,50,48,102,56,48,97,100,45,50,51,52,101,45,53,49,55,50,45,97,49,55,50,45,102,55,56,52,54,52,55,50,55,98,100,97,40,0,174,151,139,93,150,2,4,100,101,115,99,1,119,0,40,0,174,151,139,93,150,2,6,108,97,121,111,117,116,1,122,0,0,0,0,0,0,0,0,40,0,174,151,139,93,150,2,10,99,114,101,97,116,101,100,95,97,116,1,122,0,0,0,0,102,78,228,14,39,0,203,184,221,173,11,4,36,51,50,48,102,56,48,97,100,45,50,51,52,101,45,53,49,55,50,45,97,49,55,50,45,102,55,56,52,54,52,55,50,55,98,100,97,0,40,0,174,151,139,93,150,2,4,105,99,111,110,1,119,0,40,0,174,151,139,93,150,2,10,99,114,101,97,116,101,100,95,98,121,1,122,4,56,115,160,190,64,16,0,33,0,174,151,139,93,150,2,16,108,97,115,116,95,101,100,105,116,101,100,95,116,105,109,101,1,33,0,174,151,139,93,150,2,14,108,97,115,116,95,101,100,105,116,101,100,95,98,121,1,168,174,151,139,93,161,2,1,122,4,56,115,160,190,64,16,0,168,174,151,139,93,160,2,1,122,0,0,0,0,102,78,228,14,40,0,174,151,139,93,150,2,5,101,120,116,114,97,1,119,36,123,34,99,111,118,101,114,34,58,123,34,116,121,112,101,34,58,34,110,111,110,101,34,44,34,118,97,108,117,101,34,58,34,34,125,125,161,174,151,139,93,14,1,161,174,151,139,93,15,1,129,174,151,139,93,149,2,1,161,174,151,139,93,146,2,1,168,174,151,139,93,165,2,1,122,4,56,115,160,190,64,16,0,161,174,151,139,93,166,2,1,136,174,151,139,93,167,2,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,78,229,144,2,105,100,119,36,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,161,174,151,139,93,147,2,1,161,174,151,139,93,148,2,1,129,174,151,139,93,171,2,1,161,174,151,139,93,168,2,1,161,174,151,139,93,172,2,1,161,174,151,139,93,173,2,1,129,174,151,139,93,174,2,1,1,184,231,170,67,0,161,145,144,146,185,5,11,6,39,245,220,194,52,0,161,209,250,203,254,15,0,1,161,209,250,203,254,15,1,1,136,209,250,203,254,15,2,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,246,151,161,140,152,206,145,6,152,1,1,161,140,152,206,145,6,153,1,1,129,245,220,194,52,2,1,161,245,220,194,52,0,1,161,245,220,194,52,1,1,136,245,220,194,52,5,1,118,2,2,105,100,119,36,50,54,100,53,99,56,99,49,45,49,99,54,54,45,52,53,57,99,45,98,99,54,99,45,102,52,100,97,49,97,54,54,51,51,52,56,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,246,202,161,140,152,206,145,6,87,1,161,140,152,206,145,6,88,1,136,245,220,194,52,8,1,118,2,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,83,246,206,2,105,100,119,36,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,161,245,220,194,52,3,1,161,245,220,194,52,4,1,129,245,220,194,52,11,1,161,170,255,211,105,7,1,161,170,255,211,105,8,1,161,140,152,206,145,6,151,1,1,161,245,220,194,52,15,1,161,245,220,194,52,16,1,161,245,220,194,52,17,1,161,170,255,211,105,21,1,161,170,255,211,105,22,1,161,245,220,194,52,20,1,161,245,220,194,52,21,1,161,245,220,194,52,22,1,161,245,220,194,52,23,1,161,170,255,211,105,35,1,161,170,255,211,105,36,1,129,170,255,211,105,37,1,161,245,220,194,52,27,1,161,245,220,194,52,28,1,129,245,220,194,52,29,1,161,245,220,194,52,30,1,161,245,220,194,52,31,1,161,245,220,194,52,26,1,161,245,220,194,52,33,1,161,245,220,194,52,34,1,161,245,220,194,52,35,1,6,166,203,155,46,0,161,140,152,206,145,6,30,1,161,140,152,206,145,6,31,1,129,162,238,198,212,7,2,1,168,166,203,155,46,0,1,122,4,56,115,160,190,64,16,0,168,166,203,155,46,1,1,122,0,0,0,0,102,88,52,80,136,166,203,155,46,2,1,118,2,2,105,100,119,36,48,99,101,49,51,52,49,53,45,54,99,99,101,45,52,52,57,55,45,57,52,99,54,45,52,55,53,97,100,57,54,99,50,52,57,101,9,116,105,109,101,115,116,97,109,112,122,0,0,0,0,102,88,52,80,3,179,252,154,44,0,161,157,240,144,231,2,0,1,161,157,240,144,231,2,1,1,129,157,240,144,231,2,2,1,3,248,153,216,10,0,161,163,236,177,169,4,9,1,161,163,236,177,169,4,10,1,129,163,236,177,169,4,11,1,155,1,128,252,161,128,4,1,0,33,130,180,254,251,6,4,0,3,5,2,9,1,13,4,135,240,136,178,10,1,0,45,135,232,133,203,9,1,0,15,137,226,192,199,6,1,0,20,138,202,240,189,2,1,0,134,1,139,240,196,145,14,1,0,138,2,140,228,230,243,1,1,0,2,139,152,215,249,10,1,0,34,141,216,158,150,1,1,0,3,142,130,192,134,11,1,0,3,143,184,153,180,6,1,0,6,145,190,137,224,10,1,0,2,145,144,146,185,5,1,0,12,140,152,206,145,6,16,0,46,47,9,57,3,61,24,86,3,90,3,94,2,97,3,101,2,105,1,111,1,113,20,134,1,20,155,1,2,158,1,3,162,1,2,135,166,246,235,6,1,0,2,147,206,229,235,1,1,0,3,137,164,190,210,1,5,3,2,6,1,20,2,25,3,32,2,152,252,186,192,1,1,0,2,153,130,203,161,6,1,0,97,154,244,246,165,8,10,0,24,26,1,37,2,56,1,71,1,82,3,88,36,127,18,148,1,35,193,1,2,156,148,170,169,10,1,0,16,157,240,144,231,2,1,0,3,158,156,181,152,10,7,0,6,7,2,15,1,19,8,28,2,32,1,40,9,159,156,204,250,6,1,0,27,160,192,253,131,5,1,0,3,161,178,132,150,11,4,0,15,17,1,28,64,93,8,158,182,250,251,9,1,0,15,163,236,177,169,4,1,0,12,164,188,201,172,1,1,0,3,158,184,218,165,3,1,0,38,162,238,198,212,7,1,0,2,170,140,240,234,9,1,0,31,171,204,155,217,8,1,0,3,171,142,166,254,1,1,0,6,173,252,148,184,13,3,0,40,41,2,44,20,176,154,159,227,1,3,0,1,2,2,14,6,178,162,190,217,10,1,0,3,179,252,154,44,1,0,3,180,230,210,212,13,2,0,2,3,4,182,172,247,194,5,1,0,3,183,226,184,158,8,1,0,8,195,242,227,194,8,1,0,3,196,154,250,183,6,1,0,62,197,254,154,201,10,1,0,3,200,142,208,241,4,1,0,157,1,202,160,246,212,1,1,0,6,203,184,221,173,11,6,14,1,19,1,21,2,29,1,33,2,36,1,206,220,129,131,4,3,0,3,4,2,16,5,207,228,238,162,8,4,1,2,13,9,23,2,35,15,209,250,203,254,15,1,0,2,210,228,153,221,12,1,0,3,211,166,203,229,4,1,0,195,1,211,202,217,232,12,1,0,7,214,168,149,214,3,1,0,15,225,248,138,176,2,6,0,9,10,2,13,1,18,2,26,1,30,19,226,212,179,248,2,1,0,15,229,154,128,197,12,4,0,6,7,2,15,1,19,5,234,182,182,157,9,1,0,8,235,178,165,206,5,1,0,72,241,130,161,205,7,1,0,9,244,226,228,149,2,4,1,3,6,1,17,4,23,7,245,220,194,52,4,0,2,3,5,9,2,12,27,247,200,243,247,14,5,2,1,5,1,13,8,22,32,58,39,248,136,168,181,1,1,0,3,248,210,237,129,13,1,0,2,250,198,166,187,7,1,0,2,248,196,187,185,10,1,0,26,252,218,241,167,14,1,0,2,255,140,248,220,6,1,0,3,128,211,179,216,2,1,0,10,133,159,138,205,12,14,0,7,9,1,20,9,42,14,57,2,61,1,65,1,67,1,69,17,87,6,94,2,106,2,109,2,121,10,135,167,156,250,14,1,0,16,135,193,208,135,7,1,0,16,141,245,194,142,11,1,0,7,141,205,220,149,4,1,0,3,143,131,148,152,6,1,1,2,141,171,170,217,4,1,0,2,145,159,164,217,14,1,0,3,149,129,169,191,12,1,0,16,149,249,242,175,4,3,0,8,11,2,16,15,149,189,189,215,8,1,0,3,149,161,132,184,14,1,0,221,2,154,243,157,196,14,1,0,12,154,193,208,134,10,1,0,9,155,165,205,152,11,1,0,3,155,159,180,195,15,1,0,6,157,207,243,216,6,1,0,2,154,235,215,240,4,1,0,13,161,239,241,154,13,1,0,106,162,159,252,196,11,1,0,3,164,155,139,169,7,1,0,35,165,139,157,171,15,11,2,1,9,1,13,5,19,2,27,1,31,6,39,1,52,5,58,12,72,1,85,18,164,203,250,235,13,1,0,7,167,131,133,162,9,1,0,11,166,201,221,141,13,11,0,6,7,2,10,2,13,2,26,2,31,2,34,3,38,6,45,2,57,11,69,3,166,203,155,46,1,0,3,170,255,211,105,3,0,2,3,25,31,7,169,197,188,221,3,1,0,3,173,187,245,170,14,1,0,46,174,151,139,93,14,0,45,55,2,60,54,124,2,129,1,48,178,1,2,202,1,2,217,1,2,232,1,2,237,1,41,160,2,2,165,2,4,170,2,1,172,2,7,175,225,172,150,8,1,0,10,175,147,217,214,1,1,0,33,177,161,136,243,11,1,0,10,178,203,205,182,4,1,0,1,175,205,156,228,6,1,0,10,180,205,189,133,13,1,0,20,181,175,219,209,12,1,0,10,182,143,233,195,4,1,0,111,177,219,160,167,7,1,0,4,184,201,188,172,10,1,0,3,184,231,170,67,1,0,6,186,197,166,179,15,1,0,7,188,171,136,250,8,1,0,21,188,237,223,145,6,1,0,26,190,139,191,155,1,1,0,2,191,157,147,233,9,1,0,32,193,249,142,142,4,1,0,17,198,189,216,175,6,1,0,23,200,205,214,172,10,1,0,30,201,129,238,197,4,8,0,6,9,33,43,2,51,1,55,2,58,2,66,1,70,13,201,191,159,147,14,1,0,17,200,203,236,184,2,1,0,35,200,159,185,206,9,1,0,8,205,149,231,236,11,1,0,68,213,161,242,209,13,5,0,3,4,2,8,1,16,7,27,8,214,139,213,136,8,13,0,2,5,2,10,2,15,2,20,2,25,2,30,2,35,2,40,2,45,2,50,2,55,2,60,6,213,255,156,145,1,1,0,2,219,227,140,137,6,1,0,34,221,147,167,147,15,1,0,177,2,222,205,223,235,7,2,0,9,10,21,223,209,193,147,11,1,0,81,227,209,197,253,2,1,0,14,229,153,197,202,7,1,0,241,6,231,139,244,188,8,1,0,13,232,207,157,148,2,1,0,2,233,165,139,246,14,4,0,2,3,4,8,2,20,23,233,247,183,159,1,1,0,4,235,225,184,133,10,1,0,3,234,153,236,158,4,8,0,6,7,2,11,1,15,1,19,6,27,1,38,7,46,27,234,187,164,181,1,1,0,24,231,189,134,196,8,1,0,77,239,199,189,146,3,1,0,24,240,149,229,225,6,1,1,2,241,155,213,233,1,5,0,6,7,2,11,1,15,1,19,32,240,253,240,229,1,1,0,79,243,239,182,181,13,2,1,2,16,2,236,229,225,232,8,1,0,116,246,185,174,192,6,1,0,90,248,153,216,10,1,0,3,251,189,220,155,14,1,0,3,252,163,130,200,6,2,1,2,16,2,253,205,145,137,11,1,0,10,252,171,209,175,15,1,0,4,255,255,147,249,10,1,0,3],"version":0,"object_id":"9eebea03-3ed5-4298-86b2-a7f77856d48b"},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/full_doc.json b/frontend/appflowy_web_app/cypress/fixtures/full_doc.json index e47a6c6fc0..c4eabdadc4 100644 --- a/frontend/appflowy_web_app/cypress/fixtures/full_doc.json +++ b/frontend/appflowy_web_app/cypress/fixtures/full_doc.json @@ -1 +1 @@ -{"data":{"state_vector":[43,192,246,139,213,2,35,131,182,180,202,12,53,132,236,218,251,9,14,197,205,192,233,12,9,198,223,206,159,1,145,2,199,130,209,189,2,141,8,136,172,186,168,4,182,6,131,128,202,229,9,1,204,195,206,156,1,153,9,141,178,210,127,3,140,167,201,161,14,10,207,231,154,196,9,3,142,211,188,164,13,15,206,214,243,86,178,1,146,216,250,133,2,180,1,150,152,188,203,6,20,151,234,142,238,11,27,150,216,171,142,3,188,8,217,168,198,159,4,7,218,255,204,32,21,155,213,159,176,1,10,219,200,174,197,9,25,224,159,166,178,15,30,161,234,157,145,5,7,226,167,254,250,5,13,228,242,134,215,15,12,165,131,171,211,15,20,229,154,194,35,178,1,164,202,219,213,10,122,168,215,223,235,2,56,171,236,222,251,5,252,4,172,254,181,239,1,15,236,158,128,159,2,4,239,239,208,251,10,17,176,238,158,139,14,175,2,241,147,239,232,6,4,178,187,245,161,14,11,243,138,171,183,10,252,1,245,181,155,135,2,23,181,156,253,158,6,5,247,212,219,208,10,46,184,146,243,216,14,7,190,183,139,210,2,110],"doc_state":[43,9,228,242,134,215,15,0,39,0,204,195,206,156,1,4,6,109,86,80,71,80,99,2,4,0,228,242,134,215,15,0,4,104,106,107,100,161,172,254,181,239,1,14,1,132,228,242,134,215,15,4,1,56,161,228,242,134,215,15,5,1,132,228,242,134,215,15,6,1,56,161,228,242,134,215,15,7,1,132,228,242,134,215,15,8,1,56,161,228,242,134,215,15,9,1,18,165,131,171,211,15,0,129,155,213,159,176,1,6,2,161,155,213,159,176,1,7,1,161,155,213,159,176,1,8,1,161,155,213,159,176,1,9,1,161,165,131,171,211,15,2,1,161,165,131,171,211,15,3,1,161,165,131,171,211,15,4,1,161,165,131,171,211,15,5,1,161,165,131,171,211,15,6,1,161,165,131,171,211,15,7,1,129,165,131,171,211,15,1,2,161,165,131,171,211,15,8,1,161,165,131,171,211,15,9,1,161,165,131,171,211,15,10,1,129,165,131,171,211,15,12,1,161,165,131,171,211,15,13,1,161,165,131,171,211,15,14,1,161,165,131,171,211,15,15,1,28,224,159,166,178,15,0,129,165,131,171,211,15,16,1,161,197,205,192,233,12,6,1,161,197,205,192,233,12,7,1,161,197,205,192,233,12,8,1,161,224,159,166,178,15,1,1,161,224,159,166,178,15,2,1,161,224,159,166,178,15,3,1,129,224,159,166,178,15,0,1,161,224,159,166,178,15,4,1,161,224,159,166,178,15,5,1,161,224,159,166,178,15,6,1,129,224,159,166,178,15,7,2,161,224,159,166,178,15,8,1,161,224,159,166,178,15,9,1,161,224,159,166,178,15,10,1,161,224,159,166,178,15,13,1,161,224,159,166,178,15,14,1,161,224,159,166,178,15,15,1,161,224,159,166,178,15,16,1,161,224,159,166,178,15,17,1,161,224,159,166,178,15,18,1,161,224,159,166,178,15,19,1,161,224,159,166,178,15,20,1,161,224,159,166,178,15,21,1,129,224,159,166,178,15,12,2,161,224,159,166,178,15,22,1,161,224,159,166,178,15,23,1,161,224,159,166,178,15,24,1,7,184,146,243,216,14,0,129,217,168,198,159,4,3,1,161,142,211,188,164,13,12,1,161,142,211,188,164,13,13,1,161,142,211,188,164,13,14,1,161,184,146,243,216,14,1,1,161,184,146,243,216,14,2,1,161,184,146,243,216,14,3,1,5,178,187,245,161,14,0,39,0,204,195,206,156,1,4,6,95,104,88,73,115,119,2,4,0,178,187,245,161,14,0,13,229,144,140,228,184,128,228,184,170,106,106,106,57,161,198,223,206,159,1,124,1,132,178,187,245,161,14,7,1,57,161,178,187,245,161,14,8,1,5,140,167,201,161,14,0,0,4,132,204,195,206,156,1,245,5,9,229,176,177,229,135,160,229,174,182,168,198,223,206,159,1,89,1,119,96,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,97,110,121,119,104,101,114,101,32,97,110,100,32,106,117,115,116,32,115,116,97,114,116,32,116,121,112,105,110,103,229,147,136,229,147,136,229,147,136,46,229,176,177,229,135,160,229,174,182,34,125,93,125,168,198,223,206,159,1,90,1,119,10,119,79,108,117,99,85,55,51,73,76,168,198,223,206,159,1,91,1,119,4,116,101,120,116,1,176,238,158,139,14,0,161,206,214,243,86,177,1,175,2,15,142,211,188,164,13,0,161,217,168,198,159,4,4,1,161,217,168,198,159,4,5,1,161,217,168,198,159,4,6,1,161,142,211,188,164,13,0,1,161,142,211,188,164,13,1,1,161,142,211,188,164,13,2,1,161,142,211,188,164,13,3,1,161,142,211,188,164,13,4,1,161,142,211,188,164,13,5,1,161,142,211,188,164,13,6,1,161,142,211,188,164,13,7,1,161,142,211,188,164,13,8,1,161,142,211,188,164,13,9,1,161,142,211,188,164,13,10,1,161,142,211,188,164,13,11,1,9,197,205,192,233,12,0,161,165,131,171,211,15,17,1,161,165,131,171,211,15,18,1,161,165,131,171,211,15,19,1,161,197,205,192,233,12,0,1,161,197,205,192,233,12,1,1,161,197,205,192,233,12,2,1,161,197,205,192,233,12,3,1,161,197,205,192,233,12,4,1,161,197,205,192,233,12,5,1,47,131,182,180,202,12,0,129,184,146,243,216,14,0,1,161,184,146,243,216,14,4,1,161,184,146,243,216,14,5,1,161,184,146,243,216,14,6,1,129,131,182,180,202,12,0,2,161,131,182,180,202,12,1,1,161,131,182,180,202,12,2,1,161,131,182,180,202,12,3,1,161,131,182,180,202,12,6,1,161,131,182,180,202,12,7,1,161,131,182,180,202,12,8,1,161,131,182,180,202,12,9,1,161,131,182,180,202,12,10,1,161,131,182,180,202,12,11,1,161,131,182,180,202,12,12,1,161,131,182,180,202,12,13,1,161,131,182,180,202,12,14,1,129,131,182,180,202,12,5,3,161,131,182,180,202,12,15,1,161,131,182,180,202,12,16,1,161,131,182,180,202,12,17,1,161,131,182,180,202,12,21,1,161,131,182,180,202,12,22,1,161,131,182,180,202,12,23,1,161,131,182,180,202,12,24,1,161,131,182,180,202,12,25,1,161,131,182,180,202,12,26,1,161,131,182,180,202,12,27,1,161,131,182,180,202,12,28,1,161,131,182,180,202,12,29,1,129,131,182,180,202,12,20,4,161,131,182,180,202,12,30,1,161,131,182,180,202,12,31,1,161,131,182,180,202,12,32,1,161,131,182,180,202,12,37,1,161,131,182,180,202,12,38,1,161,131,182,180,202,12,39,1,129,131,182,180,202,12,36,1,161,131,182,180,202,12,40,1,161,131,182,180,202,12,41,1,161,131,182,180,202,12,42,1,161,131,182,180,202,12,44,1,161,131,182,180,202,12,45,1,161,131,182,180,202,12,46,1,161,131,182,180,202,12,47,1,161,131,182,180,202,12,48,1,161,131,182,180,202,12,49,1,1,151,234,142,238,11,0,161,229,154,194,35,177,1,27,1,239,239,208,251,10,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,17,81,164,202,219,213,10,0,39,0,204,195,206,156,1,4,6,103,67,116,99,89,115,2,39,0,204,195,206,156,1,4,6,102,105,108,83,57,100,2,4,0,164,202,219,213,10,1,10,116,111,100,111,32,108,105,115,116,32,134,164,202,219,213,10,11,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,56,84,49,52,58,50,53,58,51,50,46,52,53,55,50,55,55,34,125,132,164,202,219,213,10,12,1,36,134,164,202,219,213,10,13,7,109,101,110,116,105,111,110,4,110,117,108,108,132,164,202,219,213,10,14,4,109,101,110,116,33,0,204,195,206,156,1,1,6,88,55,78,102,76,50,1,0,7,33,0,204,195,206,156,1,3,6,112,56,66,76,122,103,1,193,198,223,206,159,1,135,1,199,130,209,189,2,60,1,168,199,130,209,189,2,140,8,1,119,161,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,116,111,100,111,32,108,105,115,116,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,56,84,49,52,58,50,53,58,51,50,46,52,53,55,50,55,55,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,44,123,34,105,110,115,101,114,116,34,58,34,109,101,110,116,34,125,93,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,39,0,204,195,206,156,1,4,6,66,120,115,95,114,76,2,33,0,204,195,206,156,1,1,6,111,56,54,77,119,121,1,0,7,33,0,204,195,206,156,1,3,6,67,89,84,109,67,89,1,193,198,223,206,159,1,135,1,164,202,219,213,10,28,1,4,0,164,202,219,213,10,30,1,35,0,1,39,0,204,195,206,156,1,4,6,109,113,102,117,86,95,2,33,0,204,195,206,156,1,1,6,84,100,115,87,90,75,1,0,7,33,0,204,195,206,156,1,3,6,49,115,106,52,120,74,1,193,198,223,206,159,1,135,1,164,202,219,213,10,40,1,4,0,164,202,219,213,10,43,1,49,0,1,132,164,202,219,213,10,54,1,50,0,1,132,164,202,219,213,10,56,1,51,0,1,132,164,202,219,213,10,58,1,32,0,1,129,164,202,219,213,10,60,1,0,1,134,164,202,219,213,10,62,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,125,132,164,202,219,213,10,64,1,36,134,164,202,219,213,10,65,7,109,101,110,116,105,111,110,4,110,117,108,108,0,1,39,0,204,195,206,156,1,4,6,103,83,52,80,113,73,2,4,0,164,202,219,213,10,68,4,49,50,51,32,134,164,202,219,213,10,72,7,109,101,110,116,105,111,110,51,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,132,164,202,219,213,10,73,1,36,134,164,202,219,213,10,74,7,109,101,110,116,105,111,110,4,110,117,108,108,132,164,202,219,213,10,75,1,32,0,1,129,164,202,219,213,10,76,1,0,1,161,204,195,206,156,1,155,1,1,161,204,195,206,156,1,156,1,1,161,204,195,206,156,1,157,1,1,0,1,132,164,202,219,213,10,78,1,32,0,1,132,164,202,219,213,10,84,1,101,0,1,132,164,202,219,213,10,86,1,114,0,1,132,164,202,219,213,10,88,1,32,0,1,132,164,202,219,213,10,90,1,32,0,1,68,164,202,219,213,10,69,1,35,0,1,68,164,202,219,213,10,94,1,35,0,1,39,0,204,195,206,156,1,4,6,120,115,71,80,56,122,2,4,0,164,202,219,213,10,98,4,49,50,51,32,134,164,202,219,213,10,102,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,125,132,164,202,219,213,10,103,1,36,134,164,202,219,213,10,104,7,109,101,110,116,105,111,110,4,110,117,108,108,132,164,202,219,213,10,105,6,32,32,101,114,32,32,39,0,204,195,206,156,1,1,6,106,97,80,87,115,68,1,40,0,164,202,219,213,10,112,2,105,100,1,119,6,106,97,80,87,115,68,40,0,164,202,219,213,10,112,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,164,202,219,213,10,112,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,164,202,219,213,10,112,8,99,104,105,108,100,114,101,110,1,119,6,106,75,88,90,122,73,33,0,164,202,219,213,10,112,4,100,97,116,97,1,40,0,164,202,219,213,10,112,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,164,202,219,213,10,112,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,75,88,90,122,73,0,200,198,223,206,159,1,135,1,164,202,219,213,10,53,1,119,6,106,97,80,87,115,68,1,247,212,219,208,10,0,161,132,236,218,251,9,13,46,240,1,243,138,171,183,10,0,161,150,216,171,142,3,178,5,1,161,150,216,171,142,3,190,5,1,161,150,216,171,142,3,200,5,1,161,150,216,171,142,3,187,6,1,161,150,216,171,142,3,188,6,1,161,150,216,171,142,3,189,6,1,161,150,216,171,142,3,190,6,2,161,150,216,171,142,3,251,5,1,161,150,216,171,142,3,144,6,1,161,150,216,171,142,3,164,6,1,161,243,138,171,183,10,7,1,161,243,138,171,183,10,0,1,161,243,138,171,183,10,1,1,161,243,138,171,183,10,2,1,161,243,138,171,183,10,8,1,161,243,138,171,183,10,9,1,161,243,138,171,183,10,10,1,161,243,138,171,183,10,11,1,161,243,138,171,183,10,3,1,161,243,138,171,183,10,4,1,161,243,138,171,183,10,5,1,161,243,138,171,183,10,18,2,161,243,138,171,183,10,12,1,161,243,138,171,183,10,13,1,161,243,138,171,183,10,14,1,161,243,138,171,183,10,19,1,161,243,138,171,183,10,20,1,161,243,138,171,183,10,21,1,161,243,138,171,183,10,23,1,161,243,138,171,183,10,15,1,161,243,138,171,183,10,16,1,161,243,138,171,183,10,17,1,161,243,138,171,183,10,30,2,161,243,138,171,183,10,24,1,161,243,138,171,183,10,25,1,161,243,138,171,183,10,26,1,161,243,138,171,183,10,27,1,161,243,138,171,183,10,28,1,161,243,138,171,183,10,29,1,161,243,138,171,183,10,35,1,161,243,138,171,183,10,31,1,161,243,138,171,183,10,32,1,161,243,138,171,183,10,33,1,161,243,138,171,183,10,42,2,161,243,138,171,183,10,36,1,161,243,138,171,183,10,37,1,161,243,138,171,183,10,38,1,161,243,138,171,183,10,43,1,161,243,138,171,183,10,44,1,161,243,138,171,183,10,45,1,161,243,138,171,183,10,47,1,161,243,138,171,183,10,39,1,161,243,138,171,183,10,40,1,161,243,138,171,183,10,41,1,161,243,138,171,183,10,54,2,161,243,138,171,183,10,48,1,161,243,138,171,183,10,49,1,161,243,138,171,183,10,50,1,161,243,138,171,183,10,55,1,161,243,138,171,183,10,56,1,161,243,138,171,183,10,57,1,161,243,138,171,183,10,59,1,161,243,138,171,183,10,51,1,161,243,138,171,183,10,52,1,161,243,138,171,183,10,53,1,161,243,138,171,183,10,66,2,161,243,138,171,183,10,60,1,161,243,138,171,183,10,61,1,161,243,138,171,183,10,62,1,161,243,138,171,183,10,63,1,161,243,138,171,183,10,64,1,161,243,138,171,183,10,65,1,161,243,138,171,183,10,71,2,161,243,138,171,183,10,67,1,161,243,138,171,183,10,68,1,161,243,138,171,183,10,69,1,161,243,138,171,183,10,79,1,161,243,138,171,183,10,72,1,161,243,138,171,183,10,73,1,161,243,138,171,183,10,74,1,161,243,138,171,183,10,75,1,161,243,138,171,183,10,76,1,161,243,138,171,183,10,77,1,161,243,138,171,183,10,83,1,161,243,138,171,183,10,80,1,161,243,138,171,183,10,81,1,161,243,138,171,183,10,82,1,161,243,138,171,183,10,90,2,161,146,216,250,133,2,12,1,161,146,216,250,133,2,13,1,161,146,216,250,133,2,14,1,161,146,216,250,133,2,17,1,161,146,216,250,133,2,21,1,161,146,216,250,133,2,22,1,161,146,216,250,133,2,23,1,161,243,138,171,183,10,99,1,161,146,216,250,133,2,18,1,161,146,216,250,133,2,19,1,161,146,216,250,133,2,20,1,161,243,138,171,183,10,103,1,161,146,216,250,133,2,24,1,161,146,216,250,133,2,25,1,161,146,216,250,133,2,26,1,161,146,216,250,133,2,35,1,161,146,216,250,133,2,28,1,161,146,216,250,133,2,29,1,161,146,216,250,133,2,30,1,161,243,138,171,183,10,111,1,161,146,216,250,133,2,32,1,161,146,216,250,133,2,33,1,161,146,216,250,133,2,34,1,161,243,138,171,183,10,115,1,161,146,216,250,133,2,36,1,161,146,216,250,133,2,37,1,161,146,216,250,133,2,38,1,161,146,216,250,133,2,40,1,161,146,216,250,133,2,41,1,161,146,216,250,133,2,42,1,161,146,216,250,133,2,47,1,161,146,216,250,133,2,44,1,161,146,216,250,133,2,45,1,161,146,216,250,133,2,46,1,161,243,138,171,183,10,126,2,161,146,216,250,133,2,48,1,161,146,216,250,133,2,49,1,161,146,216,250,133,2,50,1,161,146,216,250,133,2,59,1,161,146,216,250,133,2,51,1,161,146,216,250,133,2,52,1,161,146,216,250,133,2,53,1,161,243,138,171,183,10,135,1,1,161,146,216,250,133,2,56,1,161,146,216,250,133,2,57,1,161,146,216,250,133,2,58,1,161,243,138,171,183,10,139,1,1,161,146,216,250,133,2,60,1,161,146,216,250,133,2,61,1,161,146,216,250,133,2,62,1,161,146,216,250,133,2,71,1,161,146,216,250,133,2,64,1,161,146,216,250,133,2,65,1,161,146,216,250,133,2,66,1,161,243,138,171,183,10,147,1,1,161,146,216,250,133,2,68,1,161,146,216,250,133,2,69,1,161,146,216,250,133,2,70,1,161,243,138,171,183,10,151,1,1,161,146,216,250,133,2,72,1,161,146,216,250,133,2,73,1,161,146,216,250,133,2,74,1,161,146,216,250,133,2,83,1,161,146,216,250,133,2,76,1,161,146,216,250,133,2,77,1,161,146,216,250,133,2,78,1,161,243,138,171,183,10,159,1,1,161,146,216,250,133,2,80,1,161,146,216,250,133,2,81,1,161,146,216,250,133,2,82,1,161,243,138,171,183,10,163,1,1,161,146,216,250,133,2,84,1,161,146,216,250,133,2,85,1,161,146,216,250,133,2,86,1,161,146,216,250,133,2,95,1,161,146,216,250,133,2,92,1,161,146,216,250,133,2,93,1,161,146,216,250,133,2,94,1,161,243,138,171,183,10,171,1,1,161,146,216,250,133,2,88,1,161,146,216,250,133,2,89,1,161,146,216,250,133,2,90,1,161,243,138,171,183,10,175,1,1,161,146,216,250,133,2,96,1,161,146,216,250,133,2,97,1,161,146,216,250,133,2,98,1,161,146,216,250,133,2,107,1,161,146,216,250,133,2,104,1,161,146,216,250,133,2,105,1,161,146,216,250,133,2,106,1,161,243,138,171,183,10,183,1,1,161,146,216,250,133,2,100,1,161,146,216,250,133,2,101,1,161,146,216,250,133,2,102,1,161,243,138,171,183,10,187,1,1,161,146,216,250,133,2,108,1,161,146,216,250,133,2,109,1,161,146,216,250,133,2,110,1,161,146,216,250,133,2,119,1,161,146,216,250,133,2,112,1,161,146,216,250,133,2,113,1,161,146,216,250,133,2,114,1,161,243,138,171,183,10,195,1,1,161,146,216,250,133,2,116,1,161,146,216,250,133,2,117,1,161,146,216,250,133,2,118,1,161,243,138,171,183,10,199,1,1,161,146,216,250,133,2,120,1,161,146,216,250,133,2,121,1,161,146,216,250,133,2,122,1,161,146,216,250,133,2,131,1,2,161,146,216,250,133,2,124,1,161,146,216,250,133,2,125,1,161,146,216,250,133,2,126,1,161,146,216,250,133,2,128,1,1,161,146,216,250,133,2,129,1,1,161,146,216,250,133,2,130,1,1,161,243,138,171,183,10,208,1,1,161,146,216,250,133,2,132,1,1,161,146,216,250,133,2,133,1,1,161,146,216,250,133,2,134,1,1,161,146,216,250,133,2,143,1,1,161,146,216,250,133,2,136,1,1,161,146,216,250,133,2,137,1,1,161,146,216,250,133,2,138,1,1,161,243,138,171,183,10,219,1,1,161,146,216,250,133,2,140,1,1,161,146,216,250,133,2,141,1,1,161,146,216,250,133,2,142,1,1,161,243,138,171,183,10,223,1,1,161,146,216,250,133,2,144,1,1,161,146,216,250,133,2,145,1,1,161,146,216,250,133,2,146,1,1,161,146,216,250,133,2,155,1,1,161,146,216,250,133,2,148,1,1,161,146,216,250,133,2,149,1,1,161,146,216,250,133,2,150,1,1,161,243,138,171,183,10,231,1,1,161,146,216,250,133,2,152,1,1,161,146,216,250,133,2,153,1,1,161,146,216,250,133,2,154,1,1,161,243,138,171,183,10,235,1,1,168,146,216,250,133,2,156,1,1,119,68,123,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,119,105,100,116,104,34,58,49,53,48,46,56,53,53,52,54,56,55,53,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,125,168,146,216,250,133,2,157,1,1,119,68,123,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,119,105,100,116,104,34,58,49,48,53,46,48,53,48,55,56,49,50,53,125,168,146,216,250,133,2,158,1,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,125,161,146,216,250,133,2,167,1,3,168,146,216,250,133,2,160,1,1,119,68,123,34,119,105,100,116,104,34,58,49,53,48,46,56,53,53,52,54,56,55,53,44,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,125,168,146,216,250,133,2,161,1,1,119,68,123,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,119,105,100,116,104,34,58,49,48,53,46,48,53,48,55,56,49,50,53,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,125,168,146,216,250,133,2,162,1,1,119,60,123,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,56,48,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,125,168,146,216,250,133,2,164,1,1,119,68,123,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,49,53,48,46,56,53,53,52,54,56,55,53,44,34,104,101,105,103,104,116,34,58,52,48,46,48,125,168,146,216,250,133,2,165,1,1,119,68,123,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,49,48,53,46,48,53,48,55,56,49,50,53,44,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,125,168,146,216,250,133,2,166,1,1,119,60,123,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,104,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,56,48,46,48,125,1,132,236,218,251,9,0,161,218,255,204,32,20,14,1,131,128,202,229,9,0,168,243,138,171,183,10,245,1,1,119,114,123,34,99,111,108,68,101,102,97,117,108,116,87,105,100,116,104,34,58,56,48,46,48,44,34,99,111,108,115,72,101,105,103,104,116,34,58,49,50,56,46,48,44,34,99,111,108,115,76,101,110,34,58,51,44,34,99,111,108,77,105,110,105,109,117,109,87,105,100,116,104,34,58,52,48,46,48,44,34,114,111,119,68,101,102,97,117,108,116,72,101,105,103,104,116,34,58,52,48,46,48,44,34,114,111,119,115,76,101,110,34,58,51,125,1,219,200,174,197,9,0,161,161,234,157,145,5,6,25,3,207,231,154,196,9,0,168,204,195,206,156,1,209,1,1,119,101,123,34,105,109,97,103,101,95,116,121,112,101,34,58,34,49,34,44,34,99,111,118,101,114,95,115,101,108,101,99,116,105,111,110,95,116,121,112,101,34,58,34,67,111,118,101,114,84,121,112,101,46,99,111,108,111,114,34,44,34,100,101,108,116,97,34,58,91,93,44,34,99,111,118,101,114,95,115,101,108,101,99,116,105,111,110,34,58,34,48,120,102,102,101,56,101,48,102,102,34,125,168,204,195,206,156,1,210,1,1,119,10,112,70,113,76,55,45,79,83,121,86,168,204,195,206,156,1,211,1,1,119,4,116,101,120,116,1,241,147,239,232,6,0,161,245,181,155,135,2,22,4,1,150,152,188,203,6,0,161,192,246,139,213,2,34,20,2,181,156,253,158,6,0,161,198,223,206,159,1,175,1,4,168,181,156,253,158,6,3,1,119,231,1,123,34,117,114,108,34,58,34,104,116,116,112,115,58,47,47,105,109,97,103,101,115,46,117,110,115,112,108,97,115,104,46,99,111,109,47,112,104,111,116,111,45,49,55,49,50,51,48,51,55,48,48,56,51,50,45,53,55,100,50,98,50,98,57,49,54,98,56,63,99,114,111,112,61,101,110,116,114,111,112,121,38,99,115,61,116,105,110,121,115,114,103,98,38,102,105,116,61,109,97,120,38,102,109,61,106,112,103,38,105,120,105,100,61,77,51,119,49,77,84,69,49,77,122,100,56,77,72,119,120,102,72,74,104,98,109,82,118,98,88,120,56,102,72,120,56,102,72,120,56,102,68,69,51,77,84,77,121,78,84,107,122,78,84,100,56,38,105,120,108,105,98,61,114,98,45,52,46,48,46,51,38,113,61,56,48,38,119,61,49,48,56,48,34,44,34,119,105,100,116,104,34,58,52,50,56,46,49,57,53,51,49,50,53,44,34,97,108,105,103,110,34,58,34,114,105,103,104,116,34,125,220,2,171,236,222,251,5,0,198,204,195,206,156,1,205,4,204,195,206,156,1,206,4,4,98,111,108,100,4,116,114,117,101,196,171,236,222,251,5,0,204,195,206,156,1,206,4,4,112,97,103,101,198,171,236,222,251,5,4,204,195,206,156,1,206,4,4,98,111,108,100,4,110,117,108,108,168,204,195,206,156,1,119,1,119,222,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,43,32,78,101,119,32,80,97,103,101,32,34,125,44,123,34,105,110,115,101,114,116,34,58,34,98,117,116,116,111,110,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,111,102,32,121,111,117,114,32,115,105,100,101,98,97,114,32,116,111,32,97,100,100,32,97,32,110,101,119,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,98,111,108,100,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,112,97,103,101,34,125,44,123,34,105,110,115,101,114,116,34,58,34,46,34,125,93,44,34,99,104,101,99,107,101,100,34,58,116,114,117,101,125,168,204,195,206,156,1,120,1,119,10,122,77,121,109,67,97,118,83,107,102,168,204,195,206,156,1,121,1,119,4,116,101,120,116,193,204,195,206,156,1,129,6,204,195,206,156,1,130,6,5,198,171,236,222,251,5,13,204,195,206,156,1,130,6,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,204,195,206,156,1,11,1,161,204,195,206,156,1,12,1,161,204,195,206,156,1,13,1,161,171,236,222,251,5,15,1,161,171,236,222,251,5,16,1,161,171,236,222,251,5,17,1,193,204,195,206,156,1,129,6,171,236,222,251,5,9,5,198,171,236,222,251,5,25,171,236,222,251,5,9,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,18,1,161,171,236,222,251,5,19,1,161,171,236,222,251,5,20,1,193,204,195,206,156,1,129,6,171,236,222,251,5,21,5,198,171,236,222,251,5,34,171,236,222,251,5,21,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,27,1,161,171,236,222,251,5,28,1,161,171,236,222,251,5,29,1,198,204,195,206,156,1,129,6,171,236,222,251,5,30,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,100,98,51,54,51,54,34,193,171,236,222,251,5,39,171,236,222,251,5,30,4,198,171,236,222,251,5,43,171,236,222,251,5,30,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,36,1,161,171,236,222,251,5,37,1,161,171,236,222,251,5,38,1,193,171,236,222,251,5,39,171,236,222,251,5,40,5,198,171,236,222,251,5,52,171,236,222,251,5,40,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,45,1,161,171,236,222,251,5,46,1,161,171,236,222,251,5,47,1,193,171,236,222,251,5,39,171,236,222,251,5,48,5,198,171,236,222,251,5,61,171,236,222,251,5,48,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,54,1,161,171,236,222,251,5,55,1,161,171,236,222,251,5,56,1,198,171,236,222,251,5,39,171,236,222,251,5,57,8,98,103,95,99,111,108,111,114,12,34,48,120,102,102,102,102,100,97,101,54,34,196,171,236,222,251,5,66,171,236,222,251,5,57,4,110,101,120,116,198,171,236,222,251,5,70,171,236,222,251,5,57,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,63,1,161,171,236,222,251,5,64,1,161,171,236,222,251,5,65,1,198,204,195,206,156,1,180,6,204,195,206,156,1,181,6,9,117,110,100,101,114,108,105,110,101,4,116,114,117,101,193,171,236,222,251,5,75,204,195,206,156,1,181,6,3,198,171,236,222,251,5,78,204,195,206,156,1,181,6,9,117,110,100,101,114,108,105,110,101,4,110,117,108,108,161,171,236,222,251,5,72,1,161,171,236,222,251,5,73,1,161,171,236,222,251,5,74,1,198,171,236,222,251,5,75,171,236,222,251,5,76,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,116,114,117,101,193,171,236,222,251,5,83,171,236,222,251,5,76,3,198,171,236,222,251,5,86,171,236,222,251,5,76,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,110,117,108,108,161,171,236,222,251,5,80,1,161,171,236,222,251,5,81,1,161,171,236,222,251,5,82,1,198,171,236,222,251,5,83,171,236,222,251,5,84,6,105,116,97,108,105,99,4,116,114,117,101,193,171,236,222,251,5,91,171,236,222,251,5,84,3,198,171,236,222,251,5,94,171,236,222,251,5,84,6,105,116,97,108,105,99,4,110,117,108,108,161,171,236,222,251,5,88,1,161,171,236,222,251,5,89,1,161,171,236,222,251,5,90,1,196,171,236,222,251,5,94,171,236,222,251,5,95,9,230,140,168,233,161,191,230,137,147,161,171,236,222,251,5,96,1,161,171,236,222,251,5,97,1,161,171,236,222,251,5,98,1,39,0,204,195,206,156,1,4,6,68,89,98,118,73,66,2,33,0,204,195,206,156,1,1,6,109,57,74,107,49,75,1,0,7,33,0,204,195,206,156,1,3,6,78,76,50,70,103,95,1,193,204,195,206,156,1,238,1,204,195,206,156,1,239,1,1,168,171,236,222,251,5,102,1,119,204,5,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,43,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,98,103,95,99,111,108,111,114,34,58,34,48,120,102,102,102,102,100,97,101,54,34,44,34,102,111,110,116,95,99,111,108,111,114,34,58,34,48,120,102,102,100,98,51,54,51,54,34,125,44,34,105,110,115,101,114,116,34,58,34,110,101,120,116,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,116,111,32,97,110,121,32,112,97,103,101,32,116,105,116,108,101,32,105,110,32,116,104,101,32,115,105,100,101,98,97,114,32,116,111,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,99,111,108,111,114,34,58,34,48,120,102,102,56,52,50,55,101,48,34,125,44,34,105,110,115,101,114,116,34,58,34,113,117,105,99,107,108,121,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,105,116,97,108,105,99,34,58,116,114,117,101,44,34,115,116,114,105,107,101,116,104,114,111,117,103,104,34,58,116,114,117,101,44,34,117,110,100,101,114,108,105,110,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,230,140,168,233,161,191,230,137,147,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,97,32,110,101,119,32,115,117,98,112,97,103,101,44,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,68,111,99,117,109,101,110,116,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,102,97,108,115,101,125,44,34,105,110,115,101,114,116,34,58,34,44,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,71,114,105,100,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,102,97,108,115,101,125,44,34,105,110,115,101,114,116,34,58,34,44,32,111,114,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,75,97,110,98,97,110,32,66,111,97,114,100,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,102,97,108,115,101,125,44,34,105,110,115,101,114,116,34,58,34,46,34,125,93,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,168,171,236,222,251,5,103,1,119,10,98,113,76,109,98,57,111,45,109,109,168,171,236,222,251,5,104,1,119,4,116,101,120,116,39,0,204,195,206,156,1,4,6,68,53,45,65,82,65,2,33,0,204,195,206,156,1,1,6,89,87,119,55,87,53,1,0,7,33,0,204,195,206,156,1,3,6,85,68,79,77,112,98,1,1,0,204,195,206,156,1,14,1,39,0,204,195,206,156,1,4,6,107,90,52,97,119,69,2,33,0,204,195,206,156,1,1,6,108,79,120,55,95,83,1,0,7,33,0,204,195,206,156,1,3,6,50,109,115,116,117,104,1,193,171,236,222,251,5,115,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,52,98,104,66,88,113,2,33,0,204,195,206,156,1,1,6,121,105,115,116,115,72,1,0,7,33,0,204,195,206,156,1,3,6,53,67,71,119,50,122,1,129,171,236,222,251,5,129,1,1,39,0,204,195,206,156,1,4,6,87,105,113,49,48,95,2,33,0,204,195,206,156,1,1,6,71,121,98,79,49,81,1,0,7,33,0,204,195,206,156,1,3,6,66,90,69,117,90,106,1,193,171,236,222,251,5,129,1,171,236,222,251,5,151,1,1,39,0,204,195,206,156,1,4,6,106,101,65,53,90,85,2,39,0,204,195,206,156,1,1,6,102,67,65,65,81,117,1,40,0,171,236,222,251,5,164,1,2,105,100,1,119,6,102,67,65,65,81,117,40,0,171,236,222,251,5,164,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,171,236,222,251,5,164,1,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,164,1,8,99,104,105,108,100,114,101,110,1,119,6,52,74,88,112,120,108,33,0,171,236,222,251,5,164,1,4,100,97,116,97,1,40,0,171,236,222,251,5,164,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,164,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,52,74,88,112,120,108,0,200,171,236,222,251,5,129,1,171,236,222,251,5,162,1,1,119,6,102,67,65,65,81,117,4,0,171,236,222,251,5,163,1,6,228,189,147,233,170,140,129,171,236,222,251,5,175,1,1,161,171,236,222,251,5,169,1,1,198,171,236,222,251,5,175,1,171,236,222,251,5,176,1,9,117,110,100,101,114,108,105,110,101,4,116,114,117,101,193,171,236,222,251,5,178,1,171,236,222,251,5,176,1,1,198,171,236,222,251,5,179,1,171,236,222,251,5,176,1,9,117,110,100,101,114,108,105,110,101,4,110,117,108,108,161,171,236,222,251,5,177,1,1,198,171,236,222,251,5,178,1,171,236,222,251,5,179,1,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,116,114,117,101,196,171,236,222,251,5,182,1,171,236,222,251,5,179,1,3,228,184,128,198,171,236,222,251,5,183,1,171,236,222,251,5,179,1,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,110,117,108,108,168,171,236,222,251,5,181,1,1,119,101,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,228,189,147,233,170,140,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,115,116,114,105,107,101,116,104,114,111,117,103,104,34,58,116,114,117,101,44,34,117,110,100,101,114,108,105,110,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,228,184,128,34,125,93,125,39,0,204,195,206,156,1,4,6,82,74,108,100,72,67,2,33,0,204,195,206,156,1,1,6,53,106,100,78,87,117,1,0,7,33,0,204,195,206,156,1,3,6,67,106,107,76,57,108,1,129,171,236,222,251,5,151,1,1,4,0,171,236,222,251,5,186,1,4,103,104,104,104,0,1,39,0,204,195,206,156,1,4,6,70,117,117,52,113,66,2,4,0,171,236,222,251,5,202,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,121,112,70,119,50,69,1,0,7,33,0,204,195,206,156,1,3,6,71,77,54,72,55,119,1,193,171,236,222,251,5,151,1,171,236,222,251,5,196,1,1,39,0,204,195,206,156,1,4,6,118,113,76,104,110,70,2,4,0,171,236,222,251,5,217,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,73,57,73,75,116,115,1,0,7,33,0,204,195,206,156,1,3,6,77,114,102,81,106,87,1,193,171,236,222,251,5,140,1,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,89,50,52,104,77,55,2,4,0,171,236,222,251,5,232,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,107,110,74,87,104,48,1,0,7,33,0,204,195,206,156,1,3,6,55,99,67,68,120,77,1,129,171,236,222,251,5,196,1,1,0,7,39,0,204,195,206,156,1,4,6,109,98,56,104,95,45,2,4,0,171,236,222,251,5,254,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,103,75,73,116,90,101,1,0,7,33,0,204,195,206,156,1,3,6,118,115,54,50,82,105,1,193,171,236,222,251,5,196,1,171,236,222,251,5,246,1,1,39,0,204,195,206,156,1,4,6,105,67,98,56,102,56,2,4,0,171,236,222,251,5,141,2,4,103,104,104,104,33,0,204,195,206,156,1,1,6,88,113,72,53,122,82,1,0,7,33,0,204,195,206,156,1,3,6,73,111,48,108,119,67,1,193,171,236,222,251,5,196,1,171,236,222,251,5,140,2,1,39,0,204,195,206,156,1,4,6,82,89,116,67,111,86,2,4,0,171,236,222,251,5,156,2,4,103,104,104,104,39,0,204,195,206,156,1,1,6,49,120,78,111,50,76,1,40,0,171,236,222,251,5,161,2,2,105,100,1,119,6,49,120,78,111,50,76,40,0,171,236,222,251,5,161,2,2,116,121,1,119,5,113,117,111,116,101,40,0,171,236,222,251,5,161,2,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,161,2,8,99,104,105,108,100,114,101,110,1,119,6,67,85,68,115,45,70,33,0,171,236,222,251,5,161,2,4,100,97,116,97,1,40,0,171,236,222,251,5,161,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,161,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,67,85,68,115,45,70,0,200,171,236,222,251,5,196,1,171,236,222,251,5,155,2,1,119,6,49,120,78,111,50,76,39,0,204,195,206,156,1,4,6,122,112,90,112,49,101,2,33,0,204,195,206,156,1,1,6,109,65,112,48,84,75,1,0,7,33,0,204,195,206,156,1,3,6,117,95,113,85,121,95,1,129,171,236,222,251,5,246,1,1,4,0,171,236,222,251,5,171,2,4,104,106,106,106,0,1,39,0,204,195,206,156,1,4,6,79,88,120,110,65,84,2,4,0,171,236,222,251,5,187,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,109,70,99,75,110,81,1,0,7,33,0,204,195,206,156,1,3,6,72,52,122,104,56,95,1,193,171,236,222,251,5,246,1,171,236,222,251,5,181,2,1,39,0,204,195,206,156,1,4,6,90,97,54,99,87,113,2,4,0,171,236,222,251,5,202,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,50,110,113,71,98,75,1,0,7,33,0,204,195,206,156,1,3,6,95,69,69,76,53,109,1,193,171,236,222,251,5,246,1,171,236,222,251,5,201,2,1,39,0,204,195,206,156,1,4,6,95,88,107,52,56,116,2,4,0,171,236,222,251,5,217,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,68,99,97,85,109,79,1,0,7,33,0,204,195,206,156,1,3,6,120,69,54,111,108,48,1,193,171,236,222,251,5,231,1,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,82,106,87,98,56,111,2,4,0,171,236,222,251,5,232,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,87,98,82,107,87,69,1,0,7,33,0,204,195,206,156,1,3,6,89,103,114,112,81,55,1,129,171,236,222,251,5,181,2,1,39,0,204,195,206,156,1,4,6,112,107,78,57,112,83,2,4,0,171,236,222,251,5,247,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,79,98,74,118,76,57,1,0,7,33,0,204,195,206,156,1,3,6,97,79,100,49,121,82,1,193,171,236,222,251,5,181,2,171,236,222,251,5,246,2,1,39,0,204,195,206,156,1,4,6,99,51,100,115,103,56,2,4,0,171,236,222,251,5,134,3,4,104,106,106,106,33,0,204,195,206,156,1,1,6,109,119,79,85,85,87,1,0,7,33,0,204,195,206,156,1,3,6,98,70,74,53,121,122,1,193,171,236,222,251,5,181,2,171,236,222,251,5,133,3,1,39,0,204,195,206,156,1,4,6,104,82,53,106,71,79,2,1,0,171,236,222,251,5,149,3,4,33,0,204,195,206,156,1,1,6,73,77,51,71,72,50,1,0,7,33,0,204,195,206,156,1,3,6,119,85,111,112,97,102,1,193,171,236,222,251,5,181,2,171,236,222,251,5,148,3,1,0,4,39,0,204,195,206,156,1,4,6,74,66,108,114,84,51,2,33,0,204,195,206,156,1,1,6,76,105,86,56,56,104,1,0,7,33,0,204,195,206,156,1,3,6,112,106,107,107,53,97,1,193,171,236,222,251,5,181,2,171,236,222,251,5,163,3,1,1,0,171,236,222,251,5,168,3,1,0,2,129,171,236,222,251,5,179,3,1,0,1,196,171,236,222,251,5,179,3,171,236,222,251,5,182,3,3,226,128,148,0,1,39,0,204,195,206,156,1,4,6,89,108,67,77,99,111,2,39,0,204,195,206,156,1,1,6,112,69,80,105,117,115,1,40,0,171,236,222,251,5,187,3,2,105,100,1,119,6,112,69,80,105,117,115,40,0,171,236,222,251,5,187,3,2,116,121,1,119,7,100,105,118,105,100,101,114,40,0,171,236,222,251,5,187,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,187,3,8,99,104,105,108,100,114,101,110,1,119,6,49,45,49,107,111,85,40,0,171,236,222,251,5,187,3,4,100,97,116,97,1,119,2,123,125,40,0,171,236,222,251,5,187,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,187,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,49,45,49,107,111,85,0,200,171,236,222,251,5,181,2,171,236,222,251,5,178,3,1,119,6,112,69,80,105,117,115,39,0,204,195,206,156,1,1,6,95,65,78,99,110,51,1,40,0,171,236,222,251,5,197,3,2,105,100,1,119,6,95,65,78,99,110,51,40,0,171,236,222,251,5,197,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,171,236,222,251,5,197,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,197,3,8,99,104,105,108,100,114,101,110,1,119,6,84,45,117,87,109,83,33,0,171,236,222,251,5,197,3,4,100,97,116,97,1,40,0,171,236,222,251,5,197,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,197,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,84,45,117,87,109,83,0,136,171,236,222,251,5,246,2,1,119,6,95,65,78,99,110,51,4,0,171,236,222,251,5,186,3,1,54,161,171,236,222,251,5,202,3,1,132,171,236,222,251,5,207,3,1,54,161,171,236,222,251,5,208,3,1,132,171,236,222,251,5,209,3,1,54,161,171,236,222,251,5,210,3,1,132,171,236,222,251,5,211,3,1,57,168,171,236,222,251,5,212,3,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,54,54,54,57,34,125,93,125,39,0,204,195,206,156,1,1,6,79,77,79,95,52,106,1,40,0,171,236,222,251,5,215,3,2,105,100,1,119,6,79,77,79,95,52,106,40,0,171,236,222,251,5,215,3,2,116,121,1,119,7,100,105,118,105,100,101,114,40,0,171,236,222,251,5,215,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,215,3,8,99,104,105,108,100,114,101,110,1,119,6,99,107,78,65,119,105,40,0,171,236,222,251,5,215,3,4,100,97,116,97,1,119,2,123,125,40,0,171,236,222,251,5,215,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,215,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,99,107,78,65,119,105,0,200,171,236,222,251,5,246,2,171,236,222,251,5,206,3,1,119,6,79,77,79,95,52,106,39,0,204,195,206,156,1,4,6,45,80,118,95,90,87,2,4,0,171,236,222,251,5,225,3,4,103,104,104,104,39,0,204,195,206,156,1,4,6,87,105,54,69,77,70,2,4,0,171,236,222,251,5,230,3,4,54,54,54,57,39,0,204,195,206,156,1,1,6,122,78,116,118,66,84,1,40,0,171,236,222,251,5,235,3,2,105,100,1,119,6,122,78,116,118,66,84,40,0,171,236,222,251,5,235,3,2,116,121,1,119,5,113,117,111,116,101,40,0,171,236,222,251,5,235,3,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,171,236,222,251,5,235,3,8,99,104,105,108,100,114,101,110,1,119,6,105,85,75,111,98,79,33,0,171,236,222,251,5,235,3,4,100,97,116,97,1,40,0,171,236,222,251,5,235,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,235,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,105,85,75,111,98,79,0,200,171,236,222,251,5,231,2,204,195,206,156,1,239,1,1,119,6,122,78,116,118,66,84,33,0,204,195,206,156,1,1,6,57,104,76,90,119,104,1,0,7,33,0,204,195,206,156,1,3,6,120,113,118,100,85,73,1,193,171,236,222,251,5,244,3,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,75,122,88,45,65,53,2,1,0,171,236,222,251,5,255,3,4,39,0,204,195,206,156,1,1,6,49,51,100,105,49,69,1,40,0,171,236,222,251,5,132,4,2,105,100,1,119,6,49,51,100,105,49,69,40,0,171,236,222,251,5,132,4,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,171,236,222,251,5,132,4,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,171,236,222,251,5,132,4,8,99,104,105,108,100,114,101,110,1,119,6,106,54,115,52,103,109,33,0,171,236,222,251,5,132,4,4,100,97,116,97,1,40,0,171,236,222,251,5,132,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,132,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,54,115,52,103,109,0,200,171,236,222,251,5,244,3,171,236,222,251,5,254,3,1,119,6,49,51,100,105,49,69,161,171,236,222,251,5,137,4,2,65,171,236,222,251,5,128,4,5,198,171,236,222,251,5,148,4,171,236,222,251,5,128,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,143,4,1,65,171,236,222,251,5,144,4,5,198,171,236,222,251,5,155,4,171,236,222,251,5,144,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,150,4,1,65,171,236,222,251,5,151,4,5,198,171,236,222,251,5,162,4,171,236,222,251,5,151,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,157,4,1,65,171,236,222,251,5,158,4,5,198,171,236,222,251,5,169,4,171,236,222,251,5,158,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,164,4,1,65,171,236,222,251,5,165,4,5,198,171,236,222,251,5,176,4,171,236,222,251,5,165,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,171,4,1,65,171,236,222,251,5,172,4,5,198,171,236,222,251,5,183,4,171,236,222,251,5,172,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,178,4,1,65,171,236,222,251,5,179,4,5,198,171,236,222,251,5,190,4,171,236,222,251,5,179,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,185,4,1,65,171,236,222,251,5,186,4,5,198,171,236,222,251,5,197,4,171,236,222,251,5,186,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,192,4,1,70,171,236,222,251,5,193,4,8,98,103,95,99,111,108,111,114,12,34,48,120,102,102,102,102,100,97,101,54,34,193,171,236,222,251,5,200,4,171,236,222,251,5,193,4,4,198,171,236,222,251,5,204,4,171,236,222,251,5,193,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,199,4,2,193,171,236,222,251,5,200,4,171,236,222,251,5,201,4,5,198,171,236,222,251,5,212,4,171,236,222,251,5,201,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,207,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,208,4,5,198,171,236,222,251,5,219,4,171,236,222,251,5,208,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,214,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,215,4,5,198,171,236,222,251,5,226,4,171,236,222,251,5,215,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,221,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,222,4,5,198,171,236,222,251,5,233,4,171,236,222,251,5,222,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,228,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,229,4,5,198,171,236,222,251,5,240,4,171,236,222,251,5,229,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,235,4,1,70,171,236,222,251,5,200,4,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,101,97,56,102,48,54,34,198,171,236,222,251,5,243,4,171,236,222,251,5,200,4,8,98,103,95,99,111,108,111,114,12,34,48,120,102,102,97,55,100,102,52,97,34,196,171,236,222,251,5,244,4,171,236,222,251,5,200,4,4,54,54,54,57,193,171,236,222,251,5,248,4,171,236,222,251,5,200,4,1,198,171,236,222,251,5,249,4,171,236,222,251,5,200,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,168,171,236,222,251,5,242,4,1,119,110,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,98,103,95,99,111,108,111,114,34,58,34,48,120,102,102,97,55,100,102,52,97,34,44,34,102,111,110,116,95,99,111,108,111,114,34,58,34,48,120,102,102,101,97,56,102,48,54,34,125,44,34,105,110,115,101,114,116,34,58,34,54,54,54,57,34,125,93,125,7,226,167,254,250,5,0,39,0,204,195,206,156,1,4,6,72,97,87,55,95,104,2,4,0,226,167,254,250,5,0,13,229,144,140,228,184,128,228,184,170,106,106,106,56,161,198,223,206,159,1,124,1,132,226,167,254,250,5,7,1,56,161,226,167,254,250,5,8,1,132,226,167,254,250,5,9,1,56,161,226,167,254,250,5,10,1,1,161,234,157,145,5,0,161,247,212,219,208,10,45,7,1,136,172,186,168,4,0,161,176,238,158,139,14,174,2,182,6,4,217,168,198,159,4,0,129,204,195,206,156,1,154,7,4,161,204,195,206,156,1,227,1,1,161,204,195,206,156,1,228,1,1,161,204,195,206,156,1,229,1,1,215,6,150,216,171,142,3,0,161,199,130,209,189,2,177,3,6,161,164,202,219,213,10,80,1,161,164,202,219,213,10,81,1,161,164,202,219,213,10,82,1,161,150,216,171,142,3,6,1,161,150,216,171,142,3,7,1,161,150,216,171,142,3,8,1,129,204,195,206,156,1,207,5,1,161,150,216,171,142,3,9,1,161,150,216,171,142,3,10,1,161,150,216,171,142,3,11,1,129,150,216,171,142,3,12,1,161,150,216,171,142,3,13,1,161,150,216,171,142,3,14,1,161,150,216,171,142,3,15,1,161,150,216,171,142,3,17,1,161,150,216,171,142,3,18,1,161,150,216,171,142,3,19,1,161,150,216,171,142,3,20,1,161,150,216,171,142,3,21,1,161,150,216,171,142,3,22,1,129,150,216,171,142,3,16,1,161,150,216,171,142,3,23,1,161,150,216,171,142,3,24,1,161,150,216,171,142,3,25,1,129,150,216,171,142,3,26,1,161,150,216,171,142,3,27,1,161,150,216,171,142,3,28,1,161,150,216,171,142,3,29,1,129,150,216,171,142,3,30,1,161,150,216,171,142,3,31,1,161,150,216,171,142,3,32,1,161,150,216,171,142,3,33,1,129,150,216,171,142,3,34,1,161,150,216,171,142,3,35,1,161,150,216,171,142,3,36,1,161,150,216,171,142,3,37,1,129,150,216,171,142,3,38,1,161,150,216,171,142,3,39,1,161,150,216,171,142,3,40,1,161,150,216,171,142,3,41,1,129,150,216,171,142,3,42,1,161,150,216,171,142,3,43,1,161,150,216,171,142,3,44,1,161,150,216,171,142,3,45,1,129,150,216,171,142,3,46,1,161,150,216,171,142,3,47,1,161,150,216,171,142,3,48,1,161,150,216,171,142,3,49,1,129,150,216,171,142,3,50,1,161,150,216,171,142,3,51,1,161,150,216,171,142,3,52,1,161,150,216,171,142,3,53,1,129,150,216,171,142,3,54,1,161,150,216,171,142,3,55,1,161,150,216,171,142,3,56,1,161,150,216,171,142,3,57,1,129,150,216,171,142,3,58,1,161,150,216,171,142,3,59,1,161,150,216,171,142,3,60,1,161,150,216,171,142,3,61,1,129,150,216,171,142,3,62,1,161,150,216,171,142,3,63,1,161,150,216,171,142,3,64,1,161,150,216,171,142,3,65,1,129,150,216,171,142,3,66,1,161,150,216,171,142,3,67,1,161,150,216,171,142,3,68,1,161,150,216,171,142,3,69,1,129,150,216,171,142,3,70,1,161,150,216,171,142,3,71,1,161,150,216,171,142,3,72,1,161,150,216,171,142,3,73,1,129,150,216,171,142,3,74,1,161,150,216,171,142,3,75,1,161,150,216,171,142,3,76,1,161,150,216,171,142,3,77,1,129,150,216,171,142,3,78,1,161,150,216,171,142,3,79,1,161,150,216,171,142,3,80,1,161,150,216,171,142,3,81,1,129,150,216,171,142,3,82,1,161,150,216,171,142,3,83,1,161,150,216,171,142,3,84,1,161,150,216,171,142,3,85,1,129,150,216,171,142,3,86,1,161,150,216,171,142,3,87,1,161,150,216,171,142,3,88,1,161,150,216,171,142,3,89,1,129,150,216,171,142,3,90,1,161,150,216,171,142,3,91,1,161,150,216,171,142,3,92,1,161,150,216,171,142,3,93,1,129,150,216,171,142,3,94,1,161,150,216,171,142,3,95,1,161,150,216,171,142,3,96,1,161,150,216,171,142,3,97,1,129,150,216,171,142,3,98,1,161,150,216,171,142,3,99,1,161,150,216,171,142,3,100,1,161,150,216,171,142,3,101,1,129,150,216,171,142,3,102,1,161,150,216,171,142,3,103,1,161,150,216,171,142,3,104,1,161,150,216,171,142,3,105,1,129,150,216,171,142,3,106,1,161,150,216,171,142,3,107,1,161,150,216,171,142,3,108,1,161,150,216,171,142,3,109,1,129,150,216,171,142,3,110,1,161,150,216,171,142,3,111,1,161,150,216,171,142,3,112,1,161,150,216,171,142,3,113,1,129,150,216,171,142,3,114,1,161,150,216,171,142,3,115,1,161,150,216,171,142,3,116,1,161,150,216,171,142,3,117,1,129,150,216,171,142,3,118,1,161,150,216,171,142,3,119,1,161,150,216,171,142,3,120,1,161,150,216,171,142,3,121,1,129,150,216,171,142,3,122,1,161,150,216,171,142,3,123,1,161,150,216,171,142,3,124,1,161,150,216,171,142,3,125,1,129,150,216,171,142,3,126,1,161,150,216,171,142,3,127,1,161,150,216,171,142,3,128,1,1,161,150,216,171,142,3,129,1,1,129,150,216,171,142,3,130,1,1,161,150,216,171,142,3,131,1,1,161,150,216,171,142,3,132,1,1,161,150,216,171,142,3,133,1,1,129,150,216,171,142,3,134,1,1,161,150,216,171,142,3,135,1,1,161,150,216,171,142,3,136,1,1,161,150,216,171,142,3,137,1,1,193,150,216,171,142,3,134,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,139,1,1,161,150,216,171,142,3,140,1,1,161,150,216,171,142,3,141,1,1,193,150,216,171,142,3,142,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,143,1,1,161,150,216,171,142,3,144,1,1,161,150,216,171,142,3,145,1,1,193,150,216,171,142,3,146,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,147,1,1,161,150,216,171,142,3,148,1,1,161,150,216,171,142,3,149,1,1,193,150,216,171,142,3,150,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,151,1,1,161,150,216,171,142,3,152,1,1,161,150,216,171,142,3,153,1,1,193,150,216,171,142,3,154,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,155,1,1,161,150,216,171,142,3,156,1,1,161,150,216,171,142,3,157,1,1,193,150,216,171,142,3,158,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,159,1,1,161,150,216,171,142,3,160,1,1,161,150,216,171,142,3,161,1,1,193,150,216,171,142,3,162,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,163,1,1,161,150,216,171,142,3,164,1,1,161,150,216,171,142,3,165,1,1,193,150,216,171,142,3,166,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,167,1,1,161,150,216,171,142,3,168,1,1,161,150,216,171,142,3,169,1,1,193,150,216,171,142,3,170,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,171,1,1,161,150,216,171,142,3,172,1,1,161,150,216,171,142,3,173,1,1,193,150,216,171,142,3,174,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,175,1,1,161,150,216,171,142,3,176,1,1,161,150,216,171,142,3,177,1,1,193,150,216,171,142,3,178,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,179,1,1,161,150,216,171,142,3,180,1,1,161,150,216,171,142,3,181,1,1,193,150,216,171,142,3,182,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,183,1,1,161,150,216,171,142,3,184,1,1,161,150,216,171,142,3,185,1,1,129,150,216,171,142,3,138,1,4,161,150,216,171,142,3,187,1,1,161,150,216,171,142,3,188,1,1,161,150,216,171,142,3,189,1,1,129,150,216,171,142,3,193,1,1,161,150,216,171,142,3,194,1,1,161,150,216,171,142,3,195,1,1,161,150,216,171,142,3,196,1,1,161,150,216,171,142,3,198,1,1,161,150,216,171,142,3,199,1,1,161,150,216,171,142,3,200,1,1,161,150,216,171,142,3,201,1,1,161,150,216,171,142,3,202,1,1,161,150,216,171,142,3,203,1,1,161,150,216,171,142,3,204,1,1,161,150,216,171,142,3,205,1,1,161,150,216,171,142,3,206,1,1,129,150,216,171,142,3,197,1,1,161,150,216,171,142,3,207,1,1,161,150,216,171,142,3,208,1,1,161,150,216,171,142,3,209,1,1,129,150,216,171,142,3,210,1,1,161,150,216,171,142,3,211,1,1,161,150,216,171,142,3,212,1,1,161,150,216,171,142,3,213,1,1,129,150,216,171,142,3,214,1,1,161,150,216,171,142,3,215,1,1,161,150,216,171,142,3,216,1,1,161,150,216,171,142,3,217,1,1,129,150,216,171,142,3,218,1,1,161,150,216,171,142,3,219,1,1,161,150,216,171,142,3,220,1,1,161,150,216,171,142,3,221,1,1,129,150,216,171,142,3,222,1,1,161,150,216,171,142,3,223,1,1,161,150,216,171,142,3,224,1,1,161,150,216,171,142,3,225,1,1,129,150,216,171,142,3,226,1,1,161,150,216,171,142,3,227,1,1,161,150,216,171,142,3,228,1,1,161,150,216,171,142,3,229,1,1,129,150,216,171,142,3,230,1,1,161,150,216,171,142,3,231,1,1,161,150,216,171,142,3,232,1,1,161,150,216,171,142,3,233,1,1,129,150,216,171,142,3,234,1,1,161,150,216,171,142,3,235,1,1,161,150,216,171,142,3,236,1,1,161,150,216,171,142,3,237,1,1,129,150,216,171,142,3,238,1,1,161,150,216,171,142,3,239,1,1,161,150,216,171,142,3,240,1,1,161,150,216,171,142,3,241,1,1,129,150,216,171,142,3,242,1,1,161,150,216,171,142,3,243,1,1,161,150,216,171,142,3,244,1,1,161,150,216,171,142,3,245,1,1,129,150,216,171,142,3,246,1,1,161,150,216,171,142,3,247,1,1,161,150,216,171,142,3,248,1,1,161,150,216,171,142,3,249,1,1,129,150,216,171,142,3,250,1,1,161,150,216,171,142,3,251,1,1,161,150,216,171,142,3,252,1,1,161,150,216,171,142,3,253,1,1,129,150,216,171,142,3,254,1,1,161,150,216,171,142,3,255,1,1,161,150,216,171,142,3,128,2,1,161,150,216,171,142,3,129,2,1,129,150,216,171,142,3,130,2,1,161,150,216,171,142,3,131,2,1,161,150,216,171,142,3,132,2,1,161,150,216,171,142,3,133,2,1,129,150,216,171,142,3,134,2,1,161,150,216,171,142,3,135,2,1,161,150,216,171,142,3,136,2,1,161,150,216,171,142,3,137,2,1,129,150,216,171,142,3,138,2,1,161,150,216,171,142,3,139,2,1,161,150,216,171,142,3,140,2,1,161,150,216,171,142,3,141,2,1,161,150,216,171,142,3,143,2,1,161,150,216,171,142,3,144,2,1,161,150,216,171,142,3,145,2,1,129,150,216,171,142,3,142,2,1,161,150,216,171,142,3,146,2,1,161,150,216,171,142,3,147,2,1,161,150,216,171,142,3,148,2,1,161,150,216,171,142,3,150,2,1,161,150,216,171,142,3,151,2,1,161,150,216,171,142,3,152,2,1,161,150,216,171,142,3,153,2,1,161,150,216,171,142,3,154,2,1,161,150,216,171,142,3,155,2,1,161,150,216,171,142,3,156,2,1,161,150,216,171,142,3,157,2,1,161,150,216,171,142,3,158,2,1,129,150,216,171,142,3,149,2,1,161,150,216,171,142,3,159,2,1,161,150,216,171,142,3,160,2,1,161,150,216,171,142,3,161,2,1,129,150,216,171,142,3,162,2,1,161,150,216,171,142,3,163,2,1,161,150,216,171,142,3,164,2,1,161,150,216,171,142,3,165,2,1,129,150,216,171,142,3,166,2,1,161,150,216,171,142,3,167,2,1,161,150,216,171,142,3,168,2,1,161,150,216,171,142,3,169,2,1,129,150,216,171,142,3,170,2,1,161,150,216,171,142,3,171,2,1,161,150,216,171,142,3,172,2,1,161,150,216,171,142,3,173,2,1,129,150,216,171,142,3,174,2,1,161,150,216,171,142,3,175,2,1,161,150,216,171,142,3,176,2,1,161,150,216,171,142,3,177,2,1,129,150,216,171,142,3,178,2,1,161,150,216,171,142,3,179,2,1,161,150,216,171,142,3,180,2,1,161,150,216,171,142,3,181,2,1,129,150,216,171,142,3,182,2,1,161,150,216,171,142,3,183,2,1,161,150,216,171,142,3,184,2,1,161,150,216,171,142,3,185,2,1,129,150,216,171,142,3,186,2,1,161,150,216,171,142,3,187,2,1,161,150,216,171,142,3,188,2,1,161,150,216,171,142,3,189,2,1,129,150,216,171,142,3,190,2,1,161,150,216,171,142,3,191,2,1,161,150,216,171,142,3,192,2,1,161,150,216,171,142,3,193,2,1,129,150,216,171,142,3,194,2,1,161,150,216,171,142,3,195,2,1,161,150,216,171,142,3,196,2,1,161,150,216,171,142,3,197,2,1,129,150,216,171,142,3,198,2,1,161,150,216,171,142,3,199,2,1,161,150,216,171,142,3,200,2,1,161,150,216,171,142,3,201,2,1,193,150,216,171,142,3,198,2,150,216,171,142,3,202,2,1,161,150,216,171,142,3,203,2,1,161,150,216,171,142,3,204,2,1,161,150,216,171,142,3,205,2,1,193,150,216,171,142,3,206,2,150,216,171,142,3,202,2,1,161,150,216,171,142,3,207,2,1,161,150,216,171,142,3,208,2,1,161,150,216,171,142,3,209,2,1,193,150,216,171,142,3,206,2,150,216,171,142,3,210,2,2,161,150,216,171,142,3,211,2,1,161,150,216,171,142,3,212,2,1,161,150,216,171,142,3,213,2,1,193,150,216,171,142,3,215,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,216,2,1,161,150,216,171,142,3,217,2,1,161,150,216,171,142,3,218,2,1,193,150,216,171,142,3,219,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,220,2,1,161,150,216,171,142,3,221,2,1,161,150,216,171,142,3,222,2,1,193,150,216,171,142,3,223,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,224,2,1,161,150,216,171,142,3,225,2,1,161,150,216,171,142,3,226,2,1,193,150,216,171,142,3,227,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,228,2,1,161,150,216,171,142,3,229,2,1,161,150,216,171,142,3,230,2,1,193,150,216,171,142,3,231,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,232,2,1,161,150,216,171,142,3,233,2,1,161,150,216,171,142,3,234,2,1,193,150,216,171,142,3,235,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,236,2,1,161,150,216,171,142,3,237,2,1,161,150,216,171,142,3,238,2,1,193,150,216,171,142,3,239,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,240,2,1,161,150,216,171,142,3,241,2,1,161,150,216,171,142,3,242,2,1,193,150,216,171,142,3,243,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,244,2,1,161,150,216,171,142,3,245,2,1,161,150,216,171,142,3,246,2,1,193,150,216,171,142,3,247,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,248,2,1,161,150,216,171,142,3,249,2,1,161,150,216,171,142,3,250,2,1,193,150,216,171,142,3,247,2,150,216,171,142,3,251,2,1,161,150,216,171,142,3,252,2,1,161,150,216,171,142,3,253,2,1,161,150,216,171,142,3,254,2,1,193,150,216,171,142,3,255,2,150,216,171,142,3,251,2,1,161,150,216,171,142,3,128,3,1,161,150,216,171,142,3,129,3,1,161,150,216,171,142,3,130,3,1,193,150,216,171,142,3,255,2,150,216,171,142,3,131,3,1,161,150,216,171,142,3,132,3,1,161,150,216,171,142,3,133,3,1,161,150,216,171,142,3,134,3,1,193,150,216,171,142,3,135,3,150,216,171,142,3,131,3,1,161,150,216,171,142,3,136,3,1,161,150,216,171,142,3,137,3,1,161,150,216,171,142,3,138,3,1,193,150,216,171,142,3,139,3,150,216,171,142,3,131,3,1,161,150,216,171,142,3,140,3,1,161,150,216,171,142,3,141,3,1,161,150,216,171,142,3,142,3,1,161,150,216,171,142,3,144,3,1,161,150,216,171,142,3,145,3,1,161,150,216,171,142,3,146,3,1,193,204,195,206,156,1,130,5,204,195,206,156,1,131,5,1,161,150,216,171,142,3,147,3,1,161,150,216,171,142,3,148,3,1,161,150,216,171,142,3,149,3,1,129,150,216,171,142,3,202,2,1,161,150,216,171,142,3,151,3,1,161,150,216,171,142,3,152,3,1,161,150,216,171,142,3,153,3,1,129,150,216,171,142,3,154,3,1,161,150,216,171,142,3,155,3,1,161,150,216,171,142,3,156,3,1,161,150,216,171,142,3,157,3,1,161,150,216,171,142,3,159,3,1,161,150,216,171,142,3,160,3,1,161,150,216,171,142,3,161,3,1,161,150,216,171,142,3,162,3,1,161,150,216,171,142,3,163,3,1,161,150,216,171,142,3,164,3,1,161,150,216,171,142,3,165,3,1,161,150,216,171,142,3,166,3,1,161,150,216,171,142,3,167,3,1,132,150,216,171,142,3,158,3,1,102,161,150,216,171,142,3,168,3,1,161,150,216,171,142,3,169,3,1,161,150,216,171,142,3,170,3,1,132,150,216,171,142,3,171,3,1,117,161,150,216,171,142,3,172,3,1,161,150,216,171,142,3,173,3,1,161,150,216,171,142,3,174,3,1,132,150,216,171,142,3,175,3,1,110,161,150,216,171,142,3,176,3,1,161,150,216,171,142,3,177,3,1,161,150,216,171,142,3,178,3,1,132,150,216,171,142,3,179,3,1,99,161,150,216,171,142,3,180,3,1,161,150,216,171,142,3,181,3,1,161,150,216,171,142,3,182,3,1,132,150,216,171,142,3,183,3,1,116,161,150,216,171,142,3,184,3,1,161,150,216,171,142,3,185,3,1,161,150,216,171,142,3,186,3,1,132,150,216,171,142,3,187,3,1,105,161,150,216,171,142,3,188,3,1,161,150,216,171,142,3,189,3,1,161,150,216,171,142,3,190,3,1,132,150,216,171,142,3,191,3,1,111,161,150,216,171,142,3,192,3,1,161,150,216,171,142,3,193,3,1,161,150,216,171,142,3,194,3,1,132,150,216,171,142,3,195,3,1,110,161,150,216,171,142,3,196,3,1,161,150,216,171,142,3,197,3,1,161,150,216,171,142,3,198,3,1,132,150,216,171,142,3,199,3,1,32,161,150,216,171,142,3,200,3,1,161,150,216,171,142,3,201,3,1,161,150,216,171,142,3,202,3,1,132,150,216,171,142,3,203,3,1,109,161,150,216,171,142,3,204,3,1,161,150,216,171,142,3,205,3,1,161,150,216,171,142,3,206,3,1,132,150,216,171,142,3,207,3,1,97,161,150,216,171,142,3,208,3,1,161,150,216,171,142,3,209,3,1,161,150,216,171,142,3,210,3,1,132,150,216,171,142,3,211,3,1,105,161,150,216,171,142,3,212,3,1,161,150,216,171,142,3,213,3,1,161,150,216,171,142,3,214,3,1,132,150,216,171,142,3,215,3,1,110,161,150,216,171,142,3,216,3,1,161,150,216,171,142,3,217,3,1,161,150,216,171,142,3,218,3,1,132,150,216,171,142,3,219,3,1,40,161,150,216,171,142,3,220,3,1,161,150,216,171,142,3,221,3,1,161,150,216,171,142,3,222,3,1,132,150,216,171,142,3,223,3,1,41,161,150,216,171,142,3,224,3,1,161,150,216,171,142,3,225,3,1,161,150,216,171,142,3,226,3,1,132,150,216,171,142,3,227,3,1,32,161,150,216,171,142,3,228,3,1,161,150,216,171,142,3,229,3,1,161,150,216,171,142,3,230,3,1,132,150,216,171,142,3,231,3,1,123,161,150,216,171,142,3,232,3,1,161,150,216,171,142,3,233,3,1,161,150,216,171,142,3,234,3,1,132,150,216,171,142,3,235,3,1,125,161,150,216,171,142,3,236,3,1,161,150,216,171,142,3,237,3,1,161,150,216,171,142,3,238,3,1,196,150,216,171,142,3,235,3,150,216,171,142,3,239,3,1,10,161,150,216,171,142,3,240,3,1,161,150,216,171,142,3,241,3,1,161,150,216,171,142,3,242,3,1,196,150,216,171,142,3,243,3,150,216,171,142,3,239,3,1,10,161,150,216,171,142,3,244,3,1,161,150,216,171,142,3,245,3,1,161,150,216,171,142,3,246,3,1,196,150,216,171,142,3,243,3,150,216,171,142,3,247,3,2,32,32,161,150,216,171,142,3,248,3,1,161,150,216,171,142,3,249,3,1,161,150,216,171,142,3,250,3,1,196,150,216,171,142,3,252,3,150,216,171,142,3,247,3,1,99,161,150,216,171,142,3,253,3,1,161,150,216,171,142,3,254,3,1,161,150,216,171,142,3,255,3,1,196,150,216,171,142,3,128,4,150,216,171,142,3,247,3,1,111,161,150,216,171,142,3,129,4,1,161,150,216,171,142,3,130,4,1,161,150,216,171,142,3,131,4,1,196,150,216,171,142,3,132,4,150,216,171,142,3,247,3,1,110,161,150,216,171,142,3,133,4,1,161,150,216,171,142,3,134,4,1,161,150,216,171,142,3,135,4,1,196,150,216,171,142,3,136,4,150,216,171,142,3,247,3,1,115,161,150,216,171,142,3,137,4,1,161,150,216,171,142,3,138,4,1,161,150,216,171,142,3,139,4,1,196,150,216,171,142,3,140,4,150,216,171,142,3,247,3,1,111,161,150,216,171,142,3,141,4,1,161,150,216,171,142,3,142,4,1,161,150,216,171,142,3,143,4,1,196,150,216,171,142,3,144,4,150,216,171,142,3,247,3,1,108,161,150,216,171,142,3,145,4,1,161,150,216,171,142,3,146,4,1,161,150,216,171,142,3,147,4,1,196,150,216,171,142,3,148,4,150,216,171,142,3,247,3,1,101,161,150,216,171,142,3,149,4,1,161,150,216,171,142,3,150,4,1,161,150,216,171,142,3,151,4,1,196,150,216,171,142,3,152,4,150,216,171,142,3,247,3,1,46,161,150,216,171,142,3,153,4,1,161,150,216,171,142,3,154,4,1,161,150,216,171,142,3,155,4,1,196,150,216,171,142,3,156,4,150,216,171,142,3,247,3,1,108,161,150,216,171,142,3,157,4,1,161,150,216,171,142,3,158,4,1,161,150,216,171,142,3,159,4,1,196,150,216,171,142,3,160,4,150,216,171,142,3,247,3,1,111,161,150,216,171,142,3,161,4,1,161,150,216,171,142,3,162,4,1,161,150,216,171,142,3,163,4,1,196,150,216,171,142,3,164,4,150,216,171,142,3,247,3,1,103,161,150,216,171,142,3,165,4,1,161,150,216,171,142,3,166,4,1,161,150,216,171,142,3,167,4,1,196,150,216,171,142,3,168,4,150,216,171,142,3,247,3,1,40,161,150,216,171,142,3,169,4,1,161,150,216,171,142,3,170,4,1,161,150,216,171,142,3,171,4,1,196,150,216,171,142,3,172,4,150,216,171,142,3,247,3,1,41,161,150,216,171,142,3,173,4,1,161,150,216,171,142,3,174,4,1,161,150,216,171,142,3,175,4,1,196,150,216,171,142,3,172,4,150,216,171,142,3,176,4,1,34,161,150,216,171,142,3,177,4,1,161,150,216,171,142,3,178,4,1,161,150,216,171,142,3,179,4,1,196,150,216,171,142,3,180,4,150,216,171,142,3,176,4,1,34,161,150,216,171,142,3,181,4,1,161,150,216,171,142,3,182,4,1,161,150,216,171,142,3,183,4,1,196,150,216,171,142,3,180,4,150,216,171,142,3,184,4,1,72,161,150,216,171,142,3,185,4,1,161,150,216,171,142,3,186,4,1,161,150,216,171,142,3,187,4,1,196,150,216,171,142,3,188,4,150,216,171,142,3,184,4,1,101,161,150,216,171,142,3,189,4,1,161,150,216,171,142,3,190,4,1,161,150,216,171,142,3,191,4,1,196,150,216,171,142,3,192,4,150,216,171,142,3,184,4,1,108,161,150,216,171,142,3,193,4,1,161,150,216,171,142,3,194,4,1,161,150,216,171,142,3,195,4,1,196,150,216,171,142,3,196,4,150,216,171,142,3,184,4,1,108,161,150,216,171,142,3,197,4,1,161,150,216,171,142,3,198,4,1,161,150,216,171,142,3,199,4,1,196,150,216,171,142,3,200,4,150,216,171,142,3,184,4,1,111,161,150,216,171,142,3,201,4,1,161,150,216,171,142,3,202,4,1,161,150,216,171,142,3,203,4,1,196,150,216,171,142,3,204,4,150,216,171,142,3,184,4,1,32,161,150,216,171,142,3,205,4,1,161,150,216,171,142,3,206,4,1,161,150,216,171,142,3,207,4,1,196,150,216,171,142,3,208,4,150,216,171,142,3,184,4,1,87,161,150,216,171,142,3,209,4,1,161,150,216,171,142,3,210,4,1,161,150,216,171,142,3,211,4,1,196,150,216,171,142,3,212,4,150,216,171,142,3,184,4,1,111,161,150,216,171,142,3,213,4,1,161,150,216,171,142,3,214,4,1,161,150,216,171,142,3,215,4,1,196,150,216,171,142,3,216,4,150,216,171,142,3,184,4,1,114,161,150,216,171,142,3,217,4,1,161,150,216,171,142,3,218,4,1,161,150,216,171,142,3,219,4,1,196,150,216,171,142,3,220,4,150,216,171,142,3,184,4,1,108,161,150,216,171,142,3,221,4,1,161,150,216,171,142,3,222,4,1,161,150,216,171,142,3,223,4,1,196,150,216,171,142,3,224,4,150,216,171,142,3,184,4,1,100,161,150,216,171,142,3,225,4,1,161,150,216,171,142,3,226,4,1,161,150,216,171,142,3,227,4,1,193,150,216,171,142,3,228,4,150,216,171,142,3,184,4,1,161,150,216,171,142,3,229,4,1,161,150,216,171,142,3,230,4,1,161,150,216,171,142,3,231,4,1,168,150,216,171,142,3,233,4,1,119,132,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,47,47,32,84,104,105,115,32,105,115,32,116,104,101,32,109,97,105,110,32,102,117,110,99,116,105,111,110,46,92,110,102,117,110,99,116,105,111,110,32,109,97,105,110,40,41,32,123,92,110,32,32,99,111,110,115,111,108,101,46,108,111,103,40,92,34,72,101,108,108,111,32,87,111,114,108,100,92,34,41,92,110,125,34,125,93,44,34,108,97,110,103,117,97,103,101,34,58,34,74,97,118,97,115,99,114,105,112,116,34,125,168,150,216,171,142,3,234,4,1,119,10,49,112,115,100,67,122,97,87,104,49,168,150,216,171,142,3,235,4,1,119,4,116,101,120,116,39,0,204,195,206,156,1,4,6,48,100,51,52,82,50,2,39,0,204,195,206,156,1,4,6,45,71,115,81,49,95,2,4,0,150,216,171,142,3,240,4,4,49,50,51,32,134,150,216,171,142,3,244,4,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,125,132,150,216,171,142,3,245,4,1,36,134,150,216,171,142,3,246,4,7,109,101,110,116,105,111,110,4,110,117,108,108,132,150,216,171,142,3,247,4,6,32,32,101,114,32,32,33,0,204,195,206,156,1,1,6,49,71,114,87,76,99,1,0,7,33,0,204,195,206,156,1,3,6,72,105,104,101,52,114,1,193,164,202,219,213,10,28,199,130,209,189,2,60,1,168,164,202,219,213,10,117,1,119,151,1,123,34,108,101,118,101,108,34,58,50,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,32,101,114,32,32,34,125,93,125,4,0,150,216,171,142,3,239,4,1,35,0,1,132,150,216,171,142,3,137,5,1,35,0,1,132,150,216,171,142,3,139,5,1,35,0,1,39,0,204,195,206,156,1,4,6,115,99,68,45,119,114,2,39,0,204,195,206,156,1,1,6,67,72,115,77,79,98,1,40,0,150,216,171,142,3,144,5,2,105,100,1,119,6,67,72,115,77,79,98,40,0,150,216,171,142,3,144,5,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,150,216,171,142,3,144,5,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,150,216,171,142,3,144,5,8,99,104,105,108,100,114,101,110,1,119,6,97,107,121,80,104,45,33,0,150,216,171,142,3,144,5,4,100,97,116,97,1,40,0,150,216,171,142,3,144,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,144,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,97,107,121,80,104,45,0,200,164,202,219,213,10,28,150,216,171,142,3,135,5,1,119,6,67,72,115,77,79,98,4,0,150,216,171,142,3,143,5,1,49,161,150,216,171,142,3,149,5,1,132,150,216,171,142,3,154,5,1,50,161,150,216,171,142,3,155,5,1,132,150,216,171,142,3,156,5,1,51,161,150,216,171,142,3,157,5,1,168,150,216,171,142,3,5,1,119,11,123,34,100,101,112,116,104,34,58,54,125,39,0,204,195,206,156,1,4,6,112,79,69,118,75,110,2,39,0,204,195,206,156,1,4,6,80,49,49,121,116,108,2,4,0,150,216,171,142,3,162,5,3,49,50,51,33,0,204,195,206,156,1,1,6,97,79,72,54,79,66,1,0,7,33,0,204,195,206,156,1,3,6,105,89,77,80,45,116,1,193,150,216,171,142,3,135,5,199,130,209,189,2,60,1,161,150,216,171,142,3,159,5,1,168,150,216,171,142,3,176,5,1,119,38,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,44,34,108,101,118,101,108,34,58,51,125,161,199,130,209,189,2,212,3,1,161,199,130,209,189,2,232,3,1,161,199,130,209,189,2,159,4,1,161,150,216,171,142,3,179,5,1,161,199,130,209,189,2,144,4,1,161,150,216,171,142,3,181,5,1,161,150,216,171,142,3,182,5,1,161,150,216,171,142,3,180,5,2,161,150,216,171,142,3,183,5,1,161,150,216,171,142,3,184,5,1,161,150,216,171,142,3,186,5,1,161,199,130,209,189,2,252,3,1,161,150,216,171,142,3,188,5,1,161,150,216,171,142,3,189,5,1,39,0,204,195,206,156,1,4,6,70,76,85,90,75,54,2,39,0,204,195,206,156,1,4,6,69,53,84,66,120,118,2,39,0,204,195,206,156,1,1,6,103,79,106,51,90,68,1,40,0,150,216,171,142,3,195,5,2,105,100,1,119,6,103,79,106,51,90,68,40,0,150,216,171,142,3,195,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,195,5,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,195,5,8,99,104,105,108,100,114,101,110,1,119,6,116,51,112,87,101,56,33,0,150,216,171,142,3,195,5,4,100,97,116,97,1,40,0,150,216,171,142,3,195,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,195,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,116,51,112,87,101,56,0,136,199,130,209,189,2,148,4,1,119,6,103,79,106,51,90,68,39,0,204,195,206,156,1,1,6,88,56,80,113,67,120,1,40,0,150,216,171,142,3,205,5,2,105,100,1,119,6,88,56,80,113,67,120,40,0,150,216,171,142,3,205,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,205,5,6,112,97,114,101,110,116,1,119,6,103,79,106,51,90,68,40,0,150,216,171,142,3,205,5,8,99,104,105,108,100,114,101,110,1,119,6,76,55,82,84,78,106,33,0,150,216,171,142,3,205,5,4,100,97,116,97,1,40,0,150,216,171,142,3,205,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,205,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,76,55,82,84,78,106,0,8,0,150,216,171,142,3,203,5,1,119,6,88,56,80,113,67,120,39,0,204,195,206,156,1,1,6,74,48,69,48,67,66,1,40,0,150,216,171,142,3,215,5,2,105,100,1,119,6,74,48,69,48,67,66,40,0,150,216,171,142,3,215,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,215,5,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,215,5,8,99,104,105,108,100,114,101,110,1,119,6,73,120,120,49,82,88,33,0,150,216,171,142,3,215,5,4,100,97,116,97,1,40,0,150,216,171,142,3,215,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,215,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,73,120,120,49,82,88,0,136,150,216,171,142,3,204,5,1,119,6,74,48,69,48,67,66,39,0,204,195,206,156,1,1,6,75,78,45,115,87,88,1,40,0,150,216,171,142,3,225,5,2,105,100,1,119,6,75,78,45,115,87,88,40,0,150,216,171,142,3,225,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,225,5,6,112,97,114,101,110,116,1,119,6,74,48,69,48,67,66,40,0,150,216,171,142,3,225,5,8,99,104,105,108,100,114,101,110,1,119,6,75,115,100,83,116,74,33,0,150,216,171,142,3,225,5,4,100,97,116,97,1,40,0,150,216,171,142,3,225,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,225,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,75,115,100,83,116,74,0,8,0,150,216,171,142,3,223,5,1,119,6,75,78,45,115,87,88,161,150,216,171,142,3,192,5,1,4,0,150,216,171,142,3,193,5,1,55,161,150,216,171,142,3,210,5,1,132,150,216,171,142,3,236,5,1,55,161,150,216,171,142,3,237,5,1,132,150,216,171,142,3,238,5,1,55,161,150,216,171,142,3,239,5,1,39,0,204,195,206,156,1,4,6,71,52,107,110,49,95,2,39,0,204,195,206,156,1,4,6,98,52,97,80,80,53,2,39,0,204,195,206,156,1,4,6,80,111,114,82,81,79,2,161,150,216,171,142,3,235,5,1,39,0,204,195,206,156,1,1,6,80,53,88,89,98,115,1,40,0,150,216,171,142,3,246,5,2,105,100,1,119,6,80,53,88,89,98,115,40,0,150,216,171,142,3,246,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,246,5,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,246,5,8,99,104,105,108,100,114,101,110,1,119,6,89,55,81,88,109,84,33,0,150,216,171,142,3,246,5,4,100,97,116,97,1,40,0,150,216,171,142,3,246,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,246,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,89,55,81,88,109,84,0,200,199,130,209,189,2,236,3,199,130,209,189,2,128,4,1,119,6,80,53,88,89,98,115,39,0,204,195,206,156,1,1,6,57,49,85,122,51,51,1,40,0,150,216,171,142,3,128,6,2,105,100,1,119,6,57,49,85,122,51,51,40,0,150,216,171,142,3,128,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,128,6,6,112,97,114,101,110,116,1,119,6,80,53,88,89,98,115,40,0,150,216,171,142,3,128,6,8,99,104,105,108,100,114,101,110,1,119,6,88,73,86,101,114,105,33,0,150,216,171,142,3,128,6,4,100,97,116,97,1,40,0,150,216,171,142,3,128,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,128,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,88,73,86,101,114,105,0,8,0,150,216,171,142,3,254,5,1,119,6,57,49,85,122,51,51,161,150,216,171,142,3,245,5,1,39,0,204,195,206,156,1,1,6,97,105,73,55,114,78,1,40,0,150,216,171,142,3,139,6,2,105,100,1,119,6,97,105,73,55,114,78,40,0,150,216,171,142,3,139,6,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,139,6,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,139,6,8,99,104,105,108,100,114,101,110,1,119,6,70,83,77,57,101,119,33,0,150,216,171,142,3,139,6,4,100,97,116,97,1,40,0,150,216,171,142,3,139,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,139,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,70,83,77,57,101,119,0,200,199,130,209,189,2,148,4,150,216,171,142,3,204,5,1,119,6,97,105,73,55,114,78,39,0,204,195,206,156,1,1,6,48,117,114,80,56,120,1,40,0,150,216,171,142,3,149,6,2,105,100,1,119,6,48,117,114,80,56,120,40,0,150,216,171,142,3,149,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,149,6,6,112,97,114,101,110,116,1,119,6,97,105,73,55,114,78,40,0,150,216,171,142,3,149,6,8,99,104,105,108,100,114,101,110,1,119,6,98,90,114,57,106,101,33,0,150,216,171,142,3,149,6,4,100,97,116,97,1,40,0,150,216,171,142,3,149,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,149,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,98,90,114,57,106,101,0,8,0,150,216,171,142,3,147,6,1,119,6,48,117,114,80,56,120,39,0,204,195,206,156,1,1,6,100,114,110,97,115,68,1,40,0,150,216,171,142,3,159,6,2,105,100,1,119,6,100,114,110,97,115,68,40,0,150,216,171,142,3,159,6,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,159,6,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,159,6,8,99,104,105,108,100,114,101,110,1,119,6,76,114,45,49,81,54,33,0,150,216,171,142,3,159,6,4,100,97,116,97,1,40,0,150,216,171,142,3,159,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,159,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,76,114,45,49,81,54,0,136,150,216,171,142,3,224,5,1,119,6,100,114,110,97,115,68,39,0,204,195,206,156,1,1,6,72,69,79,54,86,72,1,40,0,150,216,171,142,3,169,6,2,105,100,1,119,6,72,69,79,54,86,72,40,0,150,216,171,142,3,169,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,169,6,6,112,97,114,101,110,116,1,119,6,100,114,110,97,115,68,40,0,150,216,171,142,3,169,6,8,99,104,105,108,100,114,101,110,1,119,6,71,118,57,87,108,76,33,0,150,216,171,142,3,169,6,4,100,97,116,97,1,40,0,150,216,171,142,3,169,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,169,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,71,118,57,87,108,76,0,8,0,150,216,171,142,3,167,6,1,119,6,72,69,79,54,86,72,4,0,150,216,171,142,3,242,5,1,49,161,150,216,171,142,3,133,6,1,132,150,216,171,142,3,179,6,1,48,161,150,216,171,142,3,180,6,1,132,150,216,171,142,3,181,6,1,49,161,150,216,171,142,3,182,6,1,132,150,216,171,142,3,183,6,1,48,161,150,216,171,142,3,184,6,1,161,150,216,171,142,3,187,5,1,161,150,216,171,142,3,191,5,1,161,150,216,171,142,3,220,5,1,161,150,216,171,142,3,138,6,1,39,0,204,195,206,156,1,4,6,54,73,68,55,103,118,2,4,0,150,216,171,142,3,191,6,1,49,168,199,130,209,189,2,169,4,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,34,125,93,125,39,0,204,195,206,156,1,4,6,77,84,68,68,110,107,2,4,0,150,216,171,142,3,194,6,1,50,168,199,130,209,189,2,242,3,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,50,34,125,93,125,39,0,204,195,206,156,1,4,6,88,108,87,102,45,70,2,4,0,150,216,171,142,3,197,6,1,51,168,150,216,171,142,3,186,6,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,34,125,93,125,39,0,204,195,206,156,1,4,6,57,98,65,107,106,109,2,4,0,150,216,171,142,3,200,6,1,52,168,199,130,209,189,2,134,4,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,52,34,125,93,125,39,0,204,195,206,156,1,4,6,99,112,85,122,107,121,2,4,0,150,216,171,142,3,203,6,1,53,168,199,130,209,189,2,177,4,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,53,34,125,93,125,39,0,204,195,206,156,1,4,6,81,102,72,107,77,77,2,4,0,150,216,171,142,3,206,6,1,54,168,150,216,171,142,3,154,6,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,54,34,125,93,125,39,0,204,195,206,156,1,4,6,119,113,82,74,112,76,2,4,0,150,216,171,142,3,209,6,1,55,168,150,216,171,142,3,241,5,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,55,34,125,93,125,39,0,204,195,206,156,1,4,6,69,70,82,71,121,80,2,4,0,150,216,171,142,3,212,6,1,56,168,150,216,171,142,3,230,5,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,56,34,125,93,125,39,0,204,195,206,156,1,4,6,104,109,90,99,72,101,2,1,0,150,216,171,142,3,215,6,1,161,150,216,171,142,3,174,6,2,132,150,216,171,142,3,216,6,1,57,168,150,216,171,142,3,218,6,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,57,34,125,93,125,39,0,204,195,206,156,1,4,6,56,117,111,87,49,119,2,4,0,150,216,171,142,3,221,6,4,119,105,116,104,168,199,130,209,189,2,146,3,1,119,61,123,34,97,108,105,103,110,34,58,34,114,105,103,104,116,34,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,119,105,116,104,34,125,93,125,39,0,204,195,206,156,1,4,6,109,55,80,110,81,54,2,4,0,150,216,171,142,3,227,6,3,108,111,110,129,150,216,171,142,3,230,6,14,132,150,216,171,142,3,244,6,44,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,134,150,216,171,142,3,160,7,11,102,111,110,116,95,102,97,109,105,108,121,22,34,65,68,76,97,77,68,105,115,112,108,97,121,95,114,101,103,117,108,97,114,34,132,150,216,171,142,3,161,7,9,116,101,120,116,110,103,32,116,101,134,150,216,171,142,3,170,7,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,132,150,216,171,142,3,171,7,16,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,129,150,216,171,142,3,187,7,6,132,150,216,171,142,3,193,7,92,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,161,199,130,209,189,2,213,2,1,196,150,216,171,142,3,187,7,150,216,171,142,3,188,7,1,76,161,150,216,171,142,3,158,8,1,196,150,216,171,142,3,193,7,150,216,171,142,3,194,7,1,101,161,150,216,171,142,3,160,8,1,70,204,195,206,156,1,135,7,11,102,111,110,116,95,102,97,109,105,108,121,22,34,65,98,114,105,108,70,97,116,102,97,99,101,95,114,101,103,117,108,97,114,34,193,150,216,171,142,3,163,8,204,195,206,156,1,135,7,3,198,150,216,171,142,3,166,8,204,195,206,156,1,135,7,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,161,199,130,209,189,2,25,1,161,199,130,209,189,2,26,1,161,199,130,209,189,2,27,1,198,150,216,171,142,3,230,6,150,216,171,142,3,231,6,11,102,111,110,116,95,102,97,109,105,108,121,22,34,65,68,76,97,77,68,105,115,112,108,97,121,95,114,101,103,117,108,97,114,34,196,150,216,171,142,3,171,8,150,216,171,142,3,231,6,14,103,32,116,101,120,116,110,103,32,116,101,120,116,110,198,150,216,171,142,3,185,8,150,216,171,142,3,231,6,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,168,150,216,171,142,3,162,8,1,119,253,2,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,108,111,110,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,102,97,109,105,108,121,34,58,34,65,68,76,97,77,68,105,115,112,108,97,121,95,114,101,103,117,108,97,114,34,125,44,34,105,110,115,101,114,116,34,58,34,103,32,116,101,120,116,110,103,32,116,101,120,116,110,34,125,44,123,34,105,110,115,101,114,116,34,58,34,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,102,97,109,105,108,121,34,58,34,65,68,76,97,77,68,105,115,112,108,97,121,95,114,101,103,117,108,97,114,34,125,44,34,105,110,115,101,114,116,34,58,34,116,101,120,116,110,103,32,116,101,34,125,44,123,34,105,110,115,101,114,116,34,58,34,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,76,101,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,34,125,93,125,20,168,215,223,235,2,0,161,150,216,171,142,3,168,8,1,161,150,216,171,142,3,169,8,1,161,150,216,171,142,3,170,8,1,196,150,216,171,142,3,166,8,150,216,171,142,3,167,8,3,87,101,108,132,224,159,166,178,15,26,16,99,111,109,101,32,116,111,32,65,112,112,70,108,111,119,121,39,0,204,195,206,156,1,4,6,74,98,104,77,53,50,2,4,0,168,215,223,235,2,22,20,72,101,114,101,32,97,114,101,32,116,104,101,32,98,97,115,105,99,115,32,168,168,215,223,235,2,0,1,119,120,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,102,97,109,105,108,121,34,58,34,65,98,114,105,108,70,97,116,102,97,99,101,95,114,101,103,117,108,97,114,34,125,44,34,105,110,115,101,114,116,34,58,34,87,101,108,34,125,44,123,34,105,110,115,101,114,116,34,58,34,99,111,109,101,32,116,111,32,65,112,112,70,108,111,119,121,34,125,93,44,34,108,101,118,101,108,34,58,49,125,168,168,215,223,235,2,1,1,119,10,119,88,107,79,72,81,49,50,99,111,168,168,215,223,235,2,2,1,119,4,116,101,120,116,167,204,195,206,156,1,213,1,1,40,0,168,215,223,235,2,46,2,105,100,1,119,10,97,115,74,118,54,70,114,65,82,97,40,0,168,215,223,235,2,46,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,168,215,223,235,2,46,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,168,215,223,235,2,46,8,99,104,105,108,100,114,101,110,1,119,6,51,107,67,87,106,70,40,0,168,215,223,235,2,46,4,100,97,116,97,1,119,55,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,72,101,114,101,32,97,114,101,32,116,104,101,32,98,97,115,105,99,115,32,34,125,93,44,34,108,101,118,101,108,34,58,50,125,40,0,168,215,223,235,2,46,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,168,215,223,235,2,46,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,51,107,67,87,106,70,0,200,204,195,206,156,1,232,1,199,130,209,189,2,181,3,1,119,10,97,115,74,118,54,70,114,65,82,97,1,192,246,139,213,2,0,161,239,239,208,251,10,16,35,2,190,183,139,210,2,0,161,241,147,239,232,6,3,109,168,190,183,139,210,2,108,1,122,0,0,0,0,102,35,115,218,143,6,199,130,209,189,2,0,39,0,204,195,206,156,1,4,6,88,116,53,112,118,55,2,4,0,199,130,209,189,2,0,9,229,144,140,228,184,128,228,184,170,129,199,130,209,189,2,3,5,161,178,187,245,161,14,10,6,132,199,130,209,189,2,8,1,110,161,199,130,209,189,2,14,1,132,199,130,209,189,2,15,1,105,168,199,130,209,189,2,16,1,119,36,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,229,144,140,228,184,128,228,184,170,110,105,34,125,93,125,161,224,159,166,178,15,27,1,161,224,159,166,178,15,28,1,161,224,159,166,178,15,29,1,161,199,130,209,189,2,19,1,161,199,130,209,189,2,20,1,161,199,130,209,189,2,21,1,161,199,130,209,189,2,22,1,161,199,130,209,189,2,23,1,161,199,130,209,189,2,24,1,0,3,39,0,204,195,206,156,1,4,6,82,74,97,73,54,107,2,4,0,199,130,209,189,2,31,1,116,161,228,242,134,215,15,11,1,132,199,130,209,189,2,32,1,111,161,199,130,209,189,2,33,1,132,199,130,209,189,2,34,1,100,161,199,130,209,189,2,35,1,132,199,130,209,189,2,36,1,111,161,199,130,209,189,2,37,1,132,199,130,209,189,2,38,1,32,161,199,130,209,189,2,39,1,132,199,130,209,189,2,40,1,108,161,199,130,209,189,2,41,1,132,199,130,209,189,2,42,1,105,161,199,130,209,189,2,43,1,132,199,130,209,189,2,44,1,115,161,199,130,209,189,2,45,1,132,199,130,209,189,2,46,1,116,161,199,130,209,189,2,47,1,39,0,204,195,206,156,1,4,6,55,80,118,106,121,81,2,39,0,204,195,206,156,1,1,6,71,118,88,50,102,110,1,40,0,199,130,209,189,2,51,2,105,100,1,119,6,71,118,88,50,102,110,40,0,199,130,209,189,2,51,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,199,130,209,189,2,51,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,51,8,99,104,105,108,100,114,101,110,1,119,6,111,112,68,102,54,95,33,0,199,130,209,189,2,51,4,100,97,116,97,1,40,0,199,130,209,189,2,51,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,51,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,111,112,68,102,54,95,0,200,198,223,206,159,1,135,1,198,223,206,159,1,116,1,119,6,71,118,88,50,102,110,161,199,130,209,189,2,49,1,4,0,199,130,209,189,2,50,1,99,161,199,130,209,189,2,56,1,132,199,130,209,189,2,62,1,104,161,199,130,209,189,2,63,1,132,199,130,209,189,2,64,1,101,161,199,130,209,189,2,65,1,132,199,130,209,189,2,66,1,99,161,199,130,209,189,2,67,1,132,199,130,209,189,2,68,1,107,161,199,130,209,189,2,69,1,132,199,130,209,189,2,70,1,101,161,199,130,209,189,2,71,1,132,199,130,209,189,2,72,1,100,161,199,130,209,189,2,73,1,132,199,130,209,189,2,74,1,32,161,199,130,209,189,2,75,1,132,199,130,209,189,2,76,1,116,161,199,130,209,189,2,77,1,132,199,130,209,189,2,78,1,111,161,199,130,209,189,2,79,1,132,199,130,209,189,2,80,1,100,161,199,130,209,189,2,81,1,132,199,130,209,189,2,82,1,111,161,199,130,209,189,2,83,1,132,199,130,209,189,2,84,1,32,161,199,130,209,189,2,85,1,132,199,130,209,189,2,86,1,108,161,199,130,209,189,2,87,1,132,199,130,209,189,2,88,1,105,161,199,130,209,189,2,89,1,132,199,130,209,189,2,90,1,115,161,199,130,209,189,2,91,1,132,199,130,209,189,2,92,1,116,161,199,130,209,189,2,93,1,39,0,204,195,206,156,1,4,6,117,115,117,45,118,111,2,39,0,204,195,206,156,1,1,6,86,90,80,95,77,113,1,40,0,199,130,209,189,2,97,2,105,100,1,119,6,86,90,80,95,77,113,40,0,199,130,209,189,2,97,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,199,130,209,189,2,97,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,97,8,99,104,105,108,100,114,101,110,1,119,6,54,55,76,56,102,50,33,0,199,130,209,189,2,97,4,100,97,116,97,1,40,0,199,130,209,189,2,97,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,97,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,54,55,76,56,102,50,0,200,199,130,209,189,2,60,198,223,206,159,1,116,1,119,6,86,90,80,95,77,113,161,199,130,209,189,2,95,1,4,0,199,130,209,189,2,96,1,108,161,199,130,209,189,2,102,1,132,199,130,209,189,2,108,1,111,161,199,130,209,189,2,109,1,132,199,130,209,189,2,110,1,110,161,199,130,209,189,2,111,1,132,199,130,209,189,2,112,1,103,161,199,130,209,189,2,113,1,132,199,130,209,189,2,114,1,32,161,199,130,209,189,2,115,1,132,199,130,209,189,2,116,1,116,161,199,130,209,189,2,117,1,132,199,130,209,189,2,118,1,101,161,199,130,209,189,2,119,1,132,199,130,209,189,2,120,1,120,161,199,130,209,189,2,121,1,132,199,130,209,189,2,122,1,116,161,199,130,209,189,2,123,1,129,199,130,209,189,2,124,1,161,199,130,209,189,2,125,2,132,199,130,209,189,2,126,7,110,103,32,116,101,120,116,161,199,130,209,189,2,128,1,1,132,199,130,209,189,2,135,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,136,1,1,132,199,130,209,189,2,143,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,144,1,1,132,199,130,209,189,2,151,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,152,1,1,132,199,130,209,189,2,159,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,160,1,1,132,199,130,209,189,2,167,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,168,1,1,132,199,130,209,189,2,175,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,176,1,1,132,199,130,209,189,2,183,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,184,1,1,132,199,130,209,189,2,191,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,192,1,1,132,199,130,209,189,2,199,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,200,1,1,132,199,130,209,189,2,207,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,208,1,1,132,199,130,209,189,2,215,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,216,1,1,132,199,130,209,189,2,223,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,224,1,1,132,199,130,209,189,2,231,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,232,1,1,132,199,130,209,189,2,239,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,240,1,1,132,199,130,209,189,2,247,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,248,1,1,132,199,130,209,189,2,255,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,128,2,1,132,199,130,209,189,2,135,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,136,2,1,132,199,130,209,189,2,143,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,144,2,1,132,199,130,209,189,2,151,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,152,2,1,132,199,130,209,189,2,159,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,160,2,1,132,199,130,209,189,2,167,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,168,2,1,132,199,130,209,189,2,175,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,176,2,1,132,199,130,209,189,2,183,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,184,2,1,132,199,130,209,189,2,191,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,192,2,1,161,199,130,209,189,2,107,1,39,0,204,195,206,156,1,4,6,55,74,97,87,111,56,2,39,0,204,195,206,156,1,1,6,54,87,56,99,101,88,1,40,0,199,130,209,189,2,203,2,2,105,100,1,119,6,54,87,56,99,101,88,40,0,199,130,209,189,2,203,2,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,199,130,209,189,2,203,2,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,203,2,8,99,104,105,108,100,114,101,110,1,119,6,105,55,111,99,51,56,33,0,199,130,209,189,2,203,2,4,100,97,116,97,1,40,0,199,130,209,189,2,203,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,203,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,105,55,111,99,51,56,0,200,199,130,209,189,2,106,198,223,206,159,1,116,1,119,6,54,87,56,99,101,88,161,199,130,209,189,2,200,2,1,132,199,130,209,189,2,94,1,32,161,199,130,209,189,2,201,2,1,129,199,130,209,189,2,214,2,1,161,199,130,209,189,2,215,2,1,129,199,130,209,189,2,216,2,1,161,199,130,209,189,2,217,2,1,129,199,130,209,189,2,218,2,1,161,199,130,209,189,2,219,2,1,129,199,130,209,189,2,220,2,1,161,199,130,209,189,2,221,2,5,129,199,130,209,189,2,222,2,1,161,199,130,209,189,2,227,2,1,129,199,130,209,189,2,228,2,1,161,199,130,209,189,2,229,2,1,129,199,130,209,189,2,230,2,1,161,199,130,209,189,2,231,2,1,129,199,130,209,189,2,232,2,1,161,199,130,209,189,2,233,2,1,129,199,130,209,189,2,234,2,1,161,199,130,209,189,2,235,2,1,129,199,130,209,189,2,236,2,1,161,199,130,209,189,2,237,2,1,129,199,130,209,189,2,238,2,1,161,199,130,209,189,2,239,2,1,134,199,130,209,189,2,240,2,7,102,111,114,109,117,108,97,9,34,102,111,114,109,117,108,97,34,132,199,130,209,189,2,242,2,1,36,134,199,130,209,189,2,243,2,7,102,111,114,109,117,108,97,4,110,117,108,108,168,199,130,209,189,2,241,2,1,119,108,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,101,99,107,101,100,32,116,111,100,111,32,108,105,115,116,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,114,109,117,108,97,34,58,34,102,111,114,109,117,108,97,34,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,93,44,34,99,104,101,99,107,101,100,34,58,116,114,117,101,125,1,0,199,130,209,189,2,202,2,1,161,199,130,209,189,2,208,2,1,129,199,130,209,189,2,246,2,1,161,199,130,209,189,2,247,2,1,129,199,130,209,189,2,248,2,1,161,199,130,209,189,2,249,2,1,129,199,130,209,189,2,250,2,1,161,199,130,209,189,2,251,2,1,129,199,130,209,189,2,252,2,1,161,199,130,209,189,2,253,2,1,129,199,130,209,189,2,254,2,1,161,199,130,209,189,2,255,2,1,129,199,130,209,189,2,128,3,1,161,199,130,209,189,2,129,3,8,132,199,130,209,189,2,130,3,1,119,161,199,130,209,189,2,138,3,1,132,199,130,209,189,2,139,3,1,105,161,199,130,209,189,2,140,3,1,132,199,130,209,189,2,141,3,1,116,161,199,130,209,189,2,142,3,1,132,199,130,209,189,2,143,3,1,104,161,199,130,209,189,2,144,3,1,39,0,204,195,206,156,1,4,6,55,99,74,88,114,112,2,39,0,204,195,206,156,1,1,6,86,111,54,70,109,81,1,40,0,199,130,209,189,2,148,3,2,105,100,1,119,6,86,111,54,70,109,81,40,0,199,130,209,189,2,148,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,148,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,199,130,209,189,2,148,3,8,99,104,105,108,100,114,101,110,1,119,6,106,82,78,118,55,111,33,0,199,130,209,189,2,148,3,4,100,97,116,97,1,40,0,199,130,209,189,2,148,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,148,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,82,78,118,55,111,0,136,171,236,222,251,5,206,3,1,119,6,86,111,54,70,109,81,4,0,199,130,209,189,2,147,3,4,240,159,152,131,168,199,130,209,189,2,153,3,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,240,159,152,131,34,125,93,125,39,0,204,195,206,156,1,4,6,103,89,121,119,78,121,2,33,0,204,195,206,156,1,1,6,84,67,99,110,98,71,1,0,7,33,0,204,195,206,156,1,3,6,82,117,68,55,67,100,1,193,204,195,206,156,1,232,1,198,223,206,159,1,149,1,1,39,0,204,195,206,156,1,1,6,101,77,66,121,99,80,1,40,0,199,130,209,189,2,172,3,2,105,100,1,119,6,101,77,66,121,99,80,40,0,199,130,209,189,2,172,3,2,116,121,1,119,7,111,117,116,108,105,110,101,40,0,199,130,209,189,2,172,3,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,172,3,8,99,104,105,108,100,114,101,110,1,119,6,112,72,116,98,67,52,33,0,199,130,209,189,2,172,3,4,100,97,116,97,1,40,0,199,130,209,189,2,172,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,172,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,112,72,116,98,67,52,0,200,204,195,206,156,1,232,1,199,130,209,189,2,171,3,1,119,6,101,77,66,121,99,80,39,0,204,195,206,156,1,4,6,95,97,88,90,88,80,2,33,0,204,195,206,156,1,1,6,81,89,119,70,83,48,1,0,7,33,0,204,195,206,156,1,3,6,88,110,80,104,117,89,1,193,199,130,209,189,2,171,3,198,223,206,159,1,149,1,1,39,0,204,195,206,156,1,4,6,110,90,88,77,89,67,2,39,0,204,195,206,156,1,4,6,85,99,120,53,52,69,2,39,0,204,195,206,156,1,4,6,69,82,71,102,107,88,2,39,0,204,195,206,156,1,4,6,71,108,50,57,116,102,2,39,0,204,195,206,156,1,1,6,120,49,100,100,111,87,1,40,0,199,130,209,189,2,197,3,2,105,100,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,197,3,2,116,121,1,119,5,116,97,98,108,101,40,0,199,130,209,189,2,197,3,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,197,3,8,99,104,105,108,100,114,101,110,1,119,6,100,49,110,86,107,119,33,0,199,130,209,189,2,197,3,4,100,97,116,97,1,40,0,199,130,209,189,2,197,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,197,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,100,49,110,86,107,119,0,200,199,130,209,189,2,171,3,199,130,209,189,2,192,3,1,119,6,120,49,100,100,111,87,39,0,204,195,206,156,1,1,6,121,57,72,73,118,95,1,40,0,199,130,209,189,2,207,3,2,105,100,1,119,6,121,57,72,73,118,95,40,0,199,130,209,189,2,207,3,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,207,3,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,207,3,8,99,104,105,108,100,114,101,110,1,119,6,78,104,69,49,119,116,33,0,199,130,209,189,2,207,3,4,100,97,116,97,1,40,0,199,130,209,189,2,207,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,207,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,78,104,69,49,119,116,0,8,0,199,130,209,189,2,205,3,1,119,6,121,57,72,73,118,95,39,0,204,195,206,156,1,1,6,48,83,82,103,66,118,1,40,0,199,130,209,189,2,217,3,2,105,100,1,119,6,48,83,82,103,66,118,40,0,199,130,209,189,2,217,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,217,3,6,112,97,114,101,110,116,1,119,6,121,57,72,73,118,95,40,0,199,130,209,189,2,217,3,8,99,104,105,108,100,114,101,110,1,119,6,107,108,100,67,117,111,33,0,199,130,209,189,2,217,3,4,100,97,116,97,1,40,0,199,130,209,189,2,217,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,217,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,107,108,100,67,117,111,0,8,0,199,130,209,189,2,215,3,1,119,6,48,83,82,103,66,118,39,0,204,195,206,156,1,1,6,95,90,90,78,53,99,1,40,0,199,130,209,189,2,227,3,2,105,100,1,119,6,95,90,90,78,53,99,40,0,199,130,209,189,2,227,3,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,227,3,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,227,3,8,99,104,105,108,100,114,101,110,1,119,6,103,89,69,98,121,107,33,0,199,130,209,189,2,227,3,4,100,97,116,97,1,40,0,199,130,209,189,2,227,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,227,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,103,89,69,98,121,107,0,136,199,130,209,189,2,216,3,1,119,6,95,90,90,78,53,99,39,0,204,195,206,156,1,1,6,77,106,74,57,74,76,1,40,0,199,130,209,189,2,237,3,2,105,100,1,119,6,77,106,74,57,74,76,40,0,199,130,209,189,2,237,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,237,3,6,112,97,114,101,110,116,1,119,6,95,90,90,78,53,99,40,0,199,130,209,189,2,237,3,8,99,104,105,108,100,114,101,110,1,119,6,95,102,81,84,95,110,33,0,199,130,209,189,2,237,3,4,100,97,116,97,1,40,0,199,130,209,189,2,237,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,237,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,95,102,81,84,95,110,0,8,0,199,130,209,189,2,235,3,1,119,6,77,106,74,57,74,76,39,0,204,195,206,156,1,1,6,78,77,45,104,67,70,1,40,0,199,130,209,189,2,247,3,2,105,100,1,119,6,78,77,45,104,67,70,40,0,199,130,209,189,2,247,3,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,247,3,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,247,3,8,99,104,105,108,100,114,101,110,1,119,6,117,118,68,83,80,101,33,0,199,130,209,189,2,247,3,4,100,97,116,97,1,40,0,199,130,209,189,2,247,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,247,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,117,118,68,83,80,101,0,136,199,130,209,189,2,236,3,1,119,6,78,77,45,104,67,70,39,0,204,195,206,156,1,1,6,69,70,66,45,52,82,1,40,0,199,130,209,189,2,129,4,2,105,100,1,119,6,69,70,66,45,52,82,40,0,199,130,209,189,2,129,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,129,4,6,112,97,114,101,110,116,1,119,6,78,77,45,104,67,70,40,0,199,130,209,189,2,129,4,8,99,104,105,108,100,114,101,110,1,119,6,81,81,77,50,48,66,33,0,199,130,209,189,2,129,4,4,100,97,116,97,1,40,0,199,130,209,189,2,129,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,129,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,81,81,77,50,48,66,0,8,0,199,130,209,189,2,255,3,1,119,6,69,70,66,45,52,82,39,0,204,195,206,156,1,1,6,98,100,95,105,68,101,1,40,0,199,130,209,189,2,139,4,2,105,100,1,119,6,98,100,95,105,68,101,40,0,199,130,209,189,2,139,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,139,4,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,139,4,8,99,104,105,108,100,114,101,110,1,119,6,105,80,89,69,52,56,33,0,199,130,209,189,2,139,4,4,100,97,116,97,1,40,0,199,130,209,189,2,139,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,139,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,105,80,89,69,52,56,0,136,199,130,209,189,2,128,4,1,119,6,98,100,95,105,68,101,39,0,204,195,206,156,1,1,6,55,51,88,69,103,80,1,40,0,199,130,209,189,2,149,4,2,105,100,1,119,6,55,51,88,69,103,80,40,0,199,130,209,189,2,149,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,149,4,6,112,97,114,101,110,116,1,119,6,98,100,95,105,68,101,40,0,199,130,209,189,2,149,4,8,99,104,105,108,100,114,101,110,1,119,6,115,45,80,102,105,89,33,0,199,130,209,189,2,149,4,4,100,97,116,97,1,40,0,199,130,209,189,2,149,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,149,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,115,45,80,102,105,89,0,8,0,199,130,209,189,2,147,4,1,119,6,55,51,88,69,103,80,161,199,130,209,189,2,202,3,1,4,0,199,130,209,189,2,193,3,1,56,161,199,130,209,189,2,222,3,1,132,199,130,209,189,2,160,4,1,56,161,199,130,209,189,2,161,4,1,132,199,130,209,189,2,162,4,1,56,161,199,130,209,189,2,163,4,1,132,199,130,209,189,2,164,4,1,56,161,199,130,209,189,2,165,4,1,132,199,130,209,189,2,166,4,1,56,161,199,130,209,189,2,167,4,1,4,0,199,130,209,189,2,196,3,1,57,161,199,130,209,189,2,154,4,1,132,199,130,209,189,2,170,4,1,57,161,199,130,209,189,2,171,4,1,132,199,130,209,189,2,172,4,1,57,161,199,130,209,189,2,173,4,1,132,199,130,209,189,2,174,4,1,57,161,199,130,209,189,2,175,4,1,0,4,39,0,204,195,206,156,1,4,6,56,85,53,118,100,78,2,39,0,204,195,206,156,1,1,6,78,99,104,45,81,78,1,40,0,199,130,209,189,2,183,4,2,105,100,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,183,4,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,183,4,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,183,4,8,99,104,105,108,100,114,101,110,1,119,6,122,97,90,84,55,68,33,0,199,130,209,189,2,183,4,4,100,97,116,97,1,40,0,199,130,209,189,2,183,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,183,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,122,97,90,84,55,68,0,200,204,195,206,156,1,246,1,204,195,206,156,1,247,1,1,119,6,78,99,104,45,81,78,1,0,199,130,209,189,2,182,4,1,161,199,130,209,189,2,188,4,1,129,199,130,209,189,2,193,4,1,161,199,130,209,189,2,194,4,1,129,199,130,209,189,2,195,4,1,161,199,130,209,189,2,196,4,1,39,0,204,195,206,156,1,4,6,75,102,57,98,106,87,2,33,0,204,195,206,156,1,1,6,119,73,53,75,113,116,1,0,7,33,0,204,195,206,156,1,3,6,115,76,56,78,88,117,1,193,204,195,206,156,1,247,1,204,195,206,156,1,248,1,1,39,0,204,195,206,156,1,4,6,48,72,111,66,111,70,2,39,0,204,195,206,156,1,1,6,84,67,90,121,70,52,1,40,0,199,130,209,189,2,211,4,2,105,100,1,119,6,84,67,90,121,70,52,40,0,199,130,209,189,2,211,4,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,211,4,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,211,4,8,99,104,105,108,100,114,101,110,1,119,6,108,99,89,77,103,95,33,0,199,130,209,189,2,211,4,4,100,97,116,97,1,40,0,199,130,209,189,2,211,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,211,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,108,99,89,77,103,95,0,8,0,199,130,209,189,2,191,4,1,119,6,84,67,90,121,70,52,1,0,199,130,209,189,2,210,4,1,161,199,130,209,189,2,216,4,1,129,199,130,209,189,2,221,4,1,161,199,130,209,189,2,222,4,1,129,199,130,209,189,2,223,4,1,161,199,130,209,189,2,224,4,1,39,0,204,195,206,156,1,4,6,108,73,54,101,68,85,2,33,0,204,195,206,156,1,1,6,67,118,56,72,55,83,1,0,7,33,0,204,195,206,156,1,3,6,107,119,71,100,66,65,1,129,199,130,209,189,2,220,4,1,39,0,204,195,206,156,1,4,6,57,83,80,71,121,88,2,39,0,204,195,206,156,1,1,6,52,119,120,102,90,72,1,40,0,199,130,209,189,2,239,4,2,105,100,1,119,6,52,119,120,102,90,72,40,0,199,130,209,189,2,239,4,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,239,4,6,112,97,114,101,110,116,1,119,6,84,67,90,121,70,52,40,0,199,130,209,189,2,239,4,8,99,104,105,108,100,114,101,110,1,119,6,118,103,105,70,69,106,33,0,199,130,209,189,2,239,4,4,100,97,116,97,1,40,0,199,130,209,189,2,239,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,239,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,118,103,105,70,69,106,0,8,0,199,130,209,189,2,219,4,1,119,6,52,119,120,102,90,72,1,0,199,130,209,189,2,238,4,1,161,199,130,209,189,2,244,4,1,129,199,130,209,189,2,249,4,1,161,199,130,209,189,2,250,4,1,129,199,130,209,189,2,251,4,1,161,199,130,209,189,2,252,4,1,39,0,204,195,206,156,1,4,6,106,81,55,52,49,100,2,39,0,204,195,206,156,1,1,6,109,102,89,53,57,121,1,40,0,199,130,209,189,2,128,5,2,105,100,1,119,6,109,102,89,53,57,121,40,0,199,130,209,189,2,128,5,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,128,5,6,112,97,114,101,110,116,1,119,6,84,67,90,121,70,52,40,0,199,130,209,189,2,128,5,8,99,104,105,108,100,114,101,110,1,119,6,71,116,121,76,66,108,33,0,199,130,209,189,2,128,5,4,100,97,116,97,1,40,0,199,130,209,189,2,128,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,128,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,71,116,121,76,66,108,0,136,199,130,209,189,2,248,4,1,119,6,109,102,89,53,57,121,1,0,199,130,209,189,2,255,4,1,161,199,130,209,189,2,133,5,1,129,199,130,209,189,2,138,5,1,161,199,130,209,189,2,139,5,1,129,199,130,209,189,2,140,5,1,161,199,130,209,189,2,141,5,1,39,0,204,195,206,156,1,4,6,99,82,52,54,74,83,2,33,0,204,195,206,156,1,1,6,95,95,82,90,106,107,1,0,7,33,0,204,195,206,156,1,3,6,117,113,87,99,122,50,1,129,199,130,209,189,2,137,5,1,4,0,199,130,209,189,2,144,5,1,49,0,1,132,199,130,209,189,2,155,5,1,50,0,1,132,199,130,209,189,2,157,5,1,51,0,1,39,0,204,195,206,156,1,4,6,84,108,76,116,78,119,2,1,0,199,130,209,189,2,161,5,3,39,0,204,195,206,156,1,1,6,87,57,68,108,99,56,1,40,0,199,130,209,189,2,165,5,2,105,100,1,119,6,87,57,68,108,99,56,40,0,199,130,209,189,2,165,5,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,165,5,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,165,5,8,99,104,105,108,100,114,101,110,1,119,6,71,113,89,119,74,81,33,0,199,130,209,189,2,165,5,4,100,97,116,97,1,40,0,199,130,209,189,2,165,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,165,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,71,113,89,119,74,81,0,136,199,130,209,189,2,237,4,1,119,6,87,57,68,108,99,56,129,199,130,209,189,2,164,5,1,161,199,130,209,189,2,170,5,1,129,199,130,209,189,2,175,5,1,161,199,130,209,189,2,176,5,1,129,199,130,209,189,2,177,5,1,161,199,130,209,189,2,178,5,1,39,0,204,195,206,156,1,4,6,105,45,118,52,52,66,2,33,0,204,195,206,156,1,1,6,116,72,104,110,105,69,1,0,7,33,0,204,195,206,156,1,3,6,79,69,107,76,69,106,1,129,199,130,209,189,2,174,5,1,1,0,199,130,209,189,2,181,5,1,0,1,129,199,130,209,189,2,192,5,1,0,3,132,199,130,209,189,2,194,5,1,62,0,1,39,0,204,195,206,156,1,4,6,76,115,116,55,78,103,2,39,0,204,195,206,156,1,1,6,113,90,76,56,88,88,1,40,0,199,130,209,189,2,201,5,2,105,100,1,119,6,113,90,76,56,88,88,40,0,199,130,209,189,2,201,5,2,116,121,1,119,11,116,111,103,103,108,101,95,108,105,115,116,40,0,199,130,209,189,2,201,5,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,201,5,8,99,104,105,108,100,114,101,110,1,119,6,49,98,68,104,69,101,33,0,199,130,209,189,2,201,5,4,100,97,116,97,1,40,0,199,130,209,189,2,201,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,201,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,49,98,68,104,69,101,0,200,199,130,209,189,2,174,5,199,130,209,189,2,191,5,1,119,6,113,90,76,56,88,88,1,0,199,130,209,189,2,200,5,1,161,199,130,209,189,2,206,5,1,129,199,130,209,189,2,211,5,1,161,199,130,209,189,2,212,5,1,129,199,130,209,189,2,213,5,1,161,199,130,209,189,2,214,5,1,39,0,204,195,206,156,1,4,6,88,103,107,99,56,110,2,39,0,204,195,206,156,1,1,6,105,66,98,109,87,48,1,40,0,199,130,209,189,2,218,5,2,105,100,1,119,6,105,66,98,109,87,48,40,0,199,130,209,189,2,218,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,218,5,6,112,97,114,101,110,116,1,119,6,113,90,76,56,88,88,40,0,199,130,209,189,2,218,5,8,99,104,105,108,100,114,101,110,1,119,6,72,95,104,114,75,71,33,0,199,130,209,189,2,218,5,4,100,97,116,97,1,40,0,199,130,209,189,2,218,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,218,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,72,95,104,114,75,71,0,8,0,199,130,209,189,2,209,5,1,119,6,105,66,98,109,87,48,161,199,130,209,189,2,216,5,1,1,0,199,130,209,189,2,217,5,1,161,199,130,209,189,2,223,5,1,129,199,130,209,189,2,229,5,1,161,199,130,209,189,2,230,5,1,129,199,130,209,189,2,231,5,1,161,199,130,209,189,2,232,5,1,39,0,204,195,206,156,1,4,6,52,90,104,112,86,73,2,33,0,204,195,206,156,1,1,6,78,79,116,108,71,74,1,0,7,33,0,204,195,206,156,1,3,6,52,107,104,115,81,48,1,129,199,130,209,189,2,227,5,1,39,0,204,195,206,156,1,4,6,74,98,106,103,98,105,2,39,0,204,195,206,156,1,1,6,55,71,119,105,74,83,1,40,0,199,130,209,189,2,247,5,2,105,100,1,119,6,55,71,119,105,74,83,40,0,199,130,209,189,2,247,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,247,5,6,112,97,114,101,110,116,1,119,6,105,66,98,109,87,48,40,0,199,130,209,189,2,247,5,8,99,104,105,108,100,114,101,110,1,119,6,99,53,87,50,53,102,33,0,199,130,209,189,2,247,5,4,100,97,116,97,1,40,0,199,130,209,189,2,247,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,247,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,99,53,87,50,53,102,0,8,0,199,130,209,189,2,226,5,1,119,6,55,71,119,105,74,83,1,0,199,130,209,189,2,246,5,1,161,199,130,209,189,2,252,5,1,129,199,130,209,189,2,129,6,1,161,199,130,209,189,2,130,6,1,129,199,130,209,189,2,131,6,1,161,199,130,209,189,2,132,6,1,39,0,204,195,206,156,1,4,6,118,87,56,68,45,102,2,33,0,204,195,206,156,1,1,6,99,88,73,114,105,45,1,0,7,33,0,204,195,206,156,1,3,6,122,70,104,98,74,88,1,129,199,130,209,189,2,128,6,1,39,0,204,195,206,156,1,4,6,86,65,80,82,86,55,2,33,0,204,195,206,156,1,1,6,99,72,102,57,114,111,1,0,7,33,0,204,195,206,156,1,3,6,70,112,56,103,98,56,1,129,199,130,209,189,2,245,5,1,4,0,199,130,209,189,2,146,6,1,49,0,1,132,199,130,209,189,2,157,6,1,50,0,1,132,199,130,209,189,2,159,6,1,51,0,1,39,0,204,195,206,156,1,4,6,95,70,68,79,103,89,2,4,0,199,130,209,189,2,163,6,3,49,50,51,39,0,204,195,206,156,1,1,6,84,69,81,71,120,89,1,40,0,199,130,209,189,2,167,6,2,105,100,1,119,6,84,69,81,71,120,89,40,0,199,130,209,189,2,167,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,167,6,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,167,6,8,99,104,105,108,100,114,101,110,1,119,6,72,120,102,70,78,49,40,0,199,130,209,189,2,167,6,4,100,97,116,97,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,125,40,0,199,130,209,189,2,167,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,167,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,72,120,102,70,78,49,0,136,199,130,209,189,2,191,5,1,119,6,84,69,81,71,120,89,68,199,130,209,189,2,193,4,1,98,161,199,130,209,189,2,198,4,1,132,199,130,209,189,2,197,4,1,117,161,199,130,209,189,2,178,6,1,129,199,130,209,189,2,179,6,1,132,199,130,209,189,2,181,6,1,108,161,199,130,209,189,2,180,6,2,132,199,130,209,189,2,182,6,1,108,161,199,130,209,189,2,184,6,1,132,199,130,209,189,2,185,6,1,101,161,199,130,209,189,2,186,6,1,132,199,130,209,189,2,187,6,1,116,161,199,130,209,189,2,188,6,1,132,199,130,209,189,2,189,6,1,101,161,199,130,209,189,2,190,6,1,132,199,130,209,189,2,191,6,1,100,161,199,130,209,189,2,192,6,1,132,199,130,209,189,2,193,6,1,32,161,199,130,209,189,2,194,6,1,132,199,130,209,189,2,195,6,1,108,161,199,130,209,189,2,196,6,1,132,199,130,209,189,2,197,6,1,105,161,199,130,209,189,2,198,6,1,132,199,130,209,189,2,199,6,1,115,161,199,130,209,189,2,200,6,1,132,199,130,209,189,2,201,6,1,116,168,199,130,209,189,2,202,6,1,119,38,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,98,117,108,108,101,116,101,100,32,108,105,115,116,34,125,93,125,68,199,130,209,189,2,221,4,1,99,161,199,130,209,189,2,226,4,1,132,199,130,209,189,2,225,4,1,104,161,199,130,209,189,2,206,6,1,132,199,130,209,189,2,207,6,1,105,161,199,130,209,189,2,208,6,1,132,199,130,209,189,2,209,6,1,108,161,199,130,209,189,2,210,6,1,132,199,130,209,189,2,211,6,1,100,161,199,130,209,189,2,212,6,1,129,199,130,209,189,2,213,6,1,161,199,130,209,189,2,214,6,2,132,199,130,209,189,2,215,6,1,45,161,199,130,209,189,2,217,6,1,132,199,130,209,189,2,218,6,1,49,168,199,130,209,189,2,219,6,1,119,32,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,34,125,93,125,68,199,130,209,189,2,249,4,1,99,161,199,130,209,189,2,254,4,1,132,199,130,209,189,2,253,4,1,104,161,199,130,209,189,2,223,6,1,132,199,130,209,189,2,224,6,1,105,161,199,130,209,189,2,225,6,1,132,199,130,209,189,2,226,6,1,108,161,199,130,209,189,2,227,6,1,132,199,130,209,189,2,228,6,1,100,161,199,130,209,189,2,229,6,1,132,199,130,209,189,2,230,6,1,45,161,199,130,209,189,2,231,6,1,132,199,130,209,189,2,232,6,1,49,161,199,130,209,189,2,233,6,1,132,199,130,209,189,2,234,6,1,45,161,199,130,209,189,2,235,6,1,132,199,130,209,189,2,236,6,1,49,168,199,130,209,189,2,237,6,1,119,34,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,45,49,34,125,93,125,68,199,130,209,189,2,138,5,1,99,161,199,130,209,189,2,143,5,1,132,199,130,209,189,2,142,5,1,104,161,199,130,209,189,2,241,6,1,132,199,130,209,189,2,242,6,1,105,161,199,130,209,189,2,243,6,1,132,199,130,209,189,2,244,6,1,108,161,199,130,209,189,2,245,6,1,132,199,130,209,189,2,246,6,1,100,161,199,130,209,189,2,247,6,1,132,199,130,209,189,2,248,6,1,45,161,199,130,209,189,2,249,6,1,132,199,130,209,189,2,250,6,1,49,161,199,130,209,189,2,251,6,1,132,199,130,209,189,2,252,6,1,45,161,199,130,209,189,2,253,6,1,132,199,130,209,189,2,254,6,1,50,168,199,130,209,189,2,255,6,1,119,34,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,45,50,34,125,93,125,68,199,130,209,189,2,162,5,1,99,161,199,130,209,189,2,180,5,1,132,199,130,209,189,2,179,5,1,104,161,199,130,209,189,2,131,7,1,132,199,130,209,189,2,132,7,1,105,161,199,130,209,189,2,133,7,1,132,199,130,209,189,2,134,7,1,108,161,199,130,209,189,2,135,7,1,132,199,130,209,189,2,136,7,1,100,161,199,130,209,189,2,137,7,1,132,199,130,209,189,2,138,7,1,45,161,199,130,209,189,2,139,7,1,132,199,130,209,189,2,140,7,1,50,168,199,130,209,189,2,141,7,1,119,32,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,50,34,125,93,125,65,199,130,209,189,2,211,5,1,161,199,130,209,189,2,228,5,1,129,199,130,209,189,2,215,5,1,161,199,130,209,189,2,145,7,1,129,199,130,209,189,2,146,7,1,161,199,130,209,189,2,147,7,1,129,199,130,209,189,2,148,7,1,161,199,130,209,189,2,149,7,1,129,199,130,209,189,2,150,7,1,161,199,130,209,189,2,151,7,1,129,199,130,209,189,2,152,7,1,161,199,130,209,189,2,153,7,1,129,199,130,209,189,2,154,7,1,161,199,130,209,189,2,155,7,8,132,199,130,209,189,2,156,7,1,116,161,199,130,209,189,2,164,7,1,132,199,130,209,189,2,165,7,1,111,161,199,130,209,189,2,166,7,1,132,199,130,209,189,2,167,7,1,103,161,199,130,209,189,2,168,7,1,132,199,130,209,189,2,169,7,1,103,161,199,130,209,189,2,170,7,1,132,199,130,209,189,2,171,7,1,108,161,199,130,209,189,2,172,7,1,132,199,130,209,189,2,173,7,1,101,161,199,130,209,189,2,174,7,1,132,199,130,209,189,2,175,7,1,32,161,199,130,209,189,2,176,7,1,132,199,130,209,189,2,177,7,1,108,161,199,130,209,189,2,178,7,1,132,199,130,209,189,2,179,7,1,105,161,199,130,209,189,2,180,7,1,132,199,130,209,189,2,181,7,1,115,161,199,130,209,189,2,182,7,1,132,199,130,209,189,2,183,7,1,116,168,199,130,209,189,2,184,7,1,119,54,123,34,99,111,108,108,97,112,115,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,116,111,103,103,108,101,32,108,105,115,116,34,125,93,125,68,199,130,209,189,2,229,5,1,99,161,199,130,209,189,2,234,5,1,132,199,130,209,189,2,233,5,1,104,161,199,130,209,189,2,188,7,1,132,199,130,209,189,2,189,7,1,105,161,199,130,209,189,2,190,7,1,132,199,130,209,189,2,191,7,1,108,161,199,130,209,189,2,192,7,1,132,199,130,209,189,2,193,7,1,100,161,199,130,209,189,2,194,7,1,132,199,130,209,189,2,195,7,1,45,161,199,130,209,189,2,196,7,1,129,199,130,209,189,2,197,7,1,161,199,130,209,189,2,198,7,2,132,199,130,209,189,2,199,7,1,49,168,199,130,209,189,2,201,7,1,119,32,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,34,125,93,125,68,199,130,209,189,2,129,6,1,99,161,199,130,209,189,2,134,6,1,132,199,130,209,189,2,133,6,1,104,161,199,130,209,189,2,205,7,1,132,199,130,209,189,2,206,7,1,105,161,199,130,209,189,2,207,7,1,132,199,130,209,189,2,208,7,1,108,161,199,130,209,189,2,209,7,1,132,199,130,209,189,2,210,7,1,100,161,199,130,209,189,2,211,7,1,132,199,130,209,189,2,212,7,1,45,161,199,130,209,189,2,213,7,1,132,199,130,209,189,2,214,7,1,49,161,199,130,209,189,2,215,7,1,129,199,130,209,189,2,216,7,1,161,199,130,209,189,2,217,7,1,129,199,130,209,189,2,218,7,1,161,199,130,209,189,2,219,7,3,129,199,130,209,189,2,220,7,1,161,199,130,209,189,2,223,7,1,129,199,130,209,189,2,224,7,1,161,199,130,209,189,2,225,7,3,132,199,130,209,189,2,226,7,1,45,161,199,130,209,189,2,229,7,1,132,199,130,209,189,2,230,7,1,49,168,199,130,209,189,2,231,7,1,119,34,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,45,49,34,125,93,125,39,0,204,195,206,156,1,4,6,55,88,55,105,70,103,2,39,0,204,195,206,156,1,1,6,101,79,68,109,108,65,1,40,0,199,130,209,189,2,235,7,2,105,100,1,119,6,101,79,68,109,108,65,40,0,199,130,209,189,2,235,7,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,235,7,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,235,7,8,99,104,105,108,100,114,101,110,1,119,6,109,112,74,69,74,90,33,0,199,130,209,189,2,235,7,4,100,97,116,97,1,40,0,199,130,209,189,2,235,7,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,235,7,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,109,112,74,69,74,90,0,200,204,195,206,156,1,242,1,204,195,206,156,1,243,1,1,119,6,101,79,68,109,108,65,168,204,195,206,156,1,164,1,1,119,79,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,75,101,121,98,111,97,114,100,32,115,104,111,114,116,99,117,116,115,44,32,109,97,114,107,100,111,119,110,44,32,97,110,100,32,99,111,100,101,32,98,108,111,99,107,34,125,93,44,34,108,101,118,101,108,34,58,50,125,168,204,195,206,156,1,165,1,1,119,10,97,98,100,49,105,117,71,81,109,68,168,204,195,206,156,1,166,1,1,119,4,116,101,120,116,1,0,199,130,209,189,2,234,7,1,161,199,130,209,189,2,240,7,1,168,199,130,209,189,2,249,7,1,119,12,123,34,100,101,108,116,97,34,58,91,93,125,132,199,130,209,189,2,48,1,32,161,199,130,209,189,2,61,1,129,199,130,209,189,2,251,7,1,161,199,130,209,189,2,252,7,1,134,199,130,209,189,2,253,7,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,56,84,49,52,58,50,53,58,51,50,46,52,53,55,50,55,55,34,125,132,199,130,209,189,2,255,7,1,36,134,199,130,209,189,2,128,8,7,109,101,110,116,105,111,110,4,110,117,108,108,161,199,130,209,189,2,254,7,1,132,199,130,209,189,2,129,8,1,109,161,199,130,209,189,2,130,8,1,132,199,130,209,189,2,131,8,1,101,161,199,130,209,189,2,132,8,1,132,199,130,209,189,2,133,8,1,110,161,199,130,209,189,2,134,8,1,129,199,130,209,189,2,135,8,1,132,199,130,209,189,2,137,8,1,116,161,199,130,209,189,2,136,8,2,1,236,158,128,159,2,0,161,219,200,174,197,9,24,4,1,245,181,155,135,2,0,161,151,234,142,238,11,26,23,176,1,146,216,250,133,2,0,161,243,138,171,183,10,60,1,161,243,138,171,183,10,61,1,161,243,138,171,183,10,62,1,161,243,138,171,183,10,71,1,161,243,138,171,183,10,63,1,161,243,138,171,183,10,64,1,161,243,138,171,183,10,65,1,161,146,216,250,133,2,3,1,161,243,138,171,183,10,67,1,161,243,138,171,183,10,68,1,161,243,138,171,183,10,69,1,161,146,216,250,133,2,7,1,161,243,138,171,183,10,84,1,161,243,138,171,183,10,85,1,161,243,138,171,183,10,86,1,161,243,138,171,183,10,95,3,161,243,138,171,183,10,91,1,161,243,138,171,183,10,92,1,161,243,138,171,183,10,93,1,161,243,138,171,183,10,87,1,161,243,138,171,183,10,88,1,161,243,138,171,183,10,89,1,161,243,138,171,183,10,96,1,161,243,138,171,183,10,97,1,161,243,138,171,183,10,98,1,161,243,138,171,183,10,107,1,161,243,138,171,183,10,100,1,161,243,138,171,183,10,101,1,161,243,138,171,183,10,102,1,161,146,216,250,133,2,27,1,161,243,138,171,183,10,104,1,161,243,138,171,183,10,105,1,161,243,138,171,183,10,106,1,161,146,216,250,133,2,31,1,161,243,138,171,183,10,108,1,161,243,138,171,183,10,109,1,161,243,138,171,183,10,110,1,161,243,138,171,183,10,119,1,161,243,138,171,183,10,112,1,161,243,138,171,183,10,113,1,161,243,138,171,183,10,114,1,161,146,216,250,133,2,39,1,161,243,138,171,183,10,116,1,161,243,138,171,183,10,117,1,161,243,138,171,183,10,118,1,161,146,216,250,133,2,43,1,161,243,138,171,183,10,120,1,161,243,138,171,183,10,121,1,161,243,138,171,183,10,122,1,161,243,138,171,183,10,123,1,161,243,138,171,183,10,124,1,161,243,138,171,183,10,125,1,161,243,138,171,183,10,131,1,2,161,243,138,171,183,10,127,1,161,243,138,171,183,10,128,1,1,161,243,138,171,183,10,129,1,1,161,146,216,250,133,2,55,1,161,243,138,171,183,10,132,1,1,161,243,138,171,183,10,133,1,1,161,243,138,171,183,10,134,1,1,161,243,138,171,183,10,143,1,1,161,243,138,171,183,10,136,1,1,161,243,138,171,183,10,137,1,1,161,243,138,171,183,10,138,1,1,161,146,216,250,133,2,63,1,161,243,138,171,183,10,140,1,1,161,243,138,171,183,10,141,1,1,161,243,138,171,183,10,142,1,1,161,146,216,250,133,2,67,1,161,243,138,171,183,10,144,1,1,161,243,138,171,183,10,145,1,1,161,243,138,171,183,10,146,1,1,161,243,138,171,183,10,155,1,1,161,243,138,171,183,10,148,1,1,161,243,138,171,183,10,149,1,1,161,243,138,171,183,10,150,1,1,161,146,216,250,133,2,75,1,161,243,138,171,183,10,152,1,1,161,243,138,171,183,10,153,1,1,161,243,138,171,183,10,154,1,1,161,146,216,250,133,2,79,1,161,243,138,171,183,10,156,1,1,161,243,138,171,183,10,157,1,1,161,243,138,171,183,10,158,1,1,161,243,138,171,183,10,167,1,1,161,243,138,171,183,10,160,1,1,161,243,138,171,183,10,161,1,1,161,243,138,171,183,10,162,1,1,161,146,216,250,133,2,87,1,161,243,138,171,183,10,164,1,1,161,243,138,171,183,10,165,1,1,161,243,138,171,183,10,166,1,1,161,146,216,250,133,2,91,1,161,243,138,171,183,10,168,1,1,161,243,138,171,183,10,169,1,1,161,243,138,171,183,10,170,1,1,161,243,138,171,183,10,179,1,1,161,243,138,171,183,10,176,1,1,161,243,138,171,183,10,177,1,1,161,243,138,171,183,10,178,1,1,161,146,216,250,133,2,99,1,161,243,138,171,183,10,172,1,1,161,243,138,171,183,10,173,1,1,161,243,138,171,183,10,174,1,1,161,146,216,250,133,2,103,1,161,243,138,171,183,10,180,1,1,161,243,138,171,183,10,181,1,1,161,243,138,171,183,10,182,1,1,161,243,138,171,183,10,191,1,1,161,243,138,171,183,10,188,1,1,161,243,138,171,183,10,189,1,1,161,243,138,171,183,10,190,1,1,161,146,216,250,133,2,111,1,161,243,138,171,183,10,184,1,1,161,243,138,171,183,10,185,1,1,161,243,138,171,183,10,186,1,1,161,146,216,250,133,2,115,1,161,243,138,171,183,10,192,1,1,161,243,138,171,183,10,193,1,1,161,243,138,171,183,10,194,1,1,161,243,138,171,183,10,203,1,1,161,243,138,171,183,10,196,1,1,161,243,138,171,183,10,197,1,1,161,243,138,171,183,10,198,1,1,161,146,216,250,133,2,123,1,161,243,138,171,183,10,200,1,1,161,243,138,171,183,10,201,1,1,161,243,138,171,183,10,202,1,1,161,146,216,250,133,2,127,1,161,243,138,171,183,10,204,1,1,161,243,138,171,183,10,205,1,1,161,243,138,171,183,10,206,1,1,161,243,138,171,183,10,215,1,1,161,243,138,171,183,10,209,1,1,161,243,138,171,183,10,210,1,1,161,243,138,171,183,10,211,1,1,161,146,216,250,133,2,135,1,1,161,243,138,171,183,10,212,1,1,161,243,138,171,183,10,213,1,1,161,243,138,171,183,10,214,1,1,161,146,216,250,133,2,139,1,1,161,243,138,171,183,10,216,1,1,161,243,138,171,183,10,217,1,1,161,243,138,171,183,10,218,1,1,161,243,138,171,183,10,227,1,1,161,243,138,171,183,10,220,1,1,161,243,138,171,183,10,221,1,1,161,243,138,171,183,10,222,1,1,161,146,216,250,133,2,147,1,1,161,243,138,171,183,10,224,1,1,161,243,138,171,183,10,225,1,1,161,243,138,171,183,10,226,1,1,161,146,216,250,133,2,151,1,1,161,243,138,171,183,10,228,1,1,161,243,138,171,183,10,229,1,1,161,243,138,171,183,10,230,1,1,161,243,138,171,183,10,239,1,1,161,243,138,171,183,10,232,1,1,161,243,138,171,183,10,233,1,1,161,243,138,171,183,10,234,1,1,161,146,216,250,133,2,159,1,1,161,243,138,171,183,10,236,1,1,161,243,138,171,183,10,237,1,1,161,243,138,171,183,10,238,1,1,161,146,216,250,133,2,163,1,1,161,146,216,250,133,2,156,1,1,161,146,216,250,133,2,157,1,1,161,146,216,250,133,2,158,1,1,161,146,216,250,133,2,160,1,1,161,146,216,250,133,2,161,1,1,161,146,216,250,133,2,162,1,1,161,146,216,250,133,2,167,1,1,161,146,216,250,133,2,164,1,1,161,146,216,250,133,2,165,1,1,161,146,216,250,133,2,166,1,1,161,146,216,250,133,2,174,1,2,9,172,254,181,239,1,0,39,0,204,195,206,156,1,4,6,108,45,56,109,101,45,2,4,0,172,254,181,239,1,0,4,104,106,107,100,161,198,223,206,159,1,153,1,1,132,172,254,181,239,1,4,2,39,100,161,172,254,181,239,1,5,1,132,172,254,181,239,1,7,2,39,100,161,172,254,181,239,1,8,1,132,172,254,181,239,1,10,2,39,100,161,172,254,181,239,1,11,1,10,155,213,159,176,1,0,161,131,182,180,202,12,50,1,161,131,182,180,202,12,51,1,161,131,182,180,202,12,52,1,161,155,213,159,176,1,0,1,161,155,213,159,176,1,1,1,161,155,213,159,176,1,2,1,129,131,182,180,202,12,43,1,161,155,213,159,176,1,3,1,161,155,213,159,176,1,4,1,161,155,213,159,176,1,5,1,179,1,198,223,206,159,1,0,39,0,204,195,206,156,1,4,6,57,70,53,89,108,75,2,4,0,198,223,206,159,1,0,13,103,104,104,104,229,143,145,230,140,165,229,165,189,168,171,236,222,251,5,166,2,1,119,38,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,103,104,104,104,229,143,145,230,140,165,229,165,189,34,125,93,125,39,0,204,195,206,156,1,4,6,89,50,51,82,99,105,2,4,0,198,223,206,159,1,9,12,229,185,178,230,180,187,229,147,136,229,147,136,168,171,236,222,251,5,240,3,1,119,37,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,229,185,178,230,180,187,229,147,136,229,147,136,34,125,93,125,0,3,39,0,204,195,206,156,1,4,6,72,90,117,111,112,102,2,33,0,204,195,206,156,1,1,6,67,102,80,66,48,85,1,0,7,33,0,204,195,206,156,1,3,6,81,117,121,48,102,66,1,193,171,236,222,251,5,196,1,171,236,222,251,5,170,2,1,1,0,198,223,206,159,1,18,3,0,2,129,198,223,206,159,1,31,1,0,4,39,0,204,195,206,156,1,4,6,48,82,103,55,103,55,2,33,0,204,195,206,156,1,1,6,72,51,76,88,97,79,1,0,7,33,0,204,195,206,156,1,3,6,75,83,56,80,116,80,1,193,171,236,222,251,5,196,1,198,223,206,159,1,28,1,39,0,204,195,206,156,1,4,6,105,90,51,118,76,100,2,33,0,204,195,206,156,1,1,6,121,102,76,72,69,119,1,0,7,33,0,204,195,206,156,1,3,6,48,80,108,53,77,98,1,193,171,236,222,251,5,196,1,198,223,206,159,1,49,1,39,0,204,195,206,156,1,4,6,72,97,76,66,45,86,2,33,0,204,195,206,156,1,1,6,98,65,77,76,51,82,1,0,7,33,0,204,195,206,156,1,3,6,81,83,99,52,51,111,1,193,171,236,222,251,5,196,1,198,223,206,159,1,60,1,39,0,204,195,206,156,1,4,6,98,86,122,115,102,101,2,39,0,204,195,206,156,1,1,6,52,90,113,105,51,76,1,40,0,198,223,206,159,1,73,2,105,100,1,119,6,52,90,113,105,51,76,40,0,198,223,206,159,1,73,2,116,121,1,119,5,113,117,111,116,101,40,0,198,223,206,159,1,73,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,198,223,206,159,1,73,8,99,104,105,108,100,114,101,110,1,119,6,98,50,103,102,70,95,33,0,198,223,206,159,1,73,4,100,97,116,97,1,40,0,198,223,206,159,1,73,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,73,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,98,50,103,102,70,95,0,200,171,236,222,251,5,196,1,198,223,206,159,1,71,1,119,6,52,90,113,105,51,76,4,0,198,223,206,159,1,72,6,231,155,145,230,142,167,168,198,223,206,159,1,78,1,119,31,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,231,155,145,230,142,167,34,125,93,125,196,204,195,206,156,1,244,5,204,195,206,156,1,245,5,9,229,147,136,229,147,136,229,147,136,161,204,195,206,156,1,137,1,1,161,204,195,206,156,1,138,1,1,161,204,195,206,156,1,139,1,1,39,0,204,195,206,156,1,4,6,50,101,101,116,51,53,2,33,0,204,195,206,156,1,1,6,77,103,77,119,109,49,1,0,7,33,0,204,195,206,156,1,3,6,52,76,51,66,86,49,1,193,204,195,206,156,1,232,1,204,195,206,156,1,233,1,1,0,3,39,0,204,195,206,156,1,4,6,100,87,119,54,116,114,2,39,0,204,195,206,156,1,1,6,77,89,55,45,90,70,1,40,0,198,223,206,159,1,107,2,105,100,1,119,6,77,89,55,45,90,70,40,0,198,223,206,159,1,107,2,116,121,1,119,5,113,117,111,116,101,40,0,198,223,206,159,1,107,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,107,8,99,104,105,108,100,114,101,110,1,119,6,112,88,122,66,110,100,33,0,198,223,206,159,1,107,4,100,97,116,97,1,40,0,198,223,206,159,1,107,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,107,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,112,88,122,66,110,100,0,200,204,195,206,156,1,232,1,198,223,206,159,1,102,1,119,6,77,89,55,45,90,70,4,0,198,223,206,159,1,106,9,229,144,140,228,184,128,228,184,170,161,198,223,206,159,1,112,1,132,198,223,206,159,1,119,3,106,106,106,161,198,223,206,159,1,120,1,39,0,204,195,206,156,1,4,6,71,121,120,95,72,54,2,33,0,204,195,206,156,1,1,6,83,101,74,81,114,75,1,0,7,33,0,204,195,206,156,1,3,6,122,116,99,78,71,87,1,193,204,195,206,156,1,232,1,198,223,206,159,1,116,1,0,3,39,0,204,195,206,156,1,4,6,51,107,108,102,97,80,2,39,0,204,195,206,156,1,1,6,85,72,48,53,51,70,1,40,0,198,223,206,159,1,140,1,2,105,100,1,119,6,85,72,48,53,51,70,40,0,198,223,206,159,1,140,1,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,198,223,206,159,1,140,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,140,1,8,99,104,105,108,100,114,101,110,1,119,6,52,75,90,73,113,76,33,0,198,223,206,159,1,140,1,4,100,97,116,97,1,40,0,198,223,206,159,1,140,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,140,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,52,75,90,73,113,76,0,200,204,195,206,156,1,232,1,198,223,206,159,1,135,1,1,119,6,85,72,48,53,51,70,4,0,198,223,206,159,1,139,1,3,104,106,107,161,198,223,206,159,1,145,1,1,39,0,204,195,206,156,1,1,6,114,78,78,65,105,82,1,40,0,198,223,206,159,1,154,1,2,105,100,1,119,6,114,78,78,65,105,82,40,0,198,223,206,159,1,154,1,2,116,121,1,119,13,109,97,116,104,95,101,113,117,97,116,105,111,110,40,0,198,223,206,159,1,154,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,154,1,8,99,104,105,108,100,114,101,110,1,119,6,69,82,69,45,78,66,33,0,198,223,206,159,1,154,1,4,100,97,116,97,1,40,0,198,223,206,159,1,154,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,154,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,69,82,69,45,78,66,0,200,204,195,206,156,1,240,1,204,195,206,156,1,241,1,1,119,6,114,78,78,65,105,82,168,198,223,206,159,1,159,1,1,119,24,123,34,102,111,114,109,117,108,97,34,58,34,105,231,156,139,231,187,143,230,181,142,34,125,39,0,204,195,206,156,1,1,6,68,114,122,68,111,83,1,40,0,198,223,206,159,1,165,1,2,105,100,1,119,6,68,114,122,68,111,83,40,0,198,223,206,159,1,165,1,2,116,121,1,119,5,105,109,97,103,101,40,0,198,223,206,159,1,165,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,165,1,8,99,104,105,108,100,114,101,110,1,119,6,57,68,97,108,108,97,33,0,198,223,206,159,1,165,1,4,100,97,116,97,1,40,0,198,223,206,159,1,165,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,165,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,57,68,97,108,108,97,0,200,204,195,206,156,1,251,1,204,195,206,156,1,252,1,1,119,6,68,114,122,68,111,83,161,198,223,206,159,1,170,1,1,39,0,204,195,206,156,1,4,6,102,80,55,52,75,113,2,33,0,204,195,206,156,1,1,6,84,120,69,107,78,52,1,0,7,33,0,204,195,206,156,1,3,6,104,109,65,56,45,115,1,193,204,195,206,156,1,244,1,204,195,206,156,1,245,1,1,39,0,204,195,206,156,1,4,6,118,105,52,104,122,104,2,39,0,204,195,206,156,1,1,6,95,98,119,81,76,101,1,40,0,198,223,206,159,1,188,1,2,105,100,1,119,6,95,98,119,81,76,101,40,0,198,223,206,159,1,188,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,188,1,6,112,97,114,101,110,116,1,119,10,101,110,68,45,73,83,100,100,99,55,40,0,198,223,206,159,1,188,1,8,99,104,105,108,100,114,101,110,1,119,6,104,102,109,108,88,52,33,0,198,223,206,159,1,188,1,4,100,97,116,97,1,40,0,198,223,206,159,1,188,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,188,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,104,102,109,108,88,52,0,8,0,204,195,206,156,1,23,1,119,6,95,98,119,81,76,101,4,0,198,223,206,159,1,187,1,3,105,106,106,168,198,223,206,159,1,193,1,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,105,106,106,34,125,93,125,39,0,204,195,206,156,1,4,6,55,83,79,113,80,69,2,33,0,204,195,206,156,1,1,6,75,119,55,52,104,73,1,0,7,33,0,204,195,206,156,1,3,6,80,82,74,72,65,95,1,129,198,223,206,159,1,197,1,1,39,0,204,195,206,156,1,4,6,78,97,78,121,113,76,2,39,0,204,195,206,156,1,1,6,72,90,88,98,113,104,1,40,0,198,223,206,159,1,214,1,2,105,100,1,119,6,72,90,88,98,113,104,40,0,198,223,206,159,1,214,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,214,1,6,112,97,114,101,110,116,1,119,6,95,98,119,81,76,101,40,0,198,223,206,159,1,214,1,8,99,104,105,108,100,114,101,110,1,119,6,110,98,72,85,90,106,33,0,198,223,206,159,1,214,1,4,100,97,116,97,1,40,0,198,223,206,159,1,214,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,214,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,110,98,72,85,90,106,0,8,0,198,223,206,159,1,196,1,1,119,6,72,90,88,98,113,104,4,0,198,223,206,159,1,213,1,4,106,107,110,98,168,198,223,206,159,1,219,1,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,106,107,110,98,34,125,93,125,39,0,204,195,206,156,1,4,6,57,56,55,97,106,50,2,33,0,204,195,206,156,1,1,6,110,117,56,75,122,68,1,0,7,33,0,204,195,206,156,1,3,6,85,56,79,113,105,78,1,129,198,223,206,159,1,223,1,1,39,0,204,195,206,156,1,4,6,88,116,82,99,45,53,2,39,0,204,195,206,156,1,1,6,88,52,88,118,49,84,1,40,0,198,223,206,159,1,241,1,2,105,100,1,119,6,88,52,88,118,49,84,40,0,198,223,206,159,1,241,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,241,1,6,112,97,114,101,110,116,1,119,6,72,90,88,98,113,104,40,0,198,223,206,159,1,241,1,8,99,104,105,108,100,114,101,110,1,119,6,119,77,90,48,100,71,33,0,198,223,206,159,1,241,1,4,100,97,116,97,1,40,0,198,223,206,159,1,241,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,241,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,119,77,90,48,100,71,0,8,0,198,223,206,159,1,222,1,1,119,6,88,52,88,118,49,84,4,0,198,223,206,159,1,240,1,6,232,191,155,230,173,165,161,198,223,206,159,1,246,1,1,132,198,223,206,159,1,252,1,6,230,156,186,228,188,154,168,198,223,206,159,1,253,1,1,119,37,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,232,191,155,230,173,165,230,156,186,228,188,154,34,125,93,125,39,0,204,195,206,156,1,4,6,121,85,99,121,82,100,2,39,0,204,195,206,156,1,1,6,100,121,76,82,53,100,1,40,0,198,223,206,159,1,130,2,2,105,100,1,119,6,100,121,76,82,53,100,40,0,198,223,206,159,1,130,2,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,130,2,6,112,97,114,101,110,116,1,119,6,72,90,88,98,113,104,40,0,198,223,206,159,1,130,2,8,99,104,105,108,100,114,101,110,1,119,6,55,89,79,70,48,116,33,0,198,223,206,159,1,130,2,4,100,97,116,97,1,40,0,198,223,206,159,1,130,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,130,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,55,89,79,70,48,116,0,136,198,223,206,159,1,250,1,1,119,6,100,121,76,82,53,100,4,0,198,223,206,159,1,129,2,12,230,150,164,230,150,164,232,174,161,232,190,131,168,198,223,206,159,1,135,2,1,119,37,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,230,150,164,230,150,164,232,174,161,232,190,131,34,125,93,125,230,2,204,195,206,156,1,0,39,1,4,100,97,116,97,8,100,111,99,117,109,101,110,116,1,39,0,204,195,206,156,1,0,6,98,108,111,99,107,115,1,39,0,204,195,206,156,1,0,4,109,101,116,97,1,39,0,204,195,206,156,1,2,12,99,104,105,108,100,114,101,110,95,109,97,112,1,39,0,204,195,206,156,1,2,8,116,101,120,116,95,109,97,112,1,40,0,204,195,206,156,1,0,7,112,97,103,101,95,105,100,1,119,10,109,54,120,76,118,72,89,48,76,107,39,0,204,195,206,156,1,1,10,77,48,104,84,99,67,120,66,88,82,1,40,0,204,195,206,156,1,6,2,105,100,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,204,195,206,156,1,6,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,6,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,6,8,99,104,105,108,100,114,101,110,1,119,10,49,87,78,107,89,75,118,109,105,50,33,0,204,195,206,156,1,6,4,100,97,116,97,1,33,0,204,195,206,156,1,6,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,49,87,78,107,89,75,118,109,105,50,0,39,0,204,195,206,156,1,1,10,101,110,68,45,73,83,100,100,99,55,1,40,0,204,195,206,156,1,15,2,105,100,1,119,10,101,110,68,45,73,83,100,100,99,55,40,0,204,195,206,156,1,15,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,204,195,206,156,1,15,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,15,8,99,104,105,108,100,114,101,110,1,119,10,103,106,110,76,109,66,89,118,68,65,40,0,204,195,206,156,1,15,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,15,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,102,56,54,108,88,117,88,74,101,54,40,0,204,195,206,156,1,15,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,103,106,110,76,109,66,89,118,68,65,0,39,0,204,195,206,156,1,1,10,113,115,110,89,82,48,74,72,74,56,1,40,0,204,195,206,156,1,24,2,105,100,1,119,10,113,115,110,89,82,48,74,72,74,56,40,0,204,195,206,156,1,24,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,24,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,24,8,99,104,105,108,100,114,101,110,1,119,10,116,79,53,122,78,78,73,82,69,100,40,0,204,195,206,156,1,24,4,100,97,116,97,1,119,17,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,40,0,204,195,206,156,1,24,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,51,72,115,115,121,121,66,84,57,50,40,0,204,195,206,156,1,24,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,116,79,53,122,78,78,73,82,69,100,0,39,0,204,195,206,156,1,1,10,75,54,50,76,100,101,119,53,95,121,1,40,0,204,195,206,156,1,33,2,105,100,1,119,10,75,54,50,76,100,101,119,53,95,121,40,0,204,195,206,156,1,33,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,204,195,206,156,1,33,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,33,8,99,104,105,108,100,114,101,110,1,119,10,57,118,109,120,98,73,71,120,109,73,40,0,204,195,206,156,1,33,4,100,97,116,97,1,119,11,123,34,108,101,118,101,108,34,58,50,125,40,0,204,195,206,156,1,33,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,72,116,114,88,117,57,102,65,95,107,40,0,204,195,206,156,1,33,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,57,118,109,120,98,73,71,120,109,73,0,39,0,204,195,206,156,1,1,10,117,51,120,66,95,83,69,116,53,68,1,40,0,204,195,206,156,1,42,2,105,100,1,119,10,117,51,120,66,95,83,69,116,53,68,40,0,204,195,206,156,1,42,2,116,121,1,119,7,99,97,108,108,111,117,116,40,0,204,195,206,156,1,42,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,42,8,99,104,105,108,100,114,101,110,1,119,10,50,88,118,55,52,84,105,73,70,108,40,0,204,195,206,156,1,42,4,100,97,116,97,1,119,15,123,34,105,99,111,110,34,58,34,240,159,165,176,34,125,40,0,204,195,206,156,1,42,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,108,119,101,104,75,79,117,78,68,67,40,0,204,195,206,156,1,42,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,50,88,118,55,52,84,105,73,70,108,0,39,0,204,195,206,156,1,1,10,78,73,76,105,97,84,121,72,108,112,1,40,0,204,195,206,156,1,51,2,105,100,1,119,10,78,73,76,105,97,84,121,72,108,112,40,0,204,195,206,156,1,51,2,116,121,1,119,5,113,117,111,116,101,40,0,204,195,206,156,1,51,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,51,8,99,104,105,108,100,114,101,110,1,119,10,109,82,95,75,65,57,45,108,110,78,40,0,204,195,206,156,1,51,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,51,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,119,86,82,81,117,71,111,121,116,48,40,0,204,195,206,156,1,51,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,109,82,95,75,65,57,45,108,110,78,0,33,0,204,195,206,156,1,1,10,99,108,78,111,66,75,99,119,73,82,1,0,7,33,0,204,195,206,156,1,3,10,117,117,65,100,55,95,119,72,72,106,1,39,0,204,195,206,156,1,1,10,78,89,54,108,121,101,57,108,88,51,1,40,0,204,195,206,156,1,69,2,105,100,1,119,10,78,89,54,108,121,101,57,108,88,51,40,0,204,195,206,156,1,69,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,69,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,69,8,99,104,105,108,100,114,101,110,1,119,10,108,77,72,53,73,113,54,77,68,78,40,0,204,195,206,156,1,69,4,100,97,116,97,1,119,17,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,40,0,204,195,206,156,1,69,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,109,69,119,56,90,66,102,95,100,68,40,0,204,195,206,156,1,69,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,108,77,72,53,73,113,54,77,68,78,0,39,0,204,195,206,156,1,1,10,101,104,73,115,79,74,69,114,55,73,1,40,0,204,195,206,156,1,78,2,105,100,1,119,10,101,104,73,115,79,74,69,114,55,73,40,0,204,195,206,156,1,78,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,204,195,206,156,1,78,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,78,8,99,104,105,108,100,114,101,110,1,119,10,56,116,67,52,100,103,121,98,57,55,40,0,204,195,206,156,1,78,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,78,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,107,106,48,68,49,121,121,88,78,119,40,0,204,195,206,156,1,78,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,56,116,67,52,100,103,121,98,57,55,0,39,0,204,195,206,156,1,1,10,68,90,114,95,72,118,106,65,78,107,1,40,0,204,195,206,156,1,87,2,105,100,1,119,10,68,90,114,95,72,118,106,65,78,107,40,0,204,195,206,156,1,87,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,87,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,87,8,99,104,105,108,100,114,101,110,1,119,10,119,95,65,55,90,114,77,89,86,122,40,0,204,195,206,156,1,87,4,100,97,116,97,1,119,17,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,40,0,204,195,206,156,1,87,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,54,74,108,118,72,71,53,111,120,90,40,0,204,195,206,156,1,87,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,119,95,65,55,90,114,77,89,86,122,0,33,0,204,195,206,156,1,1,10,105,90,113,50,95,68,72,49,50,69,1,0,7,33,0,204,195,206,156,1,3,10,119,54,53,71,114,77,54,109,119,69,1,39,0,204,195,206,156,1,1,10,48,105,122,109,122,95,86,65,55,70,1,40,0,204,195,206,156,1,105,2,105,100,1,119,10,48,105,122,109,122,95,86,65,55,70,40,0,204,195,206,156,1,105,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,204,195,206,156,1,105,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,105,8,99,104,105,108,100,114,101,110,1,119,10,65,90,49,50,53,79,88,51,65,97,40,0,204,195,206,156,1,105,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,105,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,109,73,73,113,81,111,118,74,105,101,40,0,204,195,206,156,1,105,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,65,90,49,50,53,79,88,51,65,97,0,39,0,204,195,206,156,1,1,10,55,107,121,57,118,72,100,98,90,90,1,40,0,204,195,206,156,1,114,2,105,100,1,119,10,55,107,121,57,118,72,100,98,90,90,40,0,204,195,206,156,1,114,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,114,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,114,8,99,104,105,108,100,114,101,110,1,119,10,118,122,73,48,69,73,102,97,111,55,33,0,204,195,206,156,1,114,4,100,97,116,97,1,33,0,204,195,206,156,1,114,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,114,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,118,122,73,48,69,73,102,97,111,55,0,39,0,204,195,206,156,1,1,10,76,77,51,100,74,90,103,105,119,106,1,40,0,204,195,206,156,1,123,2,105,100,1,119,10,76,77,51,100,74,90,103,105,119,106,40,0,204,195,206,156,1,123,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,204,195,206,156,1,123,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,123,8,99,104,105,108,100,114,101,110,1,119,10,65,49,72,80,70,85,72,104,51,86,40,0,204,195,206,156,1,123,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,123,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,120,116,103,85,69,74,52,104,81,95,40,0,204,195,206,156,1,123,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,65,49,72,80,70,85,72,104,51,86,0,39,0,204,195,206,156,1,1,10,109,73,66,54,73,106,49,57,52,77,1,40,0,204,195,206,156,1,132,1,2,105,100,1,119,10,109,73,66,54,73,106,49,57,52,77,40,0,204,195,206,156,1,132,1,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,132,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,132,1,8,99,104,105,108,100,114,101,110,1,119,10,121,56,100,54,52,108,75,54,81,109,33,0,204,195,206,156,1,132,1,4,100,97,116,97,1,33,0,204,195,206,156,1,132,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,132,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,121,56,100,54,52,108,75,54,81,109,0,39,0,204,195,206,156,1,1,10,109,79,82,56,99,51,71,108,104,101,1,40,0,204,195,206,156,1,141,1,2,105,100,1,119,10,109,79,82,56,99,51,71,108,104,101,40,0,204,195,206,156,1,141,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,204,195,206,156,1,141,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,141,1,8,99,104,105,108,100,114,101,110,1,119,10,75,50,75,54,117,121,80,56,108,65,40,0,204,195,206,156,1,141,1,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,141,1,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,52,97,84,122,117,113,66,107,110,70,40,0,204,195,206,156,1,141,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,75,50,75,54,117,121,80,56,108,65,0,39,0,204,195,206,156,1,1,10,118,110,69,86,85,50,114,57,65,88,1,40,0,204,195,206,156,1,150,1,2,105,100,1,119,10,118,110,69,86,85,50,114,57,65,88,40,0,204,195,206,156,1,150,1,2,116,121,1,119,4,99,111,100,101,40,0,204,195,206,156,1,150,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,150,1,8,99,104,105,108,100,114,101,110,1,119,10,75,119,115,101,107,79,85,115,115,57,33,0,204,195,206,156,1,150,1,4,100,97,116,97,1,33,0,204,195,206,156,1,150,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,150,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,75,119,115,101,107,79,85,115,115,57,0,39,0,204,195,206,156,1,1,10,104,87,121,95,110,110,79,73,101,108,1,40,0,204,195,206,156,1,159,1,2,105,100,1,119,10,104,87,121,95,110,110,79,73,101,108,40,0,204,195,206,156,1,159,1,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,204,195,206,156,1,159,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,159,1,8,99,104,105,108,100,114,101,110,1,119,10,95,74,97,104,108,70,88,117,82,109,33,0,204,195,206,156,1,159,1,4,100,97,116,97,1,33,0,204,195,206,156,1,159,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,159,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,95,74,97,104,108,70,88,117,82,109,0,33,0,204,195,206,156,1,1,10,71,45,117,115,79,56,75,107,81,81,1,0,7,33,0,204,195,206,156,1,3,10,56,112,113,84,95,112,120,118,65,78,1,33,0,204,195,206,156,1,1,10,87,114,65,73,121,89,90,76,79,110,1,0,7,33,0,204,195,206,156,1,3,10,89,100,82,106,88,106,109,55,118,114,1,33,0,204,195,206,156,1,1,10,95,90,102,110,119,90,114,87,68,105,1,0,7,33,0,204,195,206,156,1,3,10,49,86,117,68,73,110,45,56,100,114,1,39,0,204,195,206,156,1,1,10,82,50,56,82,106,69,66,70,99,71,1,40,0,204,195,206,156,1,195,1,2,105,100,1,119,10,82,50,56,82,106,69,66,70,99,71,40,0,204,195,206,156,1,195,1,2,116,121,1,119,7,100,105,118,105,100,101,114,40,0,204,195,206,156,1,195,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,195,1,8,99,104,105,108,100,114,101,110,1,119,10,119,115,98,50,74,101,113,52,87,71,40,0,204,195,206,156,1,195,1,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,195,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,204,195,206,156,1,195,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,10,119,115,98,50,74,101,113,52,87,71,0,39,0,204,195,206,156,1,1,10,109,54,120,76,118,72,89,48,76,107,1,40,0,204,195,206,156,1,204,1,2,105,100,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,204,1,2,116,121,1,119,4,112,97,103,101,40,0,204,195,206,156,1,204,1,6,112,97,114,101,110,116,1,119,0,40,0,204,195,206,156,1,204,1,8,99,104,105,108,100,114,101,110,1,119,10,120,68,48,121,90,73,118,109,51,115,33,0,204,195,206,156,1,204,1,4,100,97,116,97,1,33,0,204,195,206,156,1,204,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,204,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,120,68,48,121,90,73,118,109,51,115,0,33,0,204,195,206,156,1,1,10,97,115,74,118,54,70,114,65,82,97,1,0,7,33,0,204,195,206,156,1,3,10,68,75,70,79,99,81,75,54,52,72,1,39,0,204,195,206,156,1,1,10,119,70,86,108,107,88,117,108,104,74,1,40,0,204,195,206,156,1,222,1,2,105,100,1,119,10,119,70,86,108,107,88,117,108,104,74,40,0,204,195,206,156,1,222,1,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,204,195,206,156,1,222,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,222,1,8,99,104,105,108,100,114,101,110,1,119,10,69,113,72,71,75,105,54,115,68,53,33,0,204,195,206,156,1,222,1,4,100,97,116,97,1,33,0,204,195,206,156,1,222,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,222,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,69,113,72,71,75,105,54,115,68,53,0,8,0,204,195,206,156,1,212,1,1,119,10,119,70,86,108,107,88,117,108,104,74,129,204,195,206,156,1,231,1,1,136,204,195,206,156,1,232,1,6,119,10,109,73,66,54,73,106,49,57,52,77,119,10,78,89,54,108,121,101,57,108,88,51,119,10,68,90,114,95,72,118,106,65,78,107,119,10,113,115,110,89,82,48,74,72,74,56,119,10,55,107,121,57,118,72,100,98,90,90,119,10,77,48,104,84,99,67,120,66,88,82,129,204,195,206,156,1,238,1,1,136,204,195,206,156,1,239,1,1,119,10,82,50,56,82,106,69,66,70,99,71,129,204,195,206,156,1,240,1,1,136,204,195,206,156,1,241,1,1,119,10,104,87,121,95,110,110,79,73,101,108,136,204,195,206,156,1,242,1,2,119,10,48,105,122,109,122,95,86,65,55,70,119,10,101,110,68,45,73,83,100,100,99,55,136,204,195,206,156,1,244,1,2,119,10,109,79,82,56,99,51,71,108,104,101,119,10,118,110,69,86,85,50,114,57,65,88,129,204,195,206,156,1,246,1,1,136,204,195,206,156,1,247,1,4,119,10,75,54,50,76,100,101,119,53,95,121,119,10,78,73,76,105,97,84,121,72,108,112,119,10,101,104,73,115,79,74,69,114,55,73,119,10,117,51,120,66,95,83,69,116,53,68,129,204,195,206,156,1,251,1,1,136,204,195,206,156,1,252,1,1,119,10,76,77,51,100,74,90,103,105,119,106,129,204,195,206,156,1,253,1,1,39,0,204,195,206,156,1,4,10,97,98,100,49,105,117,71,81,109,68,2,4,0,204,195,206,156,1,255,1,44,75,101,121,98,111,97,114,100,32,115,104,111,114,116,99,117,116,115,44,32,109,97,114,107,100,111,119,110,44,32,97,110,100,32,99,111,100,101,32,98,108,111,99,107,39,0,204,195,206,156,1,4,10,54,74,108,118,72,71,53,111,120,90,2,4,0,204,195,206,156,1,172,2,20,65,115,32,115,111,111,110,32,97,115,32,121,111,117,32,116,121,112,101,32,134,204,195,206,156,1,192,2,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,48,48,98,53,102,102,34,134,204,195,206,156,1,193,2,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,194,2,1,47,134,204,195,206,156,1,195,2,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,134,204,195,206,156,1,196,2,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,197,2,28,32,97,32,109,101,110,117,32,119,105,108,108,32,112,111,112,32,117,112,46,32,83,101,108,101,99,116,32,134,204,195,206,156,1,225,2,8,98,103,95,99,111,108,111,114,12,34,48,120,52,100,57,99,50,55,98,48,34,132,204,195,206,156,1,226,2,15,100,105,102,102,101,114,101,110,116,32,116,121,112,101,115,134,204,195,206,156,1,241,2,8,98,103,95,99,111,108,111,114,4,110,117,108,108,132,204,195,206,156,1,242,2,31,32,111,102,32,99,111,110,116,101,110,116,32,98,108,111,99,107,115,32,121,111,117,32,99,97,110,32,97,100,100,46,39,0,204,195,206,156,1,4,10,51,72,115,115,121,121,66,84,57,50,2,4,0,204,195,206,156,1,146,3,5,84,121,112,101,32,134,204,195,206,156,1,151,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,152,3,1,47,134,204,195,206,156,1,153,3,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,154,3,13,32,102,111,108,108,111,119,101,100,32,98,121,32,134,204,195,206,156,1,167,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,168,3,7,47,98,117,108,108,101,116,134,204,195,206,156,1,175,3,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,176,3,4,32,111,114,32,134,204,195,206,156,1,180,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,181,3,4,47,110,117,109,134,204,195,206,156,1,185,3,4,99,111,100,101,4,110,117,108,108,198,204,195,206,156,1,185,3,204,195,206,156,1,186,3,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,187,3,204,195,206,156,1,186,3,18,32,116,111,32,99,114,101,97,116,101,32,97,32,108,105,115,116,46,198,204,195,206,156,1,205,3,204,195,206,156,1,186,3,4,99,111,100,101,4,116,114,117,101,33,0,204,195,206,156,1,4,10,84,82,53,102,106,82,122,115,114,105,1,39,0,204,195,206,156,1,4,10,119,86,82,81,117,71,111,121,116,48,2,4,0,204,195,206,156,1,208,3,6,67,108,105,99,107,32,134,204,195,206,156,1,214,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,215,3,1,63,134,204,195,206,156,1,216,3,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,217,3,42,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,114,105,103,104,116,32,102,111,114,32,104,101,108,112,32,97,110,100,32,115,117,112,112,111,114,116,46,39,0,204,195,206,156,1,4,10,107,106,48,68,49,121,121,88,78,119,2,39,0,204,195,206,156,1,4,10,120,116,103,85,69,74,52,104,81,95,2,39,0,204,195,206,156,1,4,10,112,70,113,76,55,45,79,83,121,86,2,4,0,204,195,206,156,1,134,4,0,33,0,204,195,206,156,1,4,10,102,114,97,74,99,70,55,54,70,99,1,39,0,204,195,206,156,1,4,10,122,77,121,109,67,97,118,83,107,102,2,4,0,204,195,206,156,1,136,4,6,67,108,105,99,107,32,134,204,195,206,156,1,142,4,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,143,4,11,43,32,78,101,119,32,80,97,103,101,32,134,204,195,206,156,1,154,4,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,155,4,50,98,117,116,116,111,110,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,111,102,32,121,111,117,114,32,115,105,100,101,98,97,114,32,116,111,32,97,100,100,32,97,32,110,101,119,32,129,204,195,206,156,1,205,4,4,132,204,195,206,156,1,209,4,1,46,39,0,204,195,206,156,1,4,10,72,116,114,88,117,57,102,65,95,107,2,4,0,204,195,206,156,1,211,4,18,72,97,118,101,32,97,32,113,117,101,115,116,105,111,110,226,157,147,39,0,204,195,206,156,1,4,10,49,112,115,100,67,122,97,87,104,49,2,4,0,204,195,206,156,1,228,4,30,47,47,32,84,104,105,115,32,105,115,32,116,104,101,32,109,97,105,110,32,102,117,110,99,116,105,111,110,46,10,129,204,195,206,156,1,130,5,77,39,0,204,195,206,156,1,4,10,119,79,108,117,99,85,55,51,73,76,2,4,0,204,195,206,156,1,208,5,36,67,108,105,99,107,32,97,110,121,119,104,101,114,101,32,97,110,100,32,106,117,115,116,32,115,116,97,114,116,32,116,121,112,105,110,103,132,204,195,206,156,1,244,5,1,46,33,0,204,195,206,156,1,4,10,69,72,117,95,67,112,120,53,67,103,1,39,0,204,195,206,156,1,4,10,98,113,76,109,98,57,111,45,109,109,2,4,0,204,195,206,156,1,247,5,6,67,108,105,99,107,32,134,204,195,206,156,1,253,5,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,254,5,1,43,134,204,195,206,156,1,255,5,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,128,6,1,32,129,204,195,206,156,1,129,6,4,132,204,195,206,156,1,133,6,37,32,116,111,32,97,110,121,32,112,97,103,101,32,116,105,116,108,101,32,105,110,32,116,104,101,32,115,105,100,101,98,97,114,32,116,111,32,134,204,195,206,156,1,170,6,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,56,52,50,55,101,48,34,132,204,195,206,156,1,171,6,7,113,117,105,99,107,108,121,134,204,195,206,156,1,178,6,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,132,204,195,206,156,1,179,6,1,32,129,204,195,206,156,1,180,6,3,132,204,195,206,156,1,183,6,16,32,97,32,110,101,119,32,115,117,98,112,97,103,101,44,32,134,204,195,206,156,1,199,6,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,200,6,8,68,111,99,117,109,101,110,116,134,204,195,206,156,1,208,6,4,99,111,100,101,4,110,117,108,108,198,204,195,206,156,1,208,6,204,195,206,156,1,209,6,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,210,6,204,195,206,156,1,209,6,2,44,32,198,204,195,206,156,1,212,6,204,195,206,156,1,209,6,4,99,111,100,101,4,116,114,117,101,196,204,195,206,156,1,213,6,204,195,206,156,1,209,6,4,71,114,105,100,198,204,195,206,156,1,217,6,204,195,206,156,1,209,6,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,218,6,204,195,206,156,1,209,6,5,44,32,111,114,32,198,204,195,206,156,1,223,6,204,195,206,156,1,209,6,4,99,111,100,101,4,116,114,117,101,196,204,195,206,156,1,224,6,204,195,206,156,1,209,6,12,75,97,110,98,97,110,32,66,111,97,114,100,198,204,195,206,156,1,236,6,204,195,206,156,1,209,6,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,237,6,204,195,206,156,1,209,6,1,46,198,204,195,206,156,1,238,6,204,195,206,156,1,209,6,4,99,111,100,101,4,116,114,117,101,39,0,204,195,206,156,1,4,10,102,56,54,108,88,117,88,74,101,54,2,4,0,204,195,206,156,1,240,6,9,77,97,114,107,100,111,119,110,32,134,204,195,206,156,1,249,6,4,104,114,101,102,67,34,104,116,116,112,115,58,47,47,97,112,112,102,108,111,119,121,46,103,105,116,98,111,111,107,46,105,111,47,100,111,99,115,47,101,115,115,101,110,116,105,97,108,45,100,111,99,117,109,101,110,116,97,116,105,111,110,47,109,97,114,107,100,111,119,110,34,132,204,195,206,156,1,250,6,9,114,101,102,101,114,101,110,99,101,134,204,195,206,156,1,131,7,4,104,114,101,102,4,110,117,108,108,33,0,204,195,206,156,1,4,10,89,74,119,52,70,81,88,106,110,84,1,39,0,204,195,206,156,1,4,10,119,88,107,79,72,81,49,50,99,111,2,1,0,204,195,206,156,1,134,7,20,33,0,204,195,206,156,1,4,10,65,108,73,86,97,121,54,119,80,104,1,0,19,39,0,204,195,206,156,1,4,10,109,69,119,56,90,66,102,95,100,68,2,6,0,204,195,206,156,1,175,7,8,98,103,95,99,111,108,111,114,12,34,48,120,52,100,102,102,101,98,51,98,34,132,204,195,206,156,1,176,7,10,72,105,103,104,108,105,103,104,116,32,134,204,195,206,156,1,186,7,8,98,103,95,99,111,108,111,114,4,110,117,108,108,132,204,195,206,156,1,187,7,38,97,110,121,32,116,101,120,116,44,32,97,110,100,32,117,115,101,32,116,104,101,32,101,100,105,116,105,110,103,32,109,101,110,117,32,116,111,32,134,204,195,206,156,1,225,7,6,105,116,97,108,105,99,4,116,114,117,101,132,204,195,206,156,1,226,7,5,115,116,121,108,101,134,204,195,206,156,1,231,7,6,105,116,97,108,105,99,4,110,117,108,108,132,204,195,206,156,1,232,7,1,32,134,204,195,206,156,1,233,7,4,98,111,108,100,4,116,114,117,101,132,204,195,206,156,1,234,7,4,121,111,117,114,134,204,195,206,156,1,238,7,4,98,111,108,100,4,110,117,108,108,132,204,195,206,156,1,239,7,1,32,134,204,195,206,156,1,240,7,9,117,110,100,101,114,108,105,110,101,4,116,114,117,101,132,204,195,206,156,1,241,7,7,119,114,105,116,105,110,103,134,204,195,206,156,1,248,7,9,117,110,100,101,114,108,105,110,101,4,110,117,108,108,132,204,195,206,156,1,249,7,1,32,134,204,195,206,156,1,250,7,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,251,7,7,104,111,119,101,118,101,114,134,204,195,206,156,1,130,8,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,131,8,5,32,121,111,117,32,134,204,195,206,156,1,136,8,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,116,114,117,101,132,204,195,206,156,1,137,8,5,108,105,107,101,46,134,204,195,206,156,1,142,8,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,110,117,108,108,33,0,204,195,206,156,1,4,10,98,122,103,70,79,75,118,99,117,89,1,39,0,204,195,206,156,1,4,10,52,97,84,122,117,113,66,107,110,70,2,4,0,204,195,206,156,1,145,8,5,84,121,112,101,32,134,204,195,206,156,1,150,8,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,151,8,5,47,99,111,100,101,134,204,195,206,156,1,156,8,4,99,111,100,101,4,110,117,108,108,198,204,195,206,156,1,156,8,204,195,206,156,1,157,8,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,158,8,204,195,206,156,1,157,8,23,32,116,111,32,105,110,115,101,114,116,32,97,32,99,111,100,101,32,98,108,111,99,107,198,204,195,206,156,1,181,8,204,195,206,156,1,157,8,4,99,111,100,101,4,116,114,117,101,39,0,204,195,206,156,1,4,10,108,119,101,104,75,79,117,78,68,67,2,4,0,204,195,206,156,1,183,8,27,10,76,105,107,101,32,65,112,112,70,108,111,119,121,63,32,70,111,108,108,111,119,32,117,115,58,10,134,204,195,206,156,1,210,8,4,104,114,101,102,41,34,104,116,116,112,115,58,47,47,103,105,116,104,117,98,46,99,111,109,47,65,112,112,70,108,111,119,121,45,73,79,47,65,112,112,70,108,111,119,121,34,132,204,195,206,156,1,211,8,6,71,105,116,72,117,98,134,204,195,206,156,1,217,8,4,104,114,101,102,4,110,117,108,108,132,204,195,206,156,1,218,8,1,10,134,204,195,206,156,1,219,8,4,104,114,101,102,30,34,104,116,116,112,115,58,47,47,116,119,105,116,116,101,114,46,99,111,109,47,97,112,112,102,108,111,119,121,34,132,204,195,206,156,1,220,8,7,84,119,105,116,116,101,114,134,204,195,206,156,1,227,8,4,104,114,101,102,4,110,117,108,108,132,204,195,206,156,1,228,8,12,58,32,64,97,112,112,102,108,111,119,121,10,134,204,195,206,156,1,240,8,4,104,114,101,102,33,34,104,116,116,112,115,58,47,47,98,108,111,103,45,97,112,112,102,108,111,119,121,46,103,104,111,115,116,46,105,111,47,34,132,204,195,206,156,1,241,8,10,78,101,119,115,108,101,116,116,101,114,134,204,195,206,156,1,251,8,4,104,114,101,102,4,110,117,108,108,132,204,195,206,156,1,252,8,1,10,39,0,204,195,206,156,1,4,10,109,73,73,113,81,111,118,74,105,101,2,4,0,204,195,206,156,1,254,8,19,75,101,121,98,111,97,114,100,32,115,104,111,114,116,99,117,116,115,32,134,204,195,206,156,1,145,9,4,104,114,101,102,68,34,104,116,116,112,115,58,47,47,97,112,112,102,108,111,119,121,46,103,105,116,98,111,111,107,46,105,111,47,100,111,99,115,47,101,115,115,101,110,116,105,97,108,45,100,111,99,117,109,101,110,116,97,116,105,111,110,47,115,104,111,114,116,99,117,116,115,34,132,204,195,206,156,1,146,9,5,103,117,105,100,101,134,204,195,206,156,1,151,9,4,104,114,101,102,4,110,117,108,108,1,141,178,210,127,0,0,3,1,206,214,243,86,0,161,236,158,128,159,2,3,178,1,1,229,154,194,35,0,161,136,172,186,168,4,181,6,178,1,1,218,255,204,32,0,161,150,152,188,203,6,19,21,41,192,246,139,213,2,1,0,35,131,182,180,202,12,1,0,53,132,236,218,251,9,1,0,14,197,205,192,233,12,1,0,9,198,223,206,159,1,25,15,3,19,20,40,10,51,10,62,10,78,1,89,3,93,13,112,1,120,1,124,1,126,13,145,1,1,153,1,1,159,1,1,170,1,1,175,1,1,177,1,10,193,1,1,203,1,10,219,1,1,230,1,10,246,1,1,253,1,1,135,2,1,199,130,209,189,2,202,1,4,11,16,1,19,12,33,1,35,1,37,1,39,1,41,1,43,1,45,1,47,1,49,1,56,1,61,1,63,1,65,1,67,1,69,1,71,1,73,1,75,1,77,1,79,1,81,1,83,1,85,1,87,1,89,1,91,1,93,1,95,1,102,1,107,1,109,1,111,1,113,1,115,1,117,1,119,1,121,1,123,1,125,4,136,1,1,144,1,1,152,1,1,160,1,1,168,1,1,176,1,1,184,1,1,192,1,1,200,1,1,208,1,1,216,1,1,224,1,1,232,1,1,240,1,1,248,1,1,128,2,1,136,2,1,144,2,1,152,2,1,160,2,1,168,2,1,176,2,1,184,2,1,192,2,1,200,2,2,208,2,1,213,2,1,215,2,27,246,2,21,140,3,1,142,3,1,144,3,1,146,3,1,153,3,1,162,3,10,177,3,1,183,3,10,202,3,1,212,3,1,222,3,1,232,3,1,242,3,1,252,3,1,134,4,1,144,4,1,154,4,1,159,4,1,161,4,1,163,4,1,165,4,1,167,4,1,169,4,1,171,4,1,173,4,1,175,4,1,177,4,5,188,4,1,193,4,6,200,4,10,216,4,1,221,4,6,228,4,10,244,4,1,249,4,6,133,5,1,138,5,6,145,5,10,156,5,1,158,5,1,160,5,1,162,5,3,170,5,1,175,5,6,182,5,16,199,5,1,206,5,1,211,5,6,223,5,1,228,5,7,236,5,10,252,5,1,129,6,6,136,6,10,147,6,10,158,6,1,160,6,1,162,6,1,178,6,1,180,6,2,183,6,2,186,6,1,188,6,1,190,6,1,192,6,1,194,6,1,196,6,1,198,6,1,200,6,1,202,6,1,206,6,1,208,6,1,210,6,1,212,6,1,214,6,4,219,6,1,223,6,1,225,6,1,227,6,1,229,6,1,231,6,1,233,6,1,235,6,1,237,6,1,241,6,1,243,6,1,245,6,1,247,6,1,249,6,1,251,6,1,253,6,1,255,6,1,131,7,1,133,7,1,135,7,1,137,7,1,139,7,1,141,7,1,144,7,21,166,7,1,168,7,1,170,7,1,172,7,1,174,7,1,176,7,1,178,7,1,180,7,1,182,7,1,184,7,1,188,7,1,190,7,1,192,7,1,194,7,1,196,7,1,198,7,4,205,7,1,207,7,1,209,7,1,211,7,1,213,7,1,215,7,1,217,7,13,231,7,1,240,7,1,248,7,2,252,7,3,130,8,1,132,8,1,134,8,1,136,8,2,139,8,2,136,172,186,168,4,1,0,182,6,204,195,206,156,1,27,11,3,60,9,96,9,119,3,137,1,3,155,1,3,164,1,3,168,1,27,209,1,3,213,1,9,227,1,3,232,1,1,239,1,1,241,1,1,247,1,1,252,1,1,254,1,1,207,3,1,135,4,1,206,4,4,131,5,77,246,5,1,130,6,4,181,6,3,133,7,1,135,7,40,144,8,1,141,178,210,127,1,0,3,140,167,201,161,14,1,0,4,142,211,188,164,13,1,0,15,206,214,243,86,1,0,178,1,146,216,250,133,2,1,0,180,1,150,152,188,203,6,1,0,20,151,234,142,238,11,1,0,27,150,216,171,142,3,86,0,171,3,172,3,3,176,3,3,180,3,3,184,3,3,188,3,3,192,3,3,196,3,3,200,3,3,204,3,3,208,3,3,212,3,3,216,3,3,220,3,3,224,3,3,228,3,3,232,3,3,236,3,3,240,3,3,244,3,3,248,3,3,253,3,3,129,4,3,133,4,3,137,4,3,141,4,3,145,4,3,149,4,3,153,4,3,157,4,3,161,4,3,165,4,3,169,4,3,173,4,3,177,4,3,181,4,3,185,4,3,189,4,3,193,4,3,197,4,3,201,4,3,205,4,3,209,4,3,213,4,3,217,4,3,221,4,3,225,4,3,229,4,7,254,4,10,138,5,1,140,5,1,142,5,1,149,5,1,155,5,1,157,5,1,159,5,1,166,5,11,178,5,15,200,5,1,210,5,1,220,5,1,230,5,1,235,5,1,237,5,1,239,5,1,241,5,1,245,5,1,251,5,1,133,6,1,138,6,1,144,6,1,154,6,1,164,6,1,174,6,1,180,6,1,182,6,1,184,6,1,186,6,5,216,6,3,231,6,14,188,7,6,158,8,1,160,8,1,162,8,1,164,8,3,168,8,3,217,168,198,159,4,1,0,7,218,255,204,32,1,0,21,155,213,159,176,1,1,0,10,219,200,174,197,9,1,0,25,224,159,166,178,15,1,0,30,161,234,157,145,5,1,0,7,226,167,254,250,5,3,8,1,10,1,12,1,228,242,134,215,15,4,5,1,7,1,9,1,11,1,165,131,171,211,15,1,0,20,229,154,194,35,1,0,178,1,164,202,219,213,10,18,19,10,31,10,42,1,44,10,55,1,57,1,59,1,61,3,67,1,77,7,85,1,87,1,89,1,91,1,93,1,95,1,97,1,117,1,168,215,223,235,2,1,0,3,171,236,222,251,5,69,9,5,15,11,27,8,36,3,40,4,45,8,54,8,63,3,72,3,76,3,80,3,84,3,88,3,92,3,96,3,102,3,106,10,120,10,131,1,10,142,1,10,153,1,10,169,1,1,176,1,2,179,1,1,181,1,1,187,1,10,201,1,1,207,1,10,222,1,10,237,1,17,131,2,10,146,2,10,166,2,1,172,2,10,186,2,1,192,2,10,207,2,10,222,2,10,237,2,10,252,2,10,139,3,10,150,3,18,169,3,15,185,3,1,202,3,1,208,3,1,210,3,1,212,3,1,240,3,1,245,3,10,128,4,4,137,4,1,142,4,7,150,4,6,157,4,6,164,4,6,171,4,6,178,4,6,185,4,6,192,4,6,199,4,1,201,4,4,206,4,7,214,4,6,221,4,6,228,4,6,235,4,6,242,4,1,249,4,1,172,254,181,239,1,4,5,1,8,1,11,1,14,1,236,158,128,159,2,1,0,4,239,239,208,251,10,1,0,17,176,238,158,139,14,1,0,175,2,241,147,239,232,6,1,0,4,178,187,245,161,14,2,8,1,10,1,243,138,171,183,10,2,0,240,1,243,1,3,245,181,155,135,2,1,0,23,181,156,253,158,6,1,0,4,247,212,219,208,10,1,0,46,184,146,243,216,14,1,0,7,190,183,139,210,2,1,0,109],"version":0},"code":0,"message":"Operation completed successfully."} \ No newline at end of file +{"data":{"state_vector":[74,131,182,180,202,12,53,132,236,218,251,9,14,131,159,159,151,1,72,131,128,202,229,9,1,135,182,134,178,8,51,136,172,186,168,4,182,6,136,199,176,231,9,40,133,181,204,218,3,50,140,167,201,161,14,10,141,151,160,163,4,24,142,211,188,164,13,15,141,178,210,127,3,145,224,235,133,7,3,146,209,153,247,13,186,1,146,216,250,133,2,180,1,146,175,139,236,2,199,1,150,152,188,203,6,20,151,234,142,238,11,27,150,216,171,142,3,188,8,153,236,182,220,1,4,151,254,242,152,9,145,1,155,213,159,176,1,10,161,234,157,145,5,7,164,202,219,213,10,122,165,131,171,211,15,20,168,215,223,235,2,56,171,236,222,251,5,252,4,172,254,181,239,1,15,174,203,157,214,7,6,176,238,158,139,14,175,2,177,239,218,225,4,3,178,187,245,161,14,11,180,189,170,253,8,12,181,150,190,222,14,95,181,156,253,158,6,5,183,182,135,14,227,2,184,146,243,216,14,7,185,164,169,62,90,183,213,134,255,8,28,190,183,139,210,2,110,192,246,139,213,2,35,192,187,174,206,8,223,5,194,228,144,71,76,195,254,251,180,11,58,197,205,192,233,12,9,198,223,206,159,1,145,2,198,234,131,228,11,50,199,130,209,189,2,141,8,204,195,206,156,1,153,9,206,214,243,86,178,1,207,210,187,205,12,8,208,203,223,226,9,81,207,231,154,196,9,3,217,168,198,159,4,7,218,255,204,32,21,219,200,174,197,9,25,220,225,223,240,3,60,223,215,172,155,15,5,224,159,166,178,15,30,226,167,254,250,5,13,227,211,144,195,8,12,228,242,134,215,15,12,229,154,194,35,178,1,226,235,133,189,11,8,236,158,128,159,2,4,237,140,187,206,2,21,236,253,128,205,3,9,239,239,208,251,10,17,240,179,157,219,7,4,241,147,239,232,6,4,238,153,239,204,9,49,243,138,171,183,10,252,1,245,181,155,135,2,23,247,212,219,208,10,46],"doc_state":[74,9,228,242,134,215,15,0,39,0,204,195,206,156,1,4,6,109,86,80,71,80,99,2,4,0,228,242,134,215,15,0,4,104,106,107,100,161,172,254,181,239,1,14,1,132,228,242,134,215,15,4,1,56,161,228,242,134,215,15,5,1,132,228,242,134,215,15,6,1,56,161,228,242,134,215,15,7,1,132,228,242,134,215,15,8,1,56,161,228,242,134,215,15,9,1,18,165,131,171,211,15,0,129,155,213,159,176,1,6,2,161,155,213,159,176,1,7,1,161,155,213,159,176,1,8,1,161,155,213,159,176,1,9,1,161,165,131,171,211,15,2,1,161,165,131,171,211,15,3,1,161,165,131,171,211,15,4,1,161,165,131,171,211,15,5,1,161,165,131,171,211,15,6,1,161,165,131,171,211,15,7,1,129,165,131,171,211,15,1,2,161,165,131,171,211,15,8,1,161,165,131,171,211,15,9,1,161,165,131,171,211,15,10,1,129,165,131,171,211,15,12,1,161,165,131,171,211,15,13,1,161,165,131,171,211,15,14,1,161,165,131,171,211,15,15,1,28,224,159,166,178,15,0,129,165,131,171,211,15,16,1,161,197,205,192,233,12,6,1,161,197,205,192,233,12,7,1,161,197,205,192,233,12,8,1,161,224,159,166,178,15,1,1,161,224,159,166,178,15,2,1,161,224,159,166,178,15,3,1,129,224,159,166,178,15,0,1,161,224,159,166,178,15,4,1,161,224,159,166,178,15,5,1,161,224,159,166,178,15,6,1,129,224,159,166,178,15,7,2,161,224,159,166,178,15,8,1,161,224,159,166,178,15,9,1,161,224,159,166,178,15,10,1,161,224,159,166,178,15,13,1,161,224,159,166,178,15,14,1,161,224,159,166,178,15,15,1,161,224,159,166,178,15,16,1,161,224,159,166,178,15,17,1,161,224,159,166,178,15,18,1,161,224,159,166,178,15,19,1,161,224,159,166,178,15,20,1,161,224,159,166,178,15,21,1,129,224,159,166,178,15,12,2,161,224,159,166,178,15,22,1,161,224,159,166,178,15,23,1,161,224,159,166,178,15,24,1,1,223,215,172,155,15,0,161,185,164,169,62,89,5,71,181,150,190,222,14,0,39,0,204,195,206,156,1,4,6,68,81,108,56,102,54,2,1,0,181,150,190,222,14,0,2,0,6,39,0,204,195,206,156,1,4,6,110,114,88,86,119,98,2,33,0,204,195,206,156,1,1,6,114,119,110,108,70,75,1,0,7,33,0,204,195,206,156,1,3,6,54,105,119,67,105,57,1,193,199,130,209,189,2,191,5,199,130,209,189,2,176,6,1,39,0,204,195,206,156,1,4,6,76,95,120,101,104,45,2,33,0,204,195,206,156,1,1,6,118,52,75,115,74,51,1,0,7,33,0,204,195,206,156,1,3,6,77,54,85,88,53,66,1,193,199,130,209,189,2,191,5,181,150,190,222,14,19,1,39,0,204,195,206,156,1,4,6,105,82,99,102,107,49,2,33,0,204,195,206,156,1,1,6,70,101,106,82,116,48,1,0,7,33,0,204,195,206,156,1,3,6,108,75,113,56,70,69,1,129,199,130,209,189,2,156,6,1,39,0,204,195,206,156,1,4,6,69,114,74,53,80,51,2,39,0,204,195,206,156,1,1,6,115,115,117,107,51,70,1,40,0,181,150,190,222,14,43,2,105,100,1,119,6,115,115,117,107,51,70,40,0,181,150,190,222,14,43,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,181,150,190,222,14,43,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,181,150,190,222,14,43,8,99,104,105,108,100,114,101,110,1,119,6,118,108,89,79,54,57,40,0,181,150,190,222,14,43,4,100,97,116,97,1,119,12,123,34,100,101,108,116,97,34,58,91,93,125,40,0,181,150,190,222,14,43,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,181,150,190,222,14,43,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,118,108,89,79,54,57,0,136,199,130,209,189,2,176,6,1,119,6,115,115,117,107,51,70,39,0,204,195,206,156,1,4,6,98,66,87,54,98,51,2,39,0,204,195,206,156,1,1,6,80,71,48,76,73,113,1,40,0,181,150,190,222,14,54,2,105,100,1,119,6,80,71,48,76,73,113,40,0,181,150,190,222,14,54,2,116,121,1,119,11,116,111,103,103,108,101,95,108,105,115,116,40,0,181,150,190,222,14,54,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,181,150,190,222,14,54,8,99,104,105,108,100,114,101,110,1,119,6,79,69,102,100,51,114,33,0,181,150,190,222,14,54,4,100,97,116,97,1,40,0,181,150,190,222,14,54,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,181,150,190,222,14,54,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,79,69,102,100,51,114,0,136,181,150,190,222,14,52,1,119,6,80,71,48,76,73,113,4,0,181,150,190,222,14,53,1,49,161,181,150,190,222,14,59,1,132,181,150,190,222,14,64,1,49,161,181,150,190,222,14,65,1,132,181,150,190,222,14,66,1,49,161,181,150,190,222,14,67,1,132,181,150,190,222,14,68,1,49,161,181,150,190,222,14,69,1,132,181,150,190,222,14,70,1,49,161,181,150,190,222,14,71,1,39,0,204,195,206,156,1,4,6,75,77,105,49,106,114,2,39,0,204,195,206,156,1,1,6,49,116,120,121,68,99,1,40,0,181,150,190,222,14,75,2,105,100,1,119,6,49,116,120,121,68,99,40,0,181,150,190,222,14,75,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,181,150,190,222,14,75,6,112,97,114,101,110,116,1,119,6,80,71,48,76,73,113,40,0,181,150,190,222,14,75,8,99,104,105,108,100,114,101,110,1,119,6,111,67,65,71,120,67,33,0,181,150,190,222,14,75,4,100,97,116,97,1,40,0,181,150,190,222,14,75,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,181,150,190,222,14,75,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,111,67,65,71,120,67,0,8,0,181,150,190,222,14,62,1,119,6,49,116,120,121,68,99,161,181,150,190,222,14,73,1,4,0,181,150,190,222,14,74,1,54,161,181,150,190,222,14,80,1,132,181,150,190,222,14,86,1,54,161,181,150,190,222,14,87,1,132,181,150,190,222,14,88,1,54,161,181,150,190,222,14,89,1,132,181,150,190,222,14,90,1,54,168,181,150,190,222,14,91,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,54,54,54,54,34,125,93,125,168,181,150,190,222,14,85,1,119,47,123,34,99,111,108,108,97,112,115,101,100,34,58,116,114,117,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,49,49,49,49,34,125,93,125,7,184,146,243,216,14,0,129,217,168,198,159,4,3,1,161,142,211,188,164,13,12,1,161,142,211,188,164,13,13,1,161,142,211,188,164,13,14,1,161,184,146,243,216,14,1,1,161,184,146,243,216,14,2,1,161,184,146,243,216,14,3,1,5,178,187,245,161,14,0,39,0,204,195,206,156,1,4,6,95,104,88,73,115,119,2,4,0,178,187,245,161,14,0,13,229,144,140,228,184,128,228,184,170,106,106,106,57,161,198,223,206,159,1,124,1,132,178,187,245,161,14,7,1,57,161,178,187,245,161,14,8,1,5,140,167,201,161,14,0,0,4,129,204,195,206,156,1,245,5,3,161,198,223,206,159,1,89,1,161,198,223,206,159,1,90,1,161,198,223,206,159,1,91,1,1,176,238,158,139,14,0,161,206,214,243,86,177,1,175,2,1,146,209,153,247,13,0,161,131,159,159,151,1,67,186,1,15,142,211,188,164,13,0,161,217,168,198,159,4,4,1,161,217,168,198,159,4,5,1,161,217,168,198,159,4,6,1,161,142,211,188,164,13,0,1,161,142,211,188,164,13,1,1,161,142,211,188,164,13,2,1,161,142,211,188,164,13,3,1,161,142,211,188,164,13,4,1,161,142,211,188,164,13,5,1,161,142,211,188,164,13,6,1,161,142,211,188,164,13,7,1,161,142,211,188,164,13,8,1,161,142,211,188,164,13,9,1,161,142,211,188,164,13,10,1,161,142,211,188,164,13,11,1,9,197,205,192,233,12,0,161,165,131,171,211,15,17,1,161,165,131,171,211,15,18,1,161,165,131,171,211,15,19,1,161,197,205,192,233,12,0,1,161,197,205,192,233,12,1,1,161,197,205,192,233,12,2,1,161,197,205,192,233,12,3,1,161,197,205,192,233,12,4,1,161,197,205,192,233,12,5,1,1,207,210,187,205,12,0,161,208,203,223,226,9,76,8,47,131,182,180,202,12,0,129,184,146,243,216,14,0,1,161,184,146,243,216,14,4,1,161,184,146,243,216,14,5,1,161,184,146,243,216,14,6,1,129,131,182,180,202,12,0,2,161,131,182,180,202,12,1,1,161,131,182,180,202,12,2,1,161,131,182,180,202,12,3,1,161,131,182,180,202,12,6,1,161,131,182,180,202,12,7,1,161,131,182,180,202,12,8,1,161,131,182,180,202,12,9,1,161,131,182,180,202,12,10,1,161,131,182,180,202,12,11,1,161,131,182,180,202,12,12,1,161,131,182,180,202,12,13,1,161,131,182,180,202,12,14,1,129,131,182,180,202,12,5,3,161,131,182,180,202,12,15,1,161,131,182,180,202,12,16,1,161,131,182,180,202,12,17,1,161,131,182,180,202,12,21,1,161,131,182,180,202,12,22,1,161,131,182,180,202,12,23,1,161,131,182,180,202,12,24,1,161,131,182,180,202,12,25,1,161,131,182,180,202,12,26,1,161,131,182,180,202,12,27,1,161,131,182,180,202,12,28,1,161,131,182,180,202,12,29,1,129,131,182,180,202,12,20,4,161,131,182,180,202,12,30,1,161,131,182,180,202,12,31,1,161,131,182,180,202,12,32,1,161,131,182,180,202,12,37,1,161,131,182,180,202,12,38,1,161,131,182,180,202,12,39,1,129,131,182,180,202,12,36,1,161,131,182,180,202,12,40,1,161,131,182,180,202,12,41,1,161,131,182,180,202,12,42,1,161,131,182,180,202,12,44,1,161,131,182,180,202,12,45,1,161,131,182,180,202,12,46,1,161,131,182,180,202,12,47,1,161,131,182,180,202,12,48,1,161,131,182,180,202,12,49,1,1,151,234,142,238,11,0,161,229,154,194,35,177,1,27,1,198,234,131,228,11,0,161,236,253,128,205,3,8,50,2,226,235,133,189,11,0,161,145,224,235,133,7,2,7,168,226,235,133,189,11,6,1,122,0,0,0,0,102,88,73,73,1,195,254,251,180,11,0,161,183,182,135,14,224,2,58,1,239,239,208,251,10,0,33,1,4,109,101,116,97,12,108,97,115,116,95,115,121,110,99,95,97,116,17,81,164,202,219,213,10,0,39,0,204,195,206,156,1,4,6,103,67,116,99,89,115,2,39,0,204,195,206,156,1,4,6,102,105,108,83,57,100,2,4,0,164,202,219,213,10,1,10,116,111,100,111,32,108,105,115,116,32,134,164,202,219,213,10,11,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,56,84,49,52,58,50,53,58,51,50,46,52,53,55,50,55,55,34,125,132,164,202,219,213,10,12,1,36,134,164,202,219,213,10,13,7,109,101,110,116,105,111,110,4,110,117,108,108,132,164,202,219,213,10,14,4,109,101,110,116,33,0,204,195,206,156,1,1,6,88,55,78,102,76,50,1,0,7,33,0,204,195,206,156,1,3,6,112,56,66,76,122,103,1,193,198,223,206,159,1,135,1,199,130,209,189,2,60,1,168,199,130,209,189,2,140,8,1,119,161,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,116,111,100,111,32,108,105,115,116,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,56,84,49,52,58,50,53,58,51,50,46,52,53,55,50,55,55,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,44,123,34,105,110,115,101,114,116,34,58,34,109,101,110,116,34,125,93,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,39,0,204,195,206,156,1,4,6,66,120,115,95,114,76,2,33,0,204,195,206,156,1,1,6,111,56,54,77,119,121,1,0,7,33,0,204,195,206,156,1,3,6,67,89,84,109,67,89,1,193,198,223,206,159,1,135,1,164,202,219,213,10,28,1,4,0,164,202,219,213,10,30,1,35,0,1,39,0,204,195,206,156,1,4,6,109,113,102,117,86,95,2,33,0,204,195,206,156,1,1,6,84,100,115,87,90,75,1,0,7,33,0,204,195,206,156,1,3,6,49,115,106,52,120,74,1,193,198,223,206,159,1,135,1,164,202,219,213,10,40,1,4,0,164,202,219,213,10,43,1,49,0,1,132,164,202,219,213,10,54,1,50,0,1,132,164,202,219,213,10,56,1,51,0,1,132,164,202,219,213,10,58,1,32,0,1,129,164,202,219,213,10,60,1,0,1,134,164,202,219,213,10,62,7,109,101,110,116,105,111,110,51,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,132,164,202,219,213,10,64,1,36,134,164,202,219,213,10,65,7,109,101,110,116,105,111,110,4,110,117,108,108,0,1,39,0,204,195,206,156,1,4,6,103,83,52,80,113,73,2,4,0,164,202,219,213,10,68,4,49,50,51,32,134,164,202,219,213,10,72,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,125,132,164,202,219,213,10,73,1,36,134,164,202,219,213,10,74,7,109,101,110,116,105,111,110,4,110,117,108,108,132,164,202,219,213,10,75,1,32,0,1,129,164,202,219,213,10,76,1,0,1,161,204,195,206,156,1,155,1,1,161,204,195,206,156,1,156,1,1,161,204,195,206,156,1,157,1,1,0,1,132,164,202,219,213,10,78,1,32,0,1,132,164,202,219,213,10,84,1,101,0,1,132,164,202,219,213,10,86,1,114,0,1,132,164,202,219,213,10,88,1,32,0,1,132,164,202,219,213,10,90,1,32,0,1,68,164,202,219,213,10,69,1,35,0,1,68,164,202,219,213,10,94,1,35,0,1,39,0,204,195,206,156,1,4,6,120,115,71,80,56,122,2,4,0,164,202,219,213,10,98,4,49,50,51,32,134,164,202,219,213,10,102,7,109,101,110,116,105,111,110,51,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,132,164,202,219,213,10,103,1,36,134,164,202,219,213,10,104,7,109,101,110,116,105,111,110,4,110,117,108,108,132,164,202,219,213,10,105,6,32,32,101,114,32,32,39,0,204,195,206,156,1,1,6,106,97,80,87,115,68,1,40,0,164,202,219,213,10,112,2,105,100,1,119,6,106,97,80,87,115,68,40,0,164,202,219,213,10,112,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,164,202,219,213,10,112,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,164,202,219,213,10,112,8,99,104,105,108,100,114,101,110,1,119,6,106,75,88,90,122,73,33,0,164,202,219,213,10,112,4,100,97,116,97,1,40,0,164,202,219,213,10,112,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,164,202,219,213,10,112,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,75,88,90,122,73,0,200,198,223,206,159,1,135,1,164,202,219,213,10,53,1,119,6,106,97,80,87,115,68,1,247,212,219,208,10,0,161,132,236,218,251,9,13,46,240,1,243,138,171,183,10,0,161,150,216,171,142,3,178,5,1,161,150,216,171,142,3,190,5,1,161,150,216,171,142,3,200,5,1,161,150,216,171,142,3,187,6,1,161,150,216,171,142,3,188,6,1,161,150,216,171,142,3,189,6,1,161,150,216,171,142,3,190,6,2,161,150,216,171,142,3,251,5,1,161,150,216,171,142,3,144,6,1,161,150,216,171,142,3,164,6,1,161,243,138,171,183,10,7,1,161,243,138,171,183,10,0,1,161,243,138,171,183,10,1,1,161,243,138,171,183,10,2,1,161,243,138,171,183,10,8,1,161,243,138,171,183,10,9,1,161,243,138,171,183,10,10,1,161,243,138,171,183,10,11,1,161,243,138,171,183,10,3,1,161,243,138,171,183,10,4,1,161,243,138,171,183,10,5,1,161,243,138,171,183,10,18,2,161,243,138,171,183,10,12,1,161,243,138,171,183,10,13,1,161,243,138,171,183,10,14,1,161,243,138,171,183,10,19,1,161,243,138,171,183,10,20,1,161,243,138,171,183,10,21,1,161,243,138,171,183,10,23,1,161,243,138,171,183,10,15,1,161,243,138,171,183,10,16,1,161,243,138,171,183,10,17,1,161,243,138,171,183,10,30,2,161,243,138,171,183,10,24,1,161,243,138,171,183,10,25,1,161,243,138,171,183,10,26,1,161,243,138,171,183,10,27,1,161,243,138,171,183,10,28,1,161,243,138,171,183,10,29,1,161,243,138,171,183,10,35,1,161,243,138,171,183,10,31,1,161,243,138,171,183,10,32,1,161,243,138,171,183,10,33,1,161,243,138,171,183,10,42,2,161,243,138,171,183,10,36,1,161,243,138,171,183,10,37,1,161,243,138,171,183,10,38,1,161,243,138,171,183,10,43,1,161,243,138,171,183,10,44,1,161,243,138,171,183,10,45,1,161,243,138,171,183,10,47,1,161,243,138,171,183,10,39,1,161,243,138,171,183,10,40,1,161,243,138,171,183,10,41,1,161,243,138,171,183,10,54,2,161,243,138,171,183,10,48,1,161,243,138,171,183,10,49,1,161,243,138,171,183,10,50,1,161,243,138,171,183,10,55,1,161,243,138,171,183,10,56,1,161,243,138,171,183,10,57,1,161,243,138,171,183,10,59,1,161,243,138,171,183,10,51,1,161,243,138,171,183,10,52,1,161,243,138,171,183,10,53,1,161,243,138,171,183,10,66,2,161,243,138,171,183,10,60,1,161,243,138,171,183,10,61,1,161,243,138,171,183,10,62,1,161,243,138,171,183,10,63,1,161,243,138,171,183,10,64,1,161,243,138,171,183,10,65,1,161,243,138,171,183,10,71,2,161,243,138,171,183,10,67,1,161,243,138,171,183,10,68,1,161,243,138,171,183,10,69,1,161,243,138,171,183,10,79,1,161,243,138,171,183,10,72,1,161,243,138,171,183,10,73,1,161,243,138,171,183,10,74,1,161,243,138,171,183,10,75,1,161,243,138,171,183,10,76,1,161,243,138,171,183,10,77,1,161,243,138,171,183,10,83,1,161,243,138,171,183,10,80,1,161,243,138,171,183,10,81,1,161,243,138,171,183,10,82,1,161,243,138,171,183,10,90,2,161,146,216,250,133,2,12,1,161,146,216,250,133,2,13,1,161,146,216,250,133,2,14,1,161,146,216,250,133,2,17,1,161,146,216,250,133,2,21,1,161,146,216,250,133,2,22,1,161,146,216,250,133,2,23,1,161,243,138,171,183,10,99,1,161,146,216,250,133,2,18,1,161,146,216,250,133,2,19,1,161,146,216,250,133,2,20,1,161,243,138,171,183,10,103,1,161,146,216,250,133,2,24,1,161,146,216,250,133,2,25,1,161,146,216,250,133,2,26,1,161,146,216,250,133,2,35,1,161,146,216,250,133,2,28,1,161,146,216,250,133,2,29,1,161,146,216,250,133,2,30,1,161,243,138,171,183,10,111,1,161,146,216,250,133,2,32,1,161,146,216,250,133,2,33,1,161,146,216,250,133,2,34,1,161,243,138,171,183,10,115,1,161,146,216,250,133,2,36,1,161,146,216,250,133,2,37,1,161,146,216,250,133,2,38,1,161,146,216,250,133,2,40,1,161,146,216,250,133,2,41,1,161,146,216,250,133,2,42,1,161,146,216,250,133,2,47,1,161,146,216,250,133,2,44,1,161,146,216,250,133,2,45,1,161,146,216,250,133,2,46,1,161,243,138,171,183,10,126,2,161,146,216,250,133,2,48,1,161,146,216,250,133,2,49,1,161,146,216,250,133,2,50,1,161,146,216,250,133,2,59,1,161,146,216,250,133,2,51,1,161,146,216,250,133,2,52,1,161,146,216,250,133,2,53,1,161,243,138,171,183,10,135,1,1,161,146,216,250,133,2,56,1,161,146,216,250,133,2,57,1,161,146,216,250,133,2,58,1,161,243,138,171,183,10,139,1,1,161,146,216,250,133,2,60,1,161,146,216,250,133,2,61,1,161,146,216,250,133,2,62,1,161,146,216,250,133,2,71,1,161,146,216,250,133,2,64,1,161,146,216,250,133,2,65,1,161,146,216,250,133,2,66,1,161,243,138,171,183,10,147,1,1,161,146,216,250,133,2,68,1,161,146,216,250,133,2,69,1,161,146,216,250,133,2,70,1,161,243,138,171,183,10,151,1,1,161,146,216,250,133,2,72,1,161,146,216,250,133,2,73,1,161,146,216,250,133,2,74,1,161,146,216,250,133,2,83,1,161,146,216,250,133,2,76,1,161,146,216,250,133,2,77,1,161,146,216,250,133,2,78,1,161,243,138,171,183,10,159,1,1,161,146,216,250,133,2,80,1,161,146,216,250,133,2,81,1,161,146,216,250,133,2,82,1,161,243,138,171,183,10,163,1,1,161,146,216,250,133,2,84,1,161,146,216,250,133,2,85,1,161,146,216,250,133,2,86,1,161,146,216,250,133,2,95,1,161,146,216,250,133,2,92,1,161,146,216,250,133,2,93,1,161,146,216,250,133,2,94,1,161,243,138,171,183,10,171,1,1,161,146,216,250,133,2,88,1,161,146,216,250,133,2,89,1,161,146,216,250,133,2,90,1,161,243,138,171,183,10,175,1,1,161,146,216,250,133,2,96,1,161,146,216,250,133,2,97,1,161,146,216,250,133,2,98,1,161,146,216,250,133,2,107,1,161,146,216,250,133,2,104,1,161,146,216,250,133,2,105,1,161,146,216,250,133,2,106,1,161,243,138,171,183,10,183,1,1,161,146,216,250,133,2,100,1,161,146,216,250,133,2,101,1,161,146,216,250,133,2,102,1,161,243,138,171,183,10,187,1,1,161,146,216,250,133,2,108,1,161,146,216,250,133,2,109,1,161,146,216,250,133,2,110,1,161,146,216,250,133,2,119,1,161,146,216,250,133,2,112,1,161,146,216,250,133,2,113,1,161,146,216,250,133,2,114,1,161,243,138,171,183,10,195,1,1,161,146,216,250,133,2,116,1,161,146,216,250,133,2,117,1,161,146,216,250,133,2,118,1,161,243,138,171,183,10,199,1,1,161,146,216,250,133,2,120,1,161,146,216,250,133,2,121,1,161,146,216,250,133,2,122,1,161,146,216,250,133,2,131,1,2,161,146,216,250,133,2,124,1,161,146,216,250,133,2,125,1,161,146,216,250,133,2,126,1,161,146,216,250,133,2,128,1,1,161,146,216,250,133,2,129,1,1,161,146,216,250,133,2,130,1,1,161,243,138,171,183,10,208,1,1,161,146,216,250,133,2,132,1,1,161,146,216,250,133,2,133,1,1,161,146,216,250,133,2,134,1,1,161,146,216,250,133,2,143,1,1,161,146,216,250,133,2,136,1,1,161,146,216,250,133,2,137,1,1,161,146,216,250,133,2,138,1,1,161,243,138,171,183,10,219,1,1,161,146,216,250,133,2,140,1,1,161,146,216,250,133,2,141,1,1,161,146,216,250,133,2,142,1,1,161,243,138,171,183,10,223,1,1,161,146,216,250,133,2,144,1,1,161,146,216,250,133,2,145,1,1,161,146,216,250,133,2,146,1,1,161,146,216,250,133,2,155,1,1,161,146,216,250,133,2,148,1,1,161,146,216,250,133,2,149,1,1,161,146,216,250,133,2,150,1,1,161,243,138,171,183,10,231,1,1,161,146,216,250,133,2,152,1,1,161,146,216,250,133,2,153,1,1,161,146,216,250,133,2,154,1,1,161,243,138,171,183,10,235,1,1,161,146,216,250,133,2,156,1,1,161,146,216,250,133,2,157,1,1,161,146,216,250,133,2,158,1,1,161,146,216,250,133,2,167,1,3,161,146,216,250,133,2,160,1,1,161,146,216,250,133,2,161,1,1,161,146,216,250,133,2,162,1,1,161,146,216,250,133,2,164,1,1,161,146,216,250,133,2,165,1,1,161,146,216,250,133,2,166,1,1,1,132,236,218,251,9,0,161,218,255,204,32,20,14,34,136,199,176,231,9,0,39,0,204,195,206,156,1,1,6,74,52,82,97,73,114,1,40,0,136,199,176,231,9,0,2,105,100,1,119,6,74,52,82,97,73,114,40,0,136,199,176,231,9,0,2,116,121,1,119,4,103,114,105,100,40,0,136,199,176,231,9,0,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,136,199,176,231,9,0,8,99,104,105,108,100,114,101,110,1,119,6,86,95,76,83,51,101,40,0,136,199,176,231,9,0,4,100,97,116,97,1,119,101,123,34,118,105,101,119,95,105,100,34,58,34,49,51,53,54,49,53,102,97,45,54,54,102,55,45,52,52,53,49,45,57,98,53,52,45,100,55,101,57,57,52,52,53,102,99,97,52,34,44,34,112,97,114,101,110,116,95,105,100,34,58,34,55,100,50,49,52,56,102,99,45,99,97,99,101,45,52,52,53,50,45,57,99,53,99,45,57,54,101,53,50,101,54,98,102,56,98,53,34,125,40,0,136,199,176,231,9,0,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,136,199,176,231,9,0,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,86,95,76,83,51,101,0,200,204,195,206,156,1,252,1,204,195,206,156,1,253,1,1,119,6,74,52,82,97,73,114,39,0,204,195,206,156,1,1,6,115,74,113,109,112,57,1,40,0,136,199,176,231,9,10,2,105,100,1,119,6,115,74,113,109,112,57,40,0,136,199,176,231,9,10,2,116,121,1,119,5,98,111,97,114,100,40,0,136,199,176,231,9,10,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,136,199,176,231,9,10,8,99,104,105,108,100,114,101,110,1,119,6,87,71,71,122,72,118,40,0,136,199,176,231,9,10,4,100,97,116,97,1,119,101,123,34,112,97,114,101,110,116,95,105,100,34,58,34,97,53,53,54,54,101,52,57,45,102,49,53,54,45,52,49,54,56,45,57,98,50,100,45,49,55,57,50,54,99,53,100,97,51,50,57,34,44,34,118,105,101,119,95,105,100,34,58,34,98,52,101,55,55,50,48,51,45,53,99,56,98,45,52,56,100,102,45,98,98,99,53,45,50,101,49,49,52,51,101,98,48,101,54,49,34,125,40,0,136,199,176,231,9,10,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,136,199,176,231,9,10,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,87,71,71,122,72,118,0,200,136,199,176,231,9,9,204,195,206,156,1,253,1,1,119,6,115,74,113,109,112,57,33,0,204,195,206,156,1,1,6,98,118,111,52,85,121,1,0,7,33,0,204,195,206,156,1,3,6,81,122,68,56,119,121,1,193,136,199,176,231,9,19,204,195,206,156,1,253,1,1,39,0,204,195,206,156,1,1,6,71,57,106,76,66,79,1,40,0,136,199,176,231,9,30,2,105,100,1,119,6,71,57,106,76,66,79,40,0,136,199,176,231,9,30,2,116,121,1,119,8,99,97,108,101,110,100,97,114,40,0,136,199,176,231,9,30,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,136,199,176,231,9,30,8,99,104,105,108,100,114,101,110,1,119,6,122,51,54,102,102,100,40,0,136,199,176,231,9,30,4,100,97,116,97,1,119,101,123,34,118,105,101,119,95,105,100,34,58,34,50,98,102,53,48,99,48,51,45,102,52,49,102,45,52,51,54,51,45,98,53,98,49,45,49,48,49,50,49,54,97,54,99,53,99,99,34,44,34,112,97,114,101,110,116,95,105,100,34,58,34,101,101,51,97,101,56,99,101,45,57,53,57,97,45,52,100,102,51,45,56,55,51,52,45,52,48,98,53,51,53,102,102,56,56,101,51,34,125,40,0,136,199,176,231,9,30,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,136,199,176,231,9,30,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,122,51,54,102,102,100,0,200,136,199,176,231,9,29,204,195,206,156,1,253,1,1,119,6,71,57,106,76,66,79,1,131,128,202,229,9,0,161,243,138,171,183,10,245,1,1,1,208,203,223,226,9,0,161,146,209,153,247,13,185,1,81,31,238,153,239,204,9,0,161,183,213,134,255,8,25,1,161,183,213,134,255,8,26,1,161,183,213,134,255,8,27,1,132,183,213,134,255,8,24,1,100,161,238,153,239,204,9,0,1,161,238,153,239,204,9,1,1,161,238,153,239,204,9,2,1,132,238,153,239,204,9,3,1,55,161,238,153,239,204,9,4,1,161,238,153,239,204,9,5,1,161,238,153,239,204,9,6,1,132,238,153,239,204,9,7,1,55,168,238,153,239,204,9,8,1,119,133,1,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,112,97,103,101,95,105,100,34,58,34,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,34,44,34,116,121,112,101,34,58,34,112,97,103,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,44,123,34,105,110,115,101,114,116,34,58,34,100,55,55,34,125,93,125,168,238,153,239,204,9,9,1,119,10,107,106,48,68,49,121,121,88,78,119,168,238,153,239,204,9,10,1,119,4,116,101,120,116,39,0,204,195,206,156,1,4,6,111,97,103,82,55,77,2,6,0,238,153,239,204,9,15,4,104,114,101,102,13,34,97,112,112,102,108,111,119,121,46,105,111,34,132,238,153,239,204,9,16,11,97,112,112,102,108,111,119,121,46,105,111,134,238,153,239,204,9,27,4,104,114,101,102,4,110,117,108,108,132,238,153,239,204,9,28,1,32,161,151,254,242,152,9,90,1,132,238,153,239,204,9,29,1,49,161,238,153,239,204,9,30,1,39,0,204,195,206,156,1,4,6,53,101,83,117,83,45,2,6,0,238,153,239,204,9,33,4,104,114,101,102,13,34,49,57,50,46,49,54,56,46,49,46,50,34,132,238,153,239,204,9,34,9,99,111,110,116,101,110,116,32,49,134,238,153,239,204,9,43,4,104,114,101,102,4,110,117,108,108,132,238,153,239,204,9,44,1,32,161,151,254,242,152,9,134,1,1,132,238,153,239,204,9,45,1,50,161,238,153,239,204,9,46,1,1,219,200,174,197,9,0,161,161,234,157,145,5,6,25,3,207,231,154,196,9,0,161,204,195,206,156,1,209,1,1,161,204,195,206,156,1,210,1,1,161,204,195,206,156,1,211,1,1,118,151,254,242,152,9,0,39,0,204,195,206,156,1,4,6,65,119,80,77,53,56,2,6,0,151,254,242,152,9,0,7,109,101,110,116,105,111,110,64,123,34,116,121,112,101,34,58,34,112,97,103,101,34,44,34,112,97,103,101,95,105,100,34,58,34,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,34,125,132,151,254,242,152,9,1,1,36,134,151,254,242,152,9,2,7,109,101,110,116,105,111,110,4,110,117,108,108,132,151,254,242,152,9,3,1,104,161,220,225,223,240,3,59,1,129,151,254,242,152,9,4,2,161,151,254,242,152,9,5,1,129,151,254,242,152,9,7,2,161,151,254,242,152,9,8,1,129,151,254,242,152,9,10,1,132,151,254,242,152,9,12,1,104,161,151,254,242,152,9,11,1,196,151,254,242,152,9,4,151,254,242,152,9,6,2,104,104,161,151,254,242,152,9,14,1,132,151,254,242,152,9,13,1,32,161,151,254,242,152,9,17,1,129,151,254,242,152,9,18,1,161,151,254,242,152,9,19,1,134,151,254,242,152,9,20,7,109,101,110,116,105,111,110,123,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,50,53,84,49,55,58,49,50,58,52,51,46,52,51,57,57,48,57,34,44,34,114,101,109,105,110,100,101,114,95,105,100,34,58,34,118,108,95,45,105,57,52,99,82,103,69,85,115,112,84,111,81,95,115,68,86,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,114,101,109,105,110,100,101,114,95,111,112,116,105,111,110,34,58,34,97,116,84,105,109,101,79,102,69,118,101,110,116,34,125,132,151,254,242,152,9,22,1,36,134,151,254,242,152,9,23,7,109,101,110,116,105,111,110,4,110,117,108,108,168,151,254,242,152,9,21,1,119,171,2,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,112,97,103,101,95,105,100,34,58,34,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,34,44,34,116,121,112,101,34,58,34,112,97,103,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,44,123,34,105,110,115,101,114,116,34,58,34,104,104,104,104,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,50,53,84,49,55,58,49,50,58,52,51,46,52,51,57,57,48,57,34,44,34,114,101,109,105,110,100,101,114,95,105,100,34,58,34,118,108,95,45,105,57,52,99,82,103,69,85,115,112,84,111,81,95,115,68,86,34,44,34,114,101,109,105,110,100,101,114,95,111,112,116,105,111,110,34,58,34,97,116,84,105,109,101,79,102,69,118,101,110,116,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,93,125,39,0,204,195,206,156,1,4,6,107,74,118,98,69,107,2,39,0,204,195,206,156,1,1,6,112,71,75,102,71,113,1,40,0,151,254,242,152,9,27,2,105,100,1,119,6,112,71,75,102,71,113,40,0,151,254,242,152,9,27,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,151,254,242,152,9,27,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,151,254,242,152,9,27,8,99,104,105,108,100,114,101,110,1,119,6,54,97,84,68,85,107,33,0,151,254,242,152,9,27,4,100,97,116,97,1,40,0,151,254,242,152,9,27,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,151,254,242,152,9,27,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,54,97,84,68,85,107,0,200,220,225,223,240,3,45,204,195,206,156,1,251,1,1,119,6,112,71,75,102,71,113,1,0,151,254,242,152,9,26,1,161,151,254,242,152,9,32,1,129,151,254,242,152,9,37,1,161,151,254,242,152,9,38,1,129,151,254,242,152,9,39,1,161,151,254,242,152,9,40,1,129,151,254,242,152,9,41,1,161,151,254,242,152,9,42,1,129,151,254,242,152,9,43,1,161,151,254,242,152,9,44,1,65,151,254,242,152,9,37,6,198,151,254,242,152,9,52,151,254,242,152,9,37,4,104,114,101,102,4,110,117,108,108,161,151,254,242,152,9,46,1,65,151,254,242,152,9,47,1,161,151,254,242,152,9,54,1,193,151,254,242,152,9,55,151,254,242,152,9,47,1,161,151,254,242,152,9,56,1,193,151,254,242,152,9,57,151,254,242,152,9,47,1,161,151,254,242,152,9,58,1,193,151,254,242,152,9,59,151,254,242,152,9,47,1,161,151,254,242,152,9,60,1,193,151,254,242,152,9,61,151,254,242,152,9,47,1,161,151,254,242,152,9,62,1,193,151,254,242,152,9,63,151,254,242,152,9,47,1,161,151,254,242,152,9,64,1,193,151,254,242,152,9,65,151,254,242,152,9,47,1,161,151,254,242,152,9,66,1,193,151,254,242,152,9,67,151,254,242,152,9,47,1,161,151,254,242,152,9,68,1,193,151,254,242,152,9,69,151,254,242,152,9,47,1,161,151,254,242,152,9,70,1,193,151,254,242,152,9,71,151,254,242,152,9,47,1,161,151,254,242,152,9,72,1,193,151,254,242,152,9,73,151,254,242,152,9,47,1,161,151,254,242,152,9,74,1,70,151,254,242,152,9,55,4,104,114,101,102,13,34,97,112,112,102,108,111,119,121,46,105,111,34,196,151,254,242,152,9,77,151,254,242,152,9,55,11,97,112,112,102,108,111,119,121,46,105,111,193,151,254,242,152,9,88,151,254,242,152,9,55,1,161,151,254,242,152,9,76,1,39,0,204,195,206,156,1,4,6,88,82,74,89,90,53,2,39,0,204,195,206,156,1,1,6,72,77,49,70,106,86,1,40,0,151,254,242,152,9,92,2,105,100,1,119,6,72,77,49,70,106,86,40,0,151,254,242,152,9,92,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,151,254,242,152,9,92,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,151,254,242,152,9,92,8,99,104,105,108,100,114,101,110,1,119,6,95,45,107,102,121,108,33,0,151,254,242,152,9,92,4,100,97,116,97,1,40,0,151,254,242,152,9,92,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,151,254,242,152,9,92,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,95,45,107,102,121,108,0,200,151,254,242,152,9,36,204,195,206,156,1,251,1,1,119,6,72,77,49,70,106,86,1,0,151,254,242,152,9,91,1,161,151,254,242,152,9,97,2,129,151,254,242,152,9,102,1,161,151,254,242,152,9,104,1,129,151,254,242,152,9,105,1,161,151,254,242,152,9,106,1,129,151,254,242,152,9,107,1,161,151,254,242,152,9,108,1,129,151,254,242,152,9,109,1,161,151,254,242,152,9,110,1,129,151,254,242,152,9,111,1,161,151,254,242,152,9,112,1,129,151,254,242,152,9,113,1,161,151,254,242,152,9,114,1,129,151,254,242,152,9,115,1,161,151,254,242,152,9,116,1,129,151,254,242,152,9,117,1,161,151,254,242,152,9,118,1,129,151,254,242,152,9,119,1,161,151,254,242,152,9,120,1,198,151,254,242,152,9,102,151,254,242,152,9,105,4,104,114,101,102,13,34,49,57,50,46,49,54,56,46,49,46,50,34,196,151,254,242,152,9,123,151,254,242,152,9,105,9,99,111,110,116,101,110,116,32,49,198,151,254,242,152,9,132,1,151,254,242,152,9,105,4,104,114,101,102,4,110,117,108,108,161,151,254,242,152,9,122,1,129,204,195,206,156,1,131,4,1,161,204,195,206,156,1,56,1,161,204,195,206,156,1,57,1,161,204,195,206,156,1,58,1,161,151,254,242,152,9,136,1,1,161,151,254,242,152,9,137,1,1,161,151,254,242,152,9,138,1,1,168,151,254,242,152,9,139,1,1,119,128,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,63,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,114,105,103,104,116,32,102,111,114,32,104,101,108,112,32,97,110,100,32,115,117,112,112,111,114,116,34,125,93,125,168,151,254,242,152,9,140,1,1,119,10,119,86,82,81,117,71,111,121,116,48,168,151,254,242,152,9,141,1,1,119,4,116,101,120,116,28,183,213,134,255,8,0,129,220,225,223,240,3,6,1,161,220,225,223,240,3,7,1,161,220,225,223,240,3,8,1,161,220,225,223,240,3,9,1,129,183,213,134,255,8,0,1,161,183,213,134,255,8,1,1,161,183,213,134,255,8,2,1,161,183,213,134,255,8,3,1,129,183,213,134,255,8,4,1,161,183,213,134,255,8,5,1,161,183,213,134,255,8,6,1,161,183,213,134,255,8,7,1,129,183,213,134,255,8,8,1,161,183,213,134,255,8,9,1,161,183,213,134,255,8,10,1,161,183,213,134,255,8,11,1,129,183,213,134,255,8,12,1,161,183,213,134,255,8,13,1,161,183,213,134,255,8,14,1,161,183,213,134,255,8,15,1,129,183,213,134,255,8,16,1,161,183,213,134,255,8,17,1,161,183,213,134,255,8,18,1,161,183,213,134,255,8,19,1,129,183,213,134,255,8,20,1,161,183,213,134,255,8,21,1,161,183,213,134,255,8,22,1,161,183,213,134,255,8,23,1,12,180,189,170,253,8,0,168,146,175,139,236,2,0,1,119,68,123,34,119,105,100,116,104,34,58,49,53,48,46,56,53,53,52,54,56,55,53,44,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,125,168,146,175,139,236,2,1,1,119,68,123,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,44,34,119,105,100,116,104,34,58,49,48,53,46,48,53,48,55,56,49,50,53,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,104,101,105,103,104,116,34,58,52,54,46,48,125,168,146,175,139,236,2,2,1,119,60,123,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,48,44,34,119,105,100,116,104,34,58,56,48,46,48,125,168,146,175,139,236,2,3,1,119,68,123,34,119,105,100,116,104,34,58,49,53,48,46,56,53,53,52,54,56,55,53,44,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,125,168,146,175,139,236,2,4,1,119,68,123,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,44,34,119,105,100,116,104,34,58,49,48,53,46,48,53,48,55,56,49,50,53,44,34,104,101,105,103,104,116,34,58,52,54,46,48,125,168,146,175,139,236,2,5,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,49,125,161,146,175,139,236,2,11,1,168,146,175,139,236,2,7,1,119,68,123,34,99,111,108,80,111,115,105,116,105,111,110,34,58,48,44,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,49,53,48,46,56,53,53,52,54,56,55,53,125,168,146,175,139,236,2,8,1,119,68,123,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,119,105,100,116,104,34,58,49,48,53,46,48,53,48,55,56,49,50,53,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,49,125,168,146,175,139,236,2,9,1,119,60,123,34,119,105,100,116,104,34,58,56,48,46,48,44,34,114,111,119,80,111,115,105,116,105,111,110,34,58,50,44,34,104,101,105,103,104,116,34,58,52,54,46,48,44,34,99,111,108,80,111,115,105,116,105,111,110,34,58,50,125,161,180,189,170,253,8,6,1,168,180,189,170,253,8,10,1,119,114,123,34,99,111,108,77,105,110,105,109,117,109,87,105,100,116,104,34,58,52,48,46,48,44,34,114,111,119,68,101,102,97,117,108,116,72,101,105,103,104,116,34,58,52,48,46,48,44,34,99,111,108,115,76,101,110,34,58,51,44,34,114,111,119,115,76,101,110,34,58,51,44,34,99,111,108,68,101,102,97,117,108,116,87,105,100,116,104,34,58,56,48,46,48,44,34,99,111,108,115,72,101,105,103,104,116,34,58,49,52,54,46,48,125,21,192,187,174,206,8,0,39,0,204,195,206,156,1,4,6,72,101,110,107,82,107,2,161,150,216,171,142,3,187,8,1,1,0,192,187,174,206,8,0,3,129,192,187,174,206,8,4,15,129,192,187,174,206,8,19,45,129,192,187,174,206,8,64,10,134,192,187,174,206,8,74,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,129,192,187,174,206,8,75,110,161,192,187,174,206,8,1,1,65,192,187,174,206,8,2,5,193,192,187,174,206,8,4,192,187,174,206,8,5,14,193,192,187,174,206,8,19,192,187,174,206,8,20,44,193,192,187,174,206,8,64,192,187,174,206,8,65,9,193,192,187,174,206,8,74,192,187,174,206,8,75,110,161,192,187,174,206,8,186,1,2,193,192,187,174,206,8,240,2,192,187,174,206,8,75,180,1,161,192,187,174,206,8,242,2,1,70,192,187,174,206,8,187,1,11,102,111,110,116,95,102,97,109,105,108,121,15,34,65,68,76,97,77,32,68,105,115,112,108,97,121,34,196,192,187,174,206,8,168,4,192,187,174,206,8,187,1,180,1,108,111,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,76,101,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,198,192,187,174,206,8,220,5,192,187,174,206,8,187,1,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,161,192,187,174,206,8,167,4,1,11,227,211,144,195,8,0,161,243,138,171,183,10,240,1,1,161,243,138,171,183,10,241,1,1,161,243,138,171,183,10,242,1,1,161,194,228,144,71,4,1,161,194,228,144,71,5,1,161,194,228,144,71,6,1,161,220,225,223,240,3,34,1,161,220,225,223,240,3,30,1,161,220,225,223,240,3,31,1,161,220,225,223,240,3,32,1,161,227,211,144,195,8,6,2,9,135,182,134,178,8,0,168,141,151,160,163,4,21,1,119,147,2,123,34,99,111,118,101,114,95,115,101,108,101,99,116,105,111,110,95,116,121,112,101,34,58,34,67,111,118,101,114,84,121,112,101,46,102,105,108,101,34,44,34,99,111,118,101,114,95,115,101,108,101,99,116,105,111,110,34,58,34,104,116,116,112,115,58,47,47,105,109,97,103,101,115,46,117,110,115,112,108,97,115,104,46,99,111,109,47,112,104,111,116,111,45,49,55,49,52,53,48,56,56,54,50,55,56,56,45,52,52,101,52,53,99,52,51,49,53,100,48,63,99,114,111,112,61,101,110,116,114,111,112,121,38,99,115,61,116,105,110,121,115,114,103,98,38,102,105,116,61,109,97,120,38,102,109,61,106,112,103,38,105,120,105,100,61,77,51,119,49,77,84,69,49,77,122,100,56,77,72,119,120,102,72,74,104,98,109,82,118,98,88,120,56,102,72,120,56,102,72,120,56,102,68,69,51,77,84,89,51,78,122,103,121,77,84,108,56,38,105,120,108,105,98,61,114,98,45,52,46,48,46,51,38,113,61,56,48,38,119,61,49,48,56,48,34,44,34,105,109,97,103,101,95,116,121,112,101,34,58,34,49,34,44,34,100,101,108,116,97,34,58,91,93,125,168,141,151,160,163,4,22,1,119,10,112,70,113,76,55,45,79,83,121,86,168,141,151,160,163,4,23,1,119,4,116,101,120,116,70,204,195,206,156,1,209,5,11,102,111,110,116,95,102,97,109,105,108,121,15,34,65,68,76,97,32,77,68,105,115,112,108,97,121,34,196,135,182,134,178,8,3,204,195,206,156,1,209,5,55,67,108,105,99,107,32,97,110,121,119,104,101,114,101,32,97,110,100,32,106,117,115,116,32,115,116,97,114,116,32,116,121,112,105,110,103,229,147,136,229,147,136,229,147,136,46,229,176,177,229,135,160,229,174,182,198,135,182,134,178,8,46,204,195,206,156,1,209,5,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,168,140,167,201,161,14,7,1,119,141,1,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,102,97,109,105,108,121,34,58,34,65,68,76,97,32,77,68,105,115,112,108,97,121,34,125,44,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,97,110,121,119,104,101,114,101,32,97,110,100,32,106,117,115,116,32,115,116,97,114,116,32,116,121,112,105,110,103,229,147,136,229,147,136,229,147,136,46,229,176,177,229,135,160,229,174,182,34,125,93,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,168,140,167,201,161,14,8,1,119,10,119,79,108,117,99,85,55,51,73,76,168,140,167,201,161,14,9,1,119,4,116,101,120,116,1,240,179,157,219,7,0,161,174,203,157,214,7,5,4,1,174,203,157,214,7,0,161,153,236,182,220,1,3,6,1,145,224,235,133,7,0,161,223,215,172,155,15,4,3,1,241,147,239,232,6,0,161,245,181,155,135,2,22,4,1,150,152,188,203,6,0,161,192,246,139,213,2,34,20,2,181,156,253,158,6,0,161,198,223,206,159,1,175,1,4,168,181,156,253,158,6,3,1,119,231,1,123,34,117,114,108,34,58,34,104,116,116,112,115,58,47,47,105,109,97,103,101,115,46,117,110,115,112,108,97,115,104,46,99,111,109,47,112,104,111,116,111,45,49,55,49,50,51,48,51,55,48,48,56,51,50,45,53,55,100,50,98,50,98,57,49,54,98,56,63,99,114,111,112,61,101,110,116,114,111,112,121,38,99,115,61,116,105,110,121,115,114,103,98,38,102,105,116,61,109,97,120,38,102,109,61,106,112,103,38,105,120,105,100,61,77,51,119,49,77,84,69,49,77,122,100,56,77,72,119,120,102,72,74,104,98,109,82,118,98,88,120,56,102,72,120,56,102,72,120,56,102,68,69,51,77,84,77,121,78,84,107,122,78,84,100,56,38,105,120,108,105,98,61,114,98,45,52,46,48,46,51,38,113,61,56,48,38,119,61,49,48,56,48,34,44,34,119,105,100,116,104,34,58,52,50,56,46,49,57,53,51,49,50,53,44,34,97,108,105,103,110,34,58,34,114,105,103,104,116,34,125,220,2,171,236,222,251,5,0,198,204,195,206,156,1,205,4,204,195,206,156,1,206,4,4,98,111,108,100,4,116,114,117,101,196,171,236,222,251,5,0,204,195,206,156,1,206,4,4,112,97,103,101,198,171,236,222,251,5,4,204,195,206,156,1,206,4,4,98,111,108,100,4,110,117,108,108,168,204,195,206,156,1,119,1,119,222,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,43,32,78,101,119,32,80,97,103,101,32,34,125,44,123,34,105,110,115,101,114,116,34,58,34,98,117,116,116,111,110,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,111,102,32,121,111,117,114,32,115,105,100,101,98,97,114,32,116,111,32,97,100,100,32,97,32,110,101,119,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,98,111,108,100,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,112,97,103,101,34,125,44,123,34,105,110,115,101,114,116,34,58,34,46,34,125,93,44,34,99,104,101,99,107,101,100,34,58,116,114,117,101,125,168,204,195,206,156,1,120,1,119,10,122,77,121,109,67,97,118,83,107,102,168,204,195,206,156,1,121,1,119,4,116,101,120,116,193,204,195,206,156,1,129,6,204,195,206,156,1,130,6,5,198,171,236,222,251,5,13,204,195,206,156,1,130,6,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,204,195,206,156,1,11,1,161,204,195,206,156,1,12,1,161,204,195,206,156,1,13,1,161,171,236,222,251,5,15,1,161,171,236,222,251,5,16,1,161,171,236,222,251,5,17,1,193,204,195,206,156,1,129,6,171,236,222,251,5,9,5,198,171,236,222,251,5,25,171,236,222,251,5,9,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,18,1,161,171,236,222,251,5,19,1,161,171,236,222,251,5,20,1,193,204,195,206,156,1,129,6,171,236,222,251,5,21,5,198,171,236,222,251,5,34,171,236,222,251,5,21,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,27,1,161,171,236,222,251,5,28,1,161,171,236,222,251,5,29,1,198,204,195,206,156,1,129,6,171,236,222,251,5,30,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,100,98,51,54,51,54,34,193,171,236,222,251,5,39,171,236,222,251,5,30,4,198,171,236,222,251,5,43,171,236,222,251,5,30,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,36,1,161,171,236,222,251,5,37,1,161,171,236,222,251,5,38,1,193,171,236,222,251,5,39,171,236,222,251,5,40,5,198,171,236,222,251,5,52,171,236,222,251,5,40,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,45,1,161,171,236,222,251,5,46,1,161,171,236,222,251,5,47,1,193,171,236,222,251,5,39,171,236,222,251,5,48,5,198,171,236,222,251,5,61,171,236,222,251,5,48,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,54,1,161,171,236,222,251,5,55,1,161,171,236,222,251,5,56,1,198,171,236,222,251,5,39,171,236,222,251,5,57,8,98,103,95,99,111,108,111,114,12,34,48,120,102,102,102,102,100,97,101,54,34,196,171,236,222,251,5,66,171,236,222,251,5,57,4,110,101,120,116,198,171,236,222,251,5,70,171,236,222,251,5,57,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,63,1,161,171,236,222,251,5,64,1,161,171,236,222,251,5,65,1,198,204,195,206,156,1,180,6,204,195,206,156,1,181,6,9,117,110,100,101,114,108,105,110,101,4,116,114,117,101,193,171,236,222,251,5,75,204,195,206,156,1,181,6,3,198,171,236,222,251,5,78,204,195,206,156,1,181,6,9,117,110,100,101,114,108,105,110,101,4,110,117,108,108,161,171,236,222,251,5,72,1,161,171,236,222,251,5,73,1,161,171,236,222,251,5,74,1,198,171,236,222,251,5,75,171,236,222,251,5,76,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,116,114,117,101,193,171,236,222,251,5,83,171,236,222,251,5,76,3,198,171,236,222,251,5,86,171,236,222,251,5,76,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,110,117,108,108,161,171,236,222,251,5,80,1,161,171,236,222,251,5,81,1,161,171,236,222,251,5,82,1,198,171,236,222,251,5,83,171,236,222,251,5,84,6,105,116,97,108,105,99,4,116,114,117,101,193,171,236,222,251,5,91,171,236,222,251,5,84,3,198,171,236,222,251,5,94,171,236,222,251,5,84,6,105,116,97,108,105,99,4,110,117,108,108,161,171,236,222,251,5,88,1,161,171,236,222,251,5,89,1,161,171,236,222,251,5,90,1,196,171,236,222,251,5,94,171,236,222,251,5,95,9,230,140,168,233,161,191,230,137,147,161,171,236,222,251,5,96,1,161,171,236,222,251,5,97,1,161,171,236,222,251,5,98,1,39,0,204,195,206,156,1,4,6,68,89,98,118,73,66,2,33,0,204,195,206,156,1,1,6,109,57,74,107,49,75,1,0,7,33,0,204,195,206,156,1,3,6,78,76,50,70,103,95,1,193,204,195,206,156,1,238,1,204,195,206,156,1,239,1,1,168,171,236,222,251,5,102,1,119,204,5,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,67,108,105,99,107,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,43,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,98,103,95,99,111,108,111,114,34,58,34,48,120,102,102,102,102,100,97,101,54,34,44,34,102,111,110,116,95,99,111,108,111,114,34,58,34,48,120,102,102,100,98,51,54,51,54,34,125,44,34,105,110,115,101,114,116,34,58,34,110,101,120,116,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,116,111,32,97,110,121,32,112,97,103,101,32,116,105,116,108,101,32,105,110,32,116,104,101,32,115,105,100,101,98,97,114,32,116,111,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,99,111,108,111,114,34,58,34,48,120,102,102,56,52,50,55,101,48,34,125,44,34,105,110,115,101,114,116,34,58,34,113,117,105,99,107,108,121,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,105,116,97,108,105,99,34,58,116,114,117,101,44,34,115,116,114,105,107,101,116,104,114,111,117,103,104,34,58,116,114,117,101,44,34,117,110,100,101,114,108,105,110,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,230,140,168,233,161,191,230,137,147,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,97,32,110,101,119,32,115,117,98,112,97,103,101,44,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,68,111,99,117,109,101,110,116,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,102,97,108,115,101,125,44,34,105,110,115,101,114,116,34,58,34,44,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,71,114,105,100,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,102,97,108,115,101,125,44,34,105,110,115,101,114,116,34,58,34,44,32,111,114,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,75,97,110,98,97,110,32,66,111,97,114,100,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,99,111,100,101,34,58,102,97,108,115,101,125,44,34,105,110,115,101,114,116,34,58,34,46,34,125,93,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,168,171,236,222,251,5,103,1,119,10,98,113,76,109,98,57,111,45,109,109,168,171,236,222,251,5,104,1,119,4,116,101,120,116,39,0,204,195,206,156,1,4,6,68,53,45,65,82,65,2,33,0,204,195,206,156,1,1,6,89,87,119,55,87,53,1,0,7,33,0,204,195,206,156,1,3,6,85,68,79,77,112,98,1,1,0,204,195,206,156,1,14,1,39,0,204,195,206,156,1,4,6,107,90,52,97,119,69,2,33,0,204,195,206,156,1,1,6,108,79,120,55,95,83,1,0,7,33,0,204,195,206,156,1,3,6,50,109,115,116,117,104,1,193,171,236,222,251,5,115,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,52,98,104,66,88,113,2,33,0,204,195,206,156,1,1,6,121,105,115,116,115,72,1,0,7,33,0,204,195,206,156,1,3,6,53,67,71,119,50,122,1,129,171,236,222,251,5,129,1,1,39,0,204,195,206,156,1,4,6,87,105,113,49,48,95,2,33,0,204,195,206,156,1,1,6,71,121,98,79,49,81,1,0,7,33,0,204,195,206,156,1,3,6,66,90,69,117,90,106,1,193,171,236,222,251,5,129,1,171,236,222,251,5,151,1,1,39,0,204,195,206,156,1,4,6,106,101,65,53,90,85,2,39,0,204,195,206,156,1,1,6,102,67,65,65,81,117,1,40,0,171,236,222,251,5,164,1,2,105,100,1,119,6,102,67,65,65,81,117,40,0,171,236,222,251,5,164,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,171,236,222,251,5,164,1,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,164,1,8,99,104,105,108,100,114,101,110,1,119,6,52,74,88,112,120,108,33,0,171,236,222,251,5,164,1,4,100,97,116,97,1,40,0,171,236,222,251,5,164,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,164,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,52,74,88,112,120,108,0,200,171,236,222,251,5,129,1,171,236,222,251,5,162,1,1,119,6,102,67,65,65,81,117,4,0,171,236,222,251,5,163,1,6,228,189,147,233,170,140,129,171,236,222,251,5,175,1,1,161,171,236,222,251,5,169,1,1,198,171,236,222,251,5,175,1,171,236,222,251,5,176,1,9,117,110,100,101,114,108,105,110,101,4,116,114,117,101,193,171,236,222,251,5,178,1,171,236,222,251,5,176,1,1,198,171,236,222,251,5,179,1,171,236,222,251,5,176,1,9,117,110,100,101,114,108,105,110,101,4,110,117,108,108,161,171,236,222,251,5,177,1,1,198,171,236,222,251,5,178,1,171,236,222,251,5,179,1,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,116,114,117,101,196,171,236,222,251,5,182,1,171,236,222,251,5,179,1,3,228,184,128,198,171,236,222,251,5,183,1,171,236,222,251,5,179,1,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,110,117,108,108,168,171,236,222,251,5,181,1,1,119,101,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,228,189,147,233,170,140,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,115,116,114,105,107,101,116,104,114,111,117,103,104,34,58,116,114,117,101,44,34,117,110,100,101,114,108,105,110,101,34,58,116,114,117,101,125,44,34,105,110,115,101,114,116,34,58,34,228,184,128,34,125,93,125,39,0,204,195,206,156,1,4,6,82,74,108,100,72,67,2,33,0,204,195,206,156,1,1,6,53,106,100,78,87,117,1,0,7,33,0,204,195,206,156,1,3,6,67,106,107,76,57,108,1,129,171,236,222,251,5,151,1,1,4,0,171,236,222,251,5,186,1,4,103,104,104,104,0,1,39,0,204,195,206,156,1,4,6,70,117,117,52,113,66,2,4,0,171,236,222,251,5,202,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,121,112,70,119,50,69,1,0,7,33,0,204,195,206,156,1,3,6,71,77,54,72,55,119,1,193,171,236,222,251,5,151,1,171,236,222,251,5,196,1,1,39,0,204,195,206,156,1,4,6,118,113,76,104,110,70,2,4,0,171,236,222,251,5,217,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,73,57,73,75,116,115,1,0,7,33,0,204,195,206,156,1,3,6,77,114,102,81,106,87,1,193,171,236,222,251,5,140,1,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,89,50,52,104,77,55,2,4,0,171,236,222,251,5,232,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,107,110,74,87,104,48,1,0,7,33,0,204,195,206,156,1,3,6,55,99,67,68,120,77,1,129,171,236,222,251,5,196,1,1,0,7,39,0,204,195,206,156,1,4,6,109,98,56,104,95,45,2,4,0,171,236,222,251,5,254,1,4,103,104,104,104,33,0,204,195,206,156,1,1,6,103,75,73,116,90,101,1,0,7,33,0,204,195,206,156,1,3,6,118,115,54,50,82,105,1,193,171,236,222,251,5,196,1,171,236,222,251,5,246,1,1,39,0,204,195,206,156,1,4,6,105,67,98,56,102,56,2,4,0,171,236,222,251,5,141,2,4,103,104,104,104,33,0,204,195,206,156,1,1,6,88,113,72,53,122,82,1,0,7,33,0,204,195,206,156,1,3,6,73,111,48,108,119,67,1,193,171,236,222,251,5,196,1,171,236,222,251,5,140,2,1,39,0,204,195,206,156,1,4,6,82,89,116,67,111,86,2,4,0,171,236,222,251,5,156,2,4,103,104,104,104,39,0,204,195,206,156,1,1,6,49,120,78,111,50,76,1,40,0,171,236,222,251,5,161,2,2,105,100,1,119,6,49,120,78,111,50,76,40,0,171,236,222,251,5,161,2,2,116,121,1,119,5,113,117,111,116,101,40,0,171,236,222,251,5,161,2,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,161,2,8,99,104,105,108,100,114,101,110,1,119,6,67,85,68,115,45,70,33,0,171,236,222,251,5,161,2,4,100,97,116,97,1,40,0,171,236,222,251,5,161,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,161,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,67,85,68,115,45,70,0,200,171,236,222,251,5,196,1,171,236,222,251,5,155,2,1,119,6,49,120,78,111,50,76,39,0,204,195,206,156,1,4,6,122,112,90,112,49,101,2,33,0,204,195,206,156,1,1,6,109,65,112,48,84,75,1,0,7,33,0,204,195,206,156,1,3,6,117,95,113,85,121,95,1,129,171,236,222,251,5,246,1,1,4,0,171,236,222,251,5,171,2,4,104,106,106,106,0,1,39,0,204,195,206,156,1,4,6,79,88,120,110,65,84,2,4,0,171,236,222,251,5,187,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,109,70,99,75,110,81,1,0,7,33,0,204,195,206,156,1,3,6,72,52,122,104,56,95,1,193,171,236,222,251,5,246,1,171,236,222,251,5,181,2,1,39,0,204,195,206,156,1,4,6,90,97,54,99,87,113,2,4,0,171,236,222,251,5,202,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,50,110,113,71,98,75,1,0,7,33,0,204,195,206,156,1,3,6,95,69,69,76,53,109,1,193,171,236,222,251,5,246,1,171,236,222,251,5,201,2,1,39,0,204,195,206,156,1,4,6,95,88,107,52,56,116,2,4,0,171,236,222,251,5,217,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,68,99,97,85,109,79,1,0,7,33,0,204,195,206,156,1,3,6,120,69,54,111,108,48,1,193,171,236,222,251,5,231,1,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,82,106,87,98,56,111,2,4,0,171,236,222,251,5,232,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,87,98,82,107,87,69,1,0,7,33,0,204,195,206,156,1,3,6,89,103,114,112,81,55,1,129,171,236,222,251,5,181,2,1,39,0,204,195,206,156,1,4,6,112,107,78,57,112,83,2,4,0,171,236,222,251,5,247,2,4,104,106,106,106,33,0,204,195,206,156,1,1,6,79,98,74,118,76,57,1,0,7,33,0,204,195,206,156,1,3,6,97,79,100,49,121,82,1,193,171,236,222,251,5,181,2,171,236,222,251,5,246,2,1,39,0,204,195,206,156,1,4,6,99,51,100,115,103,56,2,4,0,171,236,222,251,5,134,3,4,104,106,106,106,33,0,204,195,206,156,1,1,6,109,119,79,85,85,87,1,0,7,33,0,204,195,206,156,1,3,6,98,70,74,53,121,122,1,193,171,236,222,251,5,181,2,171,236,222,251,5,133,3,1,39,0,204,195,206,156,1,4,6,104,82,53,106,71,79,2,1,0,171,236,222,251,5,149,3,4,33,0,204,195,206,156,1,1,6,73,77,51,71,72,50,1,0,7,33,0,204,195,206,156,1,3,6,119,85,111,112,97,102,1,193,171,236,222,251,5,181,2,171,236,222,251,5,148,3,1,0,4,39,0,204,195,206,156,1,4,6,74,66,108,114,84,51,2,33,0,204,195,206,156,1,1,6,76,105,86,56,56,104,1,0,7,33,0,204,195,206,156,1,3,6,112,106,107,107,53,97,1,193,171,236,222,251,5,181,2,171,236,222,251,5,163,3,1,1,0,171,236,222,251,5,168,3,1,0,2,129,171,236,222,251,5,179,3,1,0,1,196,171,236,222,251,5,179,3,171,236,222,251,5,182,3,3,226,128,148,0,1,39,0,204,195,206,156,1,4,6,89,108,67,77,99,111,2,39,0,204,195,206,156,1,1,6,112,69,80,105,117,115,1,40,0,171,236,222,251,5,187,3,2,105,100,1,119,6,112,69,80,105,117,115,40,0,171,236,222,251,5,187,3,2,116,121,1,119,7,100,105,118,105,100,101,114,40,0,171,236,222,251,5,187,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,187,3,8,99,104,105,108,100,114,101,110,1,119,6,49,45,49,107,111,85,40,0,171,236,222,251,5,187,3,4,100,97,116,97,1,119,2,123,125,40,0,171,236,222,251,5,187,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,187,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,49,45,49,107,111,85,0,200,171,236,222,251,5,181,2,171,236,222,251,5,178,3,1,119,6,112,69,80,105,117,115,39,0,204,195,206,156,1,1,6,95,65,78,99,110,51,1,40,0,171,236,222,251,5,197,3,2,105,100,1,119,6,95,65,78,99,110,51,40,0,171,236,222,251,5,197,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,171,236,222,251,5,197,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,197,3,8,99,104,105,108,100,114,101,110,1,119,6,84,45,117,87,109,83,33,0,171,236,222,251,5,197,3,4,100,97,116,97,1,40,0,171,236,222,251,5,197,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,197,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,84,45,117,87,109,83,0,136,171,236,222,251,5,246,2,1,119,6,95,65,78,99,110,51,4,0,171,236,222,251,5,186,3,1,54,161,171,236,222,251,5,202,3,1,132,171,236,222,251,5,207,3,1,54,161,171,236,222,251,5,208,3,1,132,171,236,222,251,5,209,3,1,54,161,171,236,222,251,5,210,3,1,132,171,236,222,251,5,211,3,1,57,168,171,236,222,251,5,212,3,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,54,54,54,57,34,125,93,125,39,0,204,195,206,156,1,1,6,79,77,79,95,52,106,1,40,0,171,236,222,251,5,215,3,2,105,100,1,119,6,79,77,79,95,52,106,40,0,171,236,222,251,5,215,3,2,116,121,1,119,7,100,105,118,105,100,101,114,40,0,171,236,222,251,5,215,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,171,236,222,251,5,215,3,8,99,104,105,108,100,114,101,110,1,119,6,99,107,78,65,119,105,40,0,171,236,222,251,5,215,3,4,100,97,116,97,1,119,2,123,125,40,0,171,236,222,251,5,215,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,215,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,99,107,78,65,119,105,0,200,171,236,222,251,5,246,2,171,236,222,251,5,206,3,1,119,6,79,77,79,95,52,106,39,0,204,195,206,156,1,4,6,45,80,118,95,90,87,2,4,0,171,236,222,251,5,225,3,4,103,104,104,104,39,0,204,195,206,156,1,4,6,87,105,54,69,77,70,2,4,0,171,236,222,251,5,230,3,4,54,54,54,57,39,0,204,195,206,156,1,1,6,122,78,116,118,66,84,1,40,0,171,236,222,251,5,235,3,2,105,100,1,119,6,122,78,116,118,66,84,40,0,171,236,222,251,5,235,3,2,116,121,1,119,5,113,117,111,116,101,40,0,171,236,222,251,5,235,3,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,171,236,222,251,5,235,3,8,99,104,105,108,100,114,101,110,1,119,6,105,85,75,111,98,79,33,0,171,236,222,251,5,235,3,4,100,97,116,97,1,40,0,171,236,222,251,5,235,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,235,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,105,85,75,111,98,79,0,200,171,236,222,251,5,231,2,204,195,206,156,1,239,1,1,119,6,122,78,116,118,66,84,33,0,204,195,206,156,1,1,6,57,104,76,90,119,104,1,0,7,33,0,204,195,206,156,1,3,6,120,113,118,100,85,73,1,193,171,236,222,251,5,244,3,204,195,206,156,1,239,1,1,39,0,204,195,206,156,1,4,6,75,122,88,45,65,53,2,1,0,171,236,222,251,5,255,3,4,39,0,204,195,206,156,1,1,6,49,51,100,105,49,69,1,40,0,171,236,222,251,5,132,4,2,105,100,1,119,6,49,51,100,105,49,69,40,0,171,236,222,251,5,132,4,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,171,236,222,251,5,132,4,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,171,236,222,251,5,132,4,8,99,104,105,108,100,114,101,110,1,119,6,106,54,115,52,103,109,33,0,171,236,222,251,5,132,4,4,100,97,116,97,1,40,0,171,236,222,251,5,132,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,171,236,222,251,5,132,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,54,115,52,103,109,0,200,171,236,222,251,5,244,3,171,236,222,251,5,254,3,1,119,6,49,51,100,105,49,69,161,171,236,222,251,5,137,4,2,65,171,236,222,251,5,128,4,5,198,171,236,222,251,5,148,4,171,236,222,251,5,128,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,143,4,1,65,171,236,222,251,5,144,4,5,198,171,236,222,251,5,155,4,171,236,222,251,5,144,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,150,4,1,65,171,236,222,251,5,151,4,5,198,171,236,222,251,5,162,4,171,236,222,251,5,151,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,157,4,1,65,171,236,222,251,5,158,4,5,198,171,236,222,251,5,169,4,171,236,222,251,5,158,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,164,4,1,65,171,236,222,251,5,165,4,5,198,171,236,222,251,5,176,4,171,236,222,251,5,165,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,171,4,1,65,171,236,222,251,5,172,4,5,198,171,236,222,251,5,183,4,171,236,222,251,5,172,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,178,4,1,65,171,236,222,251,5,179,4,5,198,171,236,222,251,5,190,4,171,236,222,251,5,179,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,185,4,1,65,171,236,222,251,5,186,4,5,198,171,236,222,251,5,197,4,171,236,222,251,5,186,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,192,4,1,70,171,236,222,251,5,193,4,8,98,103,95,99,111,108,111,114,12,34,48,120,102,102,102,102,100,97,101,54,34,193,171,236,222,251,5,200,4,171,236,222,251,5,193,4,4,198,171,236,222,251,5,204,4,171,236,222,251,5,193,4,8,98,103,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,199,4,2,193,171,236,222,251,5,200,4,171,236,222,251,5,201,4,5,198,171,236,222,251,5,212,4,171,236,222,251,5,201,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,207,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,208,4,5,198,171,236,222,251,5,219,4,171,236,222,251,5,208,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,214,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,215,4,5,198,171,236,222,251,5,226,4,171,236,222,251,5,215,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,221,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,222,4,5,198,171,236,222,251,5,233,4,171,236,222,251,5,222,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,228,4,1,193,171,236,222,251,5,200,4,171,236,222,251,5,229,4,5,198,171,236,222,251,5,240,4,171,236,222,251,5,229,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,161,171,236,222,251,5,235,4,1,70,171,236,222,251,5,200,4,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,101,97,56,102,48,54,34,198,171,236,222,251,5,243,4,171,236,222,251,5,200,4,8,98,103,95,99,111,108,111,114,12,34,48,120,102,102,97,55,100,102,52,97,34,196,171,236,222,251,5,244,4,171,236,222,251,5,200,4,4,54,54,54,57,193,171,236,222,251,5,248,4,171,236,222,251,5,200,4,1,198,171,236,222,251,5,249,4,171,236,222,251,5,200,4,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,168,171,236,222,251,5,242,4,1,119,110,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,98,103,95,99,111,108,111,114,34,58,34,48,120,102,102,97,55,100,102,52,97,34,44,34,102,111,110,116,95,99,111,108,111,114,34,58,34,48,120,102,102,101,97,56,102,48,54,34,125,44,34,105,110,115,101,114,116,34,58,34,54,54,54,57,34,125,93,125,7,226,167,254,250,5,0,39,0,204,195,206,156,1,4,6,72,97,87,55,95,104,2,4,0,226,167,254,250,5,0,13,229,144,140,228,184,128,228,184,170,106,106,106,56,161,198,223,206,159,1,124,1,132,226,167,254,250,5,7,1,56,161,226,167,254,250,5,8,1,132,226,167,254,250,5,9,1,56,161,226,167,254,250,5,10,1,1,161,234,157,145,5,0,161,247,212,219,208,10,45,7,3,177,239,218,225,4,0,161,207,231,154,196,9,0,1,161,207,231,154,196,9,1,1,161,207,231,154,196,9,2,1,1,136,172,186,168,4,0,161,176,238,158,139,14,174,2,182,6,24,141,151,160,163,4,0,161,177,239,218,225,4,0,1,161,177,239,218,225,4,1,1,161,177,239,218,225,4,2,1,161,141,151,160,163,4,0,1,161,141,151,160,163,4,1,1,161,141,151,160,163,4,2,1,161,141,151,160,163,4,3,1,161,141,151,160,163,4,4,1,161,141,151,160,163,4,5,1,161,141,151,160,163,4,6,1,161,141,151,160,163,4,7,1,161,141,151,160,163,4,8,1,161,141,151,160,163,4,9,1,161,141,151,160,163,4,10,1,161,141,151,160,163,4,11,1,161,141,151,160,163,4,12,1,161,141,151,160,163,4,13,1,161,141,151,160,163,4,14,1,161,141,151,160,163,4,15,1,161,141,151,160,163,4,16,1,161,141,151,160,163,4,17,1,161,141,151,160,163,4,18,1,161,141,151,160,163,4,19,1,161,141,151,160,163,4,20,1,4,217,168,198,159,4,0,129,204,195,206,156,1,154,7,4,161,204,195,206,156,1,227,1,1,161,204,195,206,156,1,228,1,1,161,204,195,206,156,1,229,1,1,51,220,225,223,240,3,0,1,0,204,195,206,156,1,132,4,1,161,204,195,206,156,1,83,1,161,204,195,206,156,1,84,1,161,204,195,206,156,1,85,1,134,220,225,223,240,3,0,7,109,101,110,116,105,111,110,64,123,34,112,97,103,101,95,105,100,34,58,34,100,48,52,57,54,51,50,52,45,53,53,55,48,45,52,48,48,54,45,98,52,101,97,45,100,98,55,53,49,54,100,50,49,50,102,100,34,44,34,116,121,112,101,34,58,34,112,97,103,101,34,125,132,220,225,223,240,3,4,1,36,134,220,225,223,240,3,5,7,109,101,110,116,105,111,110,4,110,117,108,108,161,220,225,223,240,3,1,1,161,220,225,223,240,3,2,1,161,220,225,223,240,3,3,1,39,0,204,195,206,156,1,4,6,50,108,103,80,119,50,2,33,0,204,195,206,156,1,1,6,115,120,112,66,109,100,1,0,7,33,0,204,195,206,156,1,3,6,52,97,66,55,99,78,1,193,204,195,206,156,1,250,1,204,195,206,156,1,251,1,1,1,0,220,225,223,240,3,10,1,0,2,129,220,225,223,240,3,21,1,0,2,161,243,138,171,183,10,249,1,1,161,243,138,171,183,10,250,1,1,161,243,138,171,183,10,251,1,1,161,220,225,223,240,3,27,1,161,220,225,223,240,3,28,1,161,220,225,223,240,3,29,1,161,194,228,144,71,7,2,39,0,204,195,206,156,1,4,6,48,102,55,71,122,95,2,39,0,204,195,206,156,1,1,6,54,118,84,69,79,115,1,40,0,220,225,223,240,3,36,2,105,100,1,119,6,54,118,84,69,79,115,40,0,220,225,223,240,3,36,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,220,225,223,240,3,36,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,220,225,223,240,3,36,8,99,104,105,108,100,114,101,110,1,119,6,106,107,73,81,115,57,33,0,220,225,223,240,3,36,4,100,97,116,97,1,40,0,220,225,223,240,3,36,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,220,225,223,240,3,36,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,107,73,81,115,57,0,200,220,225,223,240,3,20,204,195,206,156,1,251,1,1,119,6,54,118,84,69,79,115,1,0,220,225,223,240,3,35,1,161,220,225,223,240,3,41,1,134,220,225,223,240,3,46,7,109,101,110,116,105,111,110,64,123,34,112,97,103,101,95,105,100,34,58,34,52,52,51,53,101,53,55,98,45,99,50,54,51,45,52,101,55,102,45,97,52,51,53,45,50,48,56,55,57,97,54,50,101,54,100,97,34,44,34,116,121,112,101,34,58,34,112,97,103,101,34,125,132,220,225,223,240,3,48,1,36,134,220,225,223,240,3,49,7,109,101,110,116,105,111,110,4,110,117,108,108,161,220,225,223,240,3,47,1,39,0,204,195,206,156,1,4,6,111,89,48,54,98,73,2,161,220,225,223,240,3,51,1,1,0,220,225,223,240,3,52,1,161,220,225,223,240,3,53,1,134,220,225,223,240,3,54,7,109,101,110,116,105,111,110,64,123,34,112,97,103,101,95,105,100,34,58,34,100,100,98,57,51,98,97,55,45,48,54,99,55,45,52,49,55,54,45,57,56,50,97,45,100,55,52,50,51,101,48,57,98,52,52,49,34,44,34,116,121,112,101,34,58,34,112,97,103,101,34,125,132,220,225,223,240,3,56,1,36,134,220,225,223,240,3,57,7,109,101,110,116,105,111,110,4,110,117,108,108,161,220,225,223,240,3,55,1,29,133,181,204,218,3,0,39,0,204,195,206,156,1,4,6,118,122,72,105,108,97,2,6,0,133,181,204,218,3,0,4,104,114,101,102,13,34,49,57,50,46,49,54,56,46,49,46,50,34,132,133,181,204,218,3,1,9,99,111,110,116,101,110,116,32,49,134,133,181,204,218,3,10,4,104,114,101,102,4,110,117,108,108,132,133,181,204,218,3,11,3,32,50,32,161,238,153,239,204,9,48,1,132,133,181,204,218,3,14,1,97,161,133,181,204,218,3,15,1,129,133,181,204,218,3,16,1,132,133,181,204,218,3,18,1,112,161,133,181,204,218,3,17,1,196,133,181,204,218,3,16,133,181,204,218,3,18,1,112,161,133,181,204,218,3,20,1,132,133,181,204,218,3,19,1,102,161,133,181,204,218,3,22,1,132,133,181,204,218,3,23,1,108,161,133,181,204,218,3,24,1,132,133,181,204,218,3,25,1,111,161,133,181,204,218,3,26,1,132,133,181,204,218,3,27,1,119,161,133,181,204,218,3,28,1,132,133,181,204,218,3,29,1,121,168,133,181,204,218,3,30,1,119,95,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,104,114,101,102,34,58,34,49,57,50,46,49,54,56,46,49,46,50,34,125,44,34,105,110,115,101,114,116,34,58,34,99,111,110,116,101,110,116,32,49,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,50,32,97,112,112,102,108,111,119,121,34,125,93,125,39,0,204,195,206,156,1,4,6,68,50,72,75,72,71,2,6,0,133,181,204,218,3,33,4,104,114,101,102,22,34,97,112,112,102,108,111,119,121,46,105,111,47,100,111,119,110,108,111,97,100,34,132,133,181,204,218,3,34,11,97,112,112,102,108,111,119,121,46,105,111,134,133,181,204,218,3,45,4,104,114,101,102,4,110,117,108,108,132,133,181,204,218,3,46,2,32,49,168,238,153,239,204,9,32,1,119,97,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,104,114,101,102,34,58,34,97,112,112,102,108,111,119,121,46,105,111,47,100,111,119,110,108,111,97,100,34,125,44,34,105,110,115,101,114,116,34,58,34,97,112,112,102,108,111,119,121,46,105,111,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,49,34,125,93,125,1,236,253,128,205,3,0,161,240,179,157,219,7,3,9,215,6,150,216,171,142,3,0,161,199,130,209,189,2,177,3,6,161,164,202,219,213,10,80,1,161,164,202,219,213,10,81,1,161,164,202,219,213,10,82,1,161,150,216,171,142,3,6,1,161,150,216,171,142,3,7,1,161,150,216,171,142,3,8,1,129,204,195,206,156,1,207,5,1,161,150,216,171,142,3,9,1,161,150,216,171,142,3,10,1,161,150,216,171,142,3,11,1,129,150,216,171,142,3,12,1,161,150,216,171,142,3,13,1,161,150,216,171,142,3,14,1,161,150,216,171,142,3,15,1,161,150,216,171,142,3,17,1,161,150,216,171,142,3,18,1,161,150,216,171,142,3,19,1,161,150,216,171,142,3,20,1,161,150,216,171,142,3,21,1,161,150,216,171,142,3,22,1,129,150,216,171,142,3,16,1,161,150,216,171,142,3,23,1,161,150,216,171,142,3,24,1,161,150,216,171,142,3,25,1,129,150,216,171,142,3,26,1,161,150,216,171,142,3,27,1,161,150,216,171,142,3,28,1,161,150,216,171,142,3,29,1,129,150,216,171,142,3,30,1,161,150,216,171,142,3,31,1,161,150,216,171,142,3,32,1,161,150,216,171,142,3,33,1,129,150,216,171,142,3,34,1,161,150,216,171,142,3,35,1,161,150,216,171,142,3,36,1,161,150,216,171,142,3,37,1,129,150,216,171,142,3,38,1,161,150,216,171,142,3,39,1,161,150,216,171,142,3,40,1,161,150,216,171,142,3,41,1,129,150,216,171,142,3,42,1,161,150,216,171,142,3,43,1,161,150,216,171,142,3,44,1,161,150,216,171,142,3,45,1,129,150,216,171,142,3,46,1,161,150,216,171,142,3,47,1,161,150,216,171,142,3,48,1,161,150,216,171,142,3,49,1,129,150,216,171,142,3,50,1,161,150,216,171,142,3,51,1,161,150,216,171,142,3,52,1,161,150,216,171,142,3,53,1,129,150,216,171,142,3,54,1,161,150,216,171,142,3,55,1,161,150,216,171,142,3,56,1,161,150,216,171,142,3,57,1,129,150,216,171,142,3,58,1,161,150,216,171,142,3,59,1,161,150,216,171,142,3,60,1,161,150,216,171,142,3,61,1,129,150,216,171,142,3,62,1,161,150,216,171,142,3,63,1,161,150,216,171,142,3,64,1,161,150,216,171,142,3,65,1,129,150,216,171,142,3,66,1,161,150,216,171,142,3,67,1,161,150,216,171,142,3,68,1,161,150,216,171,142,3,69,1,129,150,216,171,142,3,70,1,161,150,216,171,142,3,71,1,161,150,216,171,142,3,72,1,161,150,216,171,142,3,73,1,129,150,216,171,142,3,74,1,161,150,216,171,142,3,75,1,161,150,216,171,142,3,76,1,161,150,216,171,142,3,77,1,129,150,216,171,142,3,78,1,161,150,216,171,142,3,79,1,161,150,216,171,142,3,80,1,161,150,216,171,142,3,81,1,129,150,216,171,142,3,82,1,161,150,216,171,142,3,83,1,161,150,216,171,142,3,84,1,161,150,216,171,142,3,85,1,129,150,216,171,142,3,86,1,161,150,216,171,142,3,87,1,161,150,216,171,142,3,88,1,161,150,216,171,142,3,89,1,129,150,216,171,142,3,90,1,161,150,216,171,142,3,91,1,161,150,216,171,142,3,92,1,161,150,216,171,142,3,93,1,129,150,216,171,142,3,94,1,161,150,216,171,142,3,95,1,161,150,216,171,142,3,96,1,161,150,216,171,142,3,97,1,129,150,216,171,142,3,98,1,161,150,216,171,142,3,99,1,161,150,216,171,142,3,100,1,161,150,216,171,142,3,101,1,129,150,216,171,142,3,102,1,161,150,216,171,142,3,103,1,161,150,216,171,142,3,104,1,161,150,216,171,142,3,105,1,129,150,216,171,142,3,106,1,161,150,216,171,142,3,107,1,161,150,216,171,142,3,108,1,161,150,216,171,142,3,109,1,129,150,216,171,142,3,110,1,161,150,216,171,142,3,111,1,161,150,216,171,142,3,112,1,161,150,216,171,142,3,113,1,129,150,216,171,142,3,114,1,161,150,216,171,142,3,115,1,161,150,216,171,142,3,116,1,161,150,216,171,142,3,117,1,129,150,216,171,142,3,118,1,161,150,216,171,142,3,119,1,161,150,216,171,142,3,120,1,161,150,216,171,142,3,121,1,129,150,216,171,142,3,122,1,161,150,216,171,142,3,123,1,161,150,216,171,142,3,124,1,161,150,216,171,142,3,125,1,129,150,216,171,142,3,126,1,161,150,216,171,142,3,127,1,161,150,216,171,142,3,128,1,1,161,150,216,171,142,3,129,1,1,129,150,216,171,142,3,130,1,1,161,150,216,171,142,3,131,1,1,161,150,216,171,142,3,132,1,1,161,150,216,171,142,3,133,1,1,129,150,216,171,142,3,134,1,1,161,150,216,171,142,3,135,1,1,161,150,216,171,142,3,136,1,1,161,150,216,171,142,3,137,1,1,193,150,216,171,142,3,134,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,139,1,1,161,150,216,171,142,3,140,1,1,161,150,216,171,142,3,141,1,1,193,150,216,171,142,3,142,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,143,1,1,161,150,216,171,142,3,144,1,1,161,150,216,171,142,3,145,1,1,193,150,216,171,142,3,146,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,147,1,1,161,150,216,171,142,3,148,1,1,161,150,216,171,142,3,149,1,1,193,150,216,171,142,3,150,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,151,1,1,161,150,216,171,142,3,152,1,1,161,150,216,171,142,3,153,1,1,193,150,216,171,142,3,154,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,155,1,1,161,150,216,171,142,3,156,1,1,161,150,216,171,142,3,157,1,1,193,150,216,171,142,3,158,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,159,1,1,161,150,216,171,142,3,160,1,1,161,150,216,171,142,3,161,1,1,193,150,216,171,142,3,162,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,163,1,1,161,150,216,171,142,3,164,1,1,161,150,216,171,142,3,165,1,1,193,150,216,171,142,3,166,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,167,1,1,161,150,216,171,142,3,168,1,1,161,150,216,171,142,3,169,1,1,193,150,216,171,142,3,170,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,171,1,1,161,150,216,171,142,3,172,1,1,161,150,216,171,142,3,173,1,1,193,150,216,171,142,3,174,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,175,1,1,161,150,216,171,142,3,176,1,1,161,150,216,171,142,3,177,1,1,193,150,216,171,142,3,178,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,179,1,1,161,150,216,171,142,3,180,1,1,161,150,216,171,142,3,181,1,1,193,150,216,171,142,3,182,1,150,216,171,142,3,138,1,1,161,150,216,171,142,3,183,1,1,161,150,216,171,142,3,184,1,1,161,150,216,171,142,3,185,1,1,129,150,216,171,142,3,138,1,4,161,150,216,171,142,3,187,1,1,161,150,216,171,142,3,188,1,1,161,150,216,171,142,3,189,1,1,129,150,216,171,142,3,193,1,1,161,150,216,171,142,3,194,1,1,161,150,216,171,142,3,195,1,1,161,150,216,171,142,3,196,1,1,161,150,216,171,142,3,198,1,1,161,150,216,171,142,3,199,1,1,161,150,216,171,142,3,200,1,1,161,150,216,171,142,3,201,1,1,161,150,216,171,142,3,202,1,1,161,150,216,171,142,3,203,1,1,161,150,216,171,142,3,204,1,1,161,150,216,171,142,3,205,1,1,161,150,216,171,142,3,206,1,1,129,150,216,171,142,3,197,1,1,161,150,216,171,142,3,207,1,1,161,150,216,171,142,3,208,1,1,161,150,216,171,142,3,209,1,1,129,150,216,171,142,3,210,1,1,161,150,216,171,142,3,211,1,1,161,150,216,171,142,3,212,1,1,161,150,216,171,142,3,213,1,1,129,150,216,171,142,3,214,1,1,161,150,216,171,142,3,215,1,1,161,150,216,171,142,3,216,1,1,161,150,216,171,142,3,217,1,1,129,150,216,171,142,3,218,1,1,161,150,216,171,142,3,219,1,1,161,150,216,171,142,3,220,1,1,161,150,216,171,142,3,221,1,1,129,150,216,171,142,3,222,1,1,161,150,216,171,142,3,223,1,1,161,150,216,171,142,3,224,1,1,161,150,216,171,142,3,225,1,1,129,150,216,171,142,3,226,1,1,161,150,216,171,142,3,227,1,1,161,150,216,171,142,3,228,1,1,161,150,216,171,142,3,229,1,1,129,150,216,171,142,3,230,1,1,161,150,216,171,142,3,231,1,1,161,150,216,171,142,3,232,1,1,161,150,216,171,142,3,233,1,1,129,150,216,171,142,3,234,1,1,161,150,216,171,142,3,235,1,1,161,150,216,171,142,3,236,1,1,161,150,216,171,142,3,237,1,1,129,150,216,171,142,3,238,1,1,161,150,216,171,142,3,239,1,1,161,150,216,171,142,3,240,1,1,161,150,216,171,142,3,241,1,1,129,150,216,171,142,3,242,1,1,161,150,216,171,142,3,243,1,1,161,150,216,171,142,3,244,1,1,161,150,216,171,142,3,245,1,1,129,150,216,171,142,3,246,1,1,161,150,216,171,142,3,247,1,1,161,150,216,171,142,3,248,1,1,161,150,216,171,142,3,249,1,1,129,150,216,171,142,3,250,1,1,161,150,216,171,142,3,251,1,1,161,150,216,171,142,3,252,1,1,161,150,216,171,142,3,253,1,1,129,150,216,171,142,3,254,1,1,161,150,216,171,142,3,255,1,1,161,150,216,171,142,3,128,2,1,161,150,216,171,142,3,129,2,1,129,150,216,171,142,3,130,2,1,161,150,216,171,142,3,131,2,1,161,150,216,171,142,3,132,2,1,161,150,216,171,142,3,133,2,1,129,150,216,171,142,3,134,2,1,161,150,216,171,142,3,135,2,1,161,150,216,171,142,3,136,2,1,161,150,216,171,142,3,137,2,1,129,150,216,171,142,3,138,2,1,161,150,216,171,142,3,139,2,1,161,150,216,171,142,3,140,2,1,161,150,216,171,142,3,141,2,1,161,150,216,171,142,3,143,2,1,161,150,216,171,142,3,144,2,1,161,150,216,171,142,3,145,2,1,129,150,216,171,142,3,142,2,1,161,150,216,171,142,3,146,2,1,161,150,216,171,142,3,147,2,1,161,150,216,171,142,3,148,2,1,161,150,216,171,142,3,150,2,1,161,150,216,171,142,3,151,2,1,161,150,216,171,142,3,152,2,1,161,150,216,171,142,3,153,2,1,161,150,216,171,142,3,154,2,1,161,150,216,171,142,3,155,2,1,161,150,216,171,142,3,156,2,1,161,150,216,171,142,3,157,2,1,161,150,216,171,142,3,158,2,1,129,150,216,171,142,3,149,2,1,161,150,216,171,142,3,159,2,1,161,150,216,171,142,3,160,2,1,161,150,216,171,142,3,161,2,1,129,150,216,171,142,3,162,2,1,161,150,216,171,142,3,163,2,1,161,150,216,171,142,3,164,2,1,161,150,216,171,142,3,165,2,1,129,150,216,171,142,3,166,2,1,161,150,216,171,142,3,167,2,1,161,150,216,171,142,3,168,2,1,161,150,216,171,142,3,169,2,1,129,150,216,171,142,3,170,2,1,161,150,216,171,142,3,171,2,1,161,150,216,171,142,3,172,2,1,161,150,216,171,142,3,173,2,1,129,150,216,171,142,3,174,2,1,161,150,216,171,142,3,175,2,1,161,150,216,171,142,3,176,2,1,161,150,216,171,142,3,177,2,1,129,150,216,171,142,3,178,2,1,161,150,216,171,142,3,179,2,1,161,150,216,171,142,3,180,2,1,161,150,216,171,142,3,181,2,1,129,150,216,171,142,3,182,2,1,161,150,216,171,142,3,183,2,1,161,150,216,171,142,3,184,2,1,161,150,216,171,142,3,185,2,1,129,150,216,171,142,3,186,2,1,161,150,216,171,142,3,187,2,1,161,150,216,171,142,3,188,2,1,161,150,216,171,142,3,189,2,1,129,150,216,171,142,3,190,2,1,161,150,216,171,142,3,191,2,1,161,150,216,171,142,3,192,2,1,161,150,216,171,142,3,193,2,1,129,150,216,171,142,3,194,2,1,161,150,216,171,142,3,195,2,1,161,150,216,171,142,3,196,2,1,161,150,216,171,142,3,197,2,1,129,150,216,171,142,3,198,2,1,161,150,216,171,142,3,199,2,1,161,150,216,171,142,3,200,2,1,161,150,216,171,142,3,201,2,1,193,150,216,171,142,3,198,2,150,216,171,142,3,202,2,1,161,150,216,171,142,3,203,2,1,161,150,216,171,142,3,204,2,1,161,150,216,171,142,3,205,2,1,193,150,216,171,142,3,206,2,150,216,171,142,3,202,2,1,161,150,216,171,142,3,207,2,1,161,150,216,171,142,3,208,2,1,161,150,216,171,142,3,209,2,1,193,150,216,171,142,3,206,2,150,216,171,142,3,210,2,2,161,150,216,171,142,3,211,2,1,161,150,216,171,142,3,212,2,1,161,150,216,171,142,3,213,2,1,193,150,216,171,142,3,215,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,216,2,1,161,150,216,171,142,3,217,2,1,161,150,216,171,142,3,218,2,1,193,150,216,171,142,3,219,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,220,2,1,161,150,216,171,142,3,221,2,1,161,150,216,171,142,3,222,2,1,193,150,216,171,142,3,223,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,224,2,1,161,150,216,171,142,3,225,2,1,161,150,216,171,142,3,226,2,1,193,150,216,171,142,3,227,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,228,2,1,161,150,216,171,142,3,229,2,1,161,150,216,171,142,3,230,2,1,193,150,216,171,142,3,231,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,232,2,1,161,150,216,171,142,3,233,2,1,161,150,216,171,142,3,234,2,1,193,150,216,171,142,3,235,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,236,2,1,161,150,216,171,142,3,237,2,1,161,150,216,171,142,3,238,2,1,193,150,216,171,142,3,239,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,240,2,1,161,150,216,171,142,3,241,2,1,161,150,216,171,142,3,242,2,1,193,150,216,171,142,3,243,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,244,2,1,161,150,216,171,142,3,245,2,1,161,150,216,171,142,3,246,2,1,193,150,216,171,142,3,247,2,150,216,171,142,3,210,2,1,161,150,216,171,142,3,248,2,1,161,150,216,171,142,3,249,2,1,161,150,216,171,142,3,250,2,1,193,150,216,171,142,3,247,2,150,216,171,142,3,251,2,1,161,150,216,171,142,3,252,2,1,161,150,216,171,142,3,253,2,1,161,150,216,171,142,3,254,2,1,193,150,216,171,142,3,255,2,150,216,171,142,3,251,2,1,161,150,216,171,142,3,128,3,1,161,150,216,171,142,3,129,3,1,161,150,216,171,142,3,130,3,1,193,150,216,171,142,3,255,2,150,216,171,142,3,131,3,1,161,150,216,171,142,3,132,3,1,161,150,216,171,142,3,133,3,1,161,150,216,171,142,3,134,3,1,193,150,216,171,142,3,135,3,150,216,171,142,3,131,3,1,161,150,216,171,142,3,136,3,1,161,150,216,171,142,3,137,3,1,161,150,216,171,142,3,138,3,1,193,150,216,171,142,3,139,3,150,216,171,142,3,131,3,1,161,150,216,171,142,3,140,3,1,161,150,216,171,142,3,141,3,1,161,150,216,171,142,3,142,3,1,161,150,216,171,142,3,144,3,1,161,150,216,171,142,3,145,3,1,161,150,216,171,142,3,146,3,1,193,204,195,206,156,1,130,5,204,195,206,156,1,131,5,1,161,150,216,171,142,3,147,3,1,161,150,216,171,142,3,148,3,1,161,150,216,171,142,3,149,3,1,129,150,216,171,142,3,202,2,1,161,150,216,171,142,3,151,3,1,161,150,216,171,142,3,152,3,1,161,150,216,171,142,3,153,3,1,129,150,216,171,142,3,154,3,1,161,150,216,171,142,3,155,3,1,161,150,216,171,142,3,156,3,1,161,150,216,171,142,3,157,3,1,161,150,216,171,142,3,159,3,1,161,150,216,171,142,3,160,3,1,161,150,216,171,142,3,161,3,1,161,150,216,171,142,3,162,3,1,161,150,216,171,142,3,163,3,1,161,150,216,171,142,3,164,3,1,161,150,216,171,142,3,165,3,1,161,150,216,171,142,3,166,3,1,161,150,216,171,142,3,167,3,1,132,150,216,171,142,3,158,3,1,102,161,150,216,171,142,3,168,3,1,161,150,216,171,142,3,169,3,1,161,150,216,171,142,3,170,3,1,132,150,216,171,142,3,171,3,1,117,161,150,216,171,142,3,172,3,1,161,150,216,171,142,3,173,3,1,161,150,216,171,142,3,174,3,1,132,150,216,171,142,3,175,3,1,110,161,150,216,171,142,3,176,3,1,161,150,216,171,142,3,177,3,1,161,150,216,171,142,3,178,3,1,132,150,216,171,142,3,179,3,1,99,161,150,216,171,142,3,180,3,1,161,150,216,171,142,3,181,3,1,161,150,216,171,142,3,182,3,1,132,150,216,171,142,3,183,3,1,116,161,150,216,171,142,3,184,3,1,161,150,216,171,142,3,185,3,1,161,150,216,171,142,3,186,3,1,132,150,216,171,142,3,187,3,1,105,161,150,216,171,142,3,188,3,1,161,150,216,171,142,3,189,3,1,161,150,216,171,142,3,190,3,1,132,150,216,171,142,3,191,3,1,111,161,150,216,171,142,3,192,3,1,161,150,216,171,142,3,193,3,1,161,150,216,171,142,3,194,3,1,132,150,216,171,142,3,195,3,1,110,161,150,216,171,142,3,196,3,1,161,150,216,171,142,3,197,3,1,161,150,216,171,142,3,198,3,1,132,150,216,171,142,3,199,3,1,32,161,150,216,171,142,3,200,3,1,161,150,216,171,142,3,201,3,1,161,150,216,171,142,3,202,3,1,132,150,216,171,142,3,203,3,1,109,161,150,216,171,142,3,204,3,1,161,150,216,171,142,3,205,3,1,161,150,216,171,142,3,206,3,1,132,150,216,171,142,3,207,3,1,97,161,150,216,171,142,3,208,3,1,161,150,216,171,142,3,209,3,1,161,150,216,171,142,3,210,3,1,132,150,216,171,142,3,211,3,1,105,161,150,216,171,142,3,212,3,1,161,150,216,171,142,3,213,3,1,161,150,216,171,142,3,214,3,1,132,150,216,171,142,3,215,3,1,110,161,150,216,171,142,3,216,3,1,161,150,216,171,142,3,217,3,1,161,150,216,171,142,3,218,3,1,132,150,216,171,142,3,219,3,1,40,161,150,216,171,142,3,220,3,1,161,150,216,171,142,3,221,3,1,161,150,216,171,142,3,222,3,1,132,150,216,171,142,3,223,3,1,41,161,150,216,171,142,3,224,3,1,161,150,216,171,142,3,225,3,1,161,150,216,171,142,3,226,3,1,132,150,216,171,142,3,227,3,1,32,161,150,216,171,142,3,228,3,1,161,150,216,171,142,3,229,3,1,161,150,216,171,142,3,230,3,1,132,150,216,171,142,3,231,3,1,123,161,150,216,171,142,3,232,3,1,161,150,216,171,142,3,233,3,1,161,150,216,171,142,3,234,3,1,132,150,216,171,142,3,235,3,1,125,161,150,216,171,142,3,236,3,1,161,150,216,171,142,3,237,3,1,161,150,216,171,142,3,238,3,1,196,150,216,171,142,3,235,3,150,216,171,142,3,239,3,1,10,161,150,216,171,142,3,240,3,1,161,150,216,171,142,3,241,3,1,161,150,216,171,142,3,242,3,1,196,150,216,171,142,3,243,3,150,216,171,142,3,239,3,1,10,161,150,216,171,142,3,244,3,1,161,150,216,171,142,3,245,3,1,161,150,216,171,142,3,246,3,1,196,150,216,171,142,3,243,3,150,216,171,142,3,247,3,2,32,32,161,150,216,171,142,3,248,3,1,161,150,216,171,142,3,249,3,1,161,150,216,171,142,3,250,3,1,196,150,216,171,142,3,252,3,150,216,171,142,3,247,3,1,99,161,150,216,171,142,3,253,3,1,161,150,216,171,142,3,254,3,1,161,150,216,171,142,3,255,3,1,196,150,216,171,142,3,128,4,150,216,171,142,3,247,3,1,111,161,150,216,171,142,3,129,4,1,161,150,216,171,142,3,130,4,1,161,150,216,171,142,3,131,4,1,196,150,216,171,142,3,132,4,150,216,171,142,3,247,3,1,110,161,150,216,171,142,3,133,4,1,161,150,216,171,142,3,134,4,1,161,150,216,171,142,3,135,4,1,196,150,216,171,142,3,136,4,150,216,171,142,3,247,3,1,115,161,150,216,171,142,3,137,4,1,161,150,216,171,142,3,138,4,1,161,150,216,171,142,3,139,4,1,196,150,216,171,142,3,140,4,150,216,171,142,3,247,3,1,111,161,150,216,171,142,3,141,4,1,161,150,216,171,142,3,142,4,1,161,150,216,171,142,3,143,4,1,196,150,216,171,142,3,144,4,150,216,171,142,3,247,3,1,108,161,150,216,171,142,3,145,4,1,161,150,216,171,142,3,146,4,1,161,150,216,171,142,3,147,4,1,196,150,216,171,142,3,148,4,150,216,171,142,3,247,3,1,101,161,150,216,171,142,3,149,4,1,161,150,216,171,142,3,150,4,1,161,150,216,171,142,3,151,4,1,196,150,216,171,142,3,152,4,150,216,171,142,3,247,3,1,46,161,150,216,171,142,3,153,4,1,161,150,216,171,142,3,154,4,1,161,150,216,171,142,3,155,4,1,196,150,216,171,142,3,156,4,150,216,171,142,3,247,3,1,108,161,150,216,171,142,3,157,4,1,161,150,216,171,142,3,158,4,1,161,150,216,171,142,3,159,4,1,196,150,216,171,142,3,160,4,150,216,171,142,3,247,3,1,111,161,150,216,171,142,3,161,4,1,161,150,216,171,142,3,162,4,1,161,150,216,171,142,3,163,4,1,196,150,216,171,142,3,164,4,150,216,171,142,3,247,3,1,103,161,150,216,171,142,3,165,4,1,161,150,216,171,142,3,166,4,1,161,150,216,171,142,3,167,4,1,196,150,216,171,142,3,168,4,150,216,171,142,3,247,3,1,40,161,150,216,171,142,3,169,4,1,161,150,216,171,142,3,170,4,1,161,150,216,171,142,3,171,4,1,196,150,216,171,142,3,172,4,150,216,171,142,3,247,3,1,41,161,150,216,171,142,3,173,4,1,161,150,216,171,142,3,174,4,1,161,150,216,171,142,3,175,4,1,196,150,216,171,142,3,172,4,150,216,171,142,3,176,4,1,34,161,150,216,171,142,3,177,4,1,161,150,216,171,142,3,178,4,1,161,150,216,171,142,3,179,4,1,196,150,216,171,142,3,180,4,150,216,171,142,3,176,4,1,34,161,150,216,171,142,3,181,4,1,161,150,216,171,142,3,182,4,1,161,150,216,171,142,3,183,4,1,196,150,216,171,142,3,180,4,150,216,171,142,3,184,4,1,72,161,150,216,171,142,3,185,4,1,161,150,216,171,142,3,186,4,1,161,150,216,171,142,3,187,4,1,196,150,216,171,142,3,188,4,150,216,171,142,3,184,4,1,101,161,150,216,171,142,3,189,4,1,161,150,216,171,142,3,190,4,1,161,150,216,171,142,3,191,4,1,196,150,216,171,142,3,192,4,150,216,171,142,3,184,4,1,108,161,150,216,171,142,3,193,4,1,161,150,216,171,142,3,194,4,1,161,150,216,171,142,3,195,4,1,196,150,216,171,142,3,196,4,150,216,171,142,3,184,4,1,108,161,150,216,171,142,3,197,4,1,161,150,216,171,142,3,198,4,1,161,150,216,171,142,3,199,4,1,196,150,216,171,142,3,200,4,150,216,171,142,3,184,4,1,111,161,150,216,171,142,3,201,4,1,161,150,216,171,142,3,202,4,1,161,150,216,171,142,3,203,4,1,196,150,216,171,142,3,204,4,150,216,171,142,3,184,4,1,32,161,150,216,171,142,3,205,4,1,161,150,216,171,142,3,206,4,1,161,150,216,171,142,3,207,4,1,196,150,216,171,142,3,208,4,150,216,171,142,3,184,4,1,87,161,150,216,171,142,3,209,4,1,161,150,216,171,142,3,210,4,1,161,150,216,171,142,3,211,4,1,196,150,216,171,142,3,212,4,150,216,171,142,3,184,4,1,111,161,150,216,171,142,3,213,4,1,161,150,216,171,142,3,214,4,1,161,150,216,171,142,3,215,4,1,196,150,216,171,142,3,216,4,150,216,171,142,3,184,4,1,114,161,150,216,171,142,3,217,4,1,161,150,216,171,142,3,218,4,1,161,150,216,171,142,3,219,4,1,196,150,216,171,142,3,220,4,150,216,171,142,3,184,4,1,108,161,150,216,171,142,3,221,4,1,161,150,216,171,142,3,222,4,1,161,150,216,171,142,3,223,4,1,196,150,216,171,142,3,224,4,150,216,171,142,3,184,4,1,100,161,150,216,171,142,3,225,4,1,161,150,216,171,142,3,226,4,1,161,150,216,171,142,3,227,4,1,193,150,216,171,142,3,228,4,150,216,171,142,3,184,4,1,161,150,216,171,142,3,229,4,1,161,150,216,171,142,3,230,4,1,161,150,216,171,142,3,231,4,1,168,150,216,171,142,3,233,4,1,119,132,1,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,47,47,32,84,104,105,115,32,105,115,32,116,104,101,32,109,97,105,110,32,102,117,110,99,116,105,111,110,46,92,110,102,117,110,99,116,105,111,110,32,109,97,105,110,40,41,32,123,92,110,32,32,99,111,110,115,111,108,101,46,108,111,103,40,92,34,72,101,108,108,111,32,87,111,114,108,100,92,34,41,92,110,125,34,125,93,44,34,108,97,110,103,117,97,103,101,34,58,34,74,97,118,97,115,99,114,105,112,116,34,125,168,150,216,171,142,3,234,4,1,119,10,49,112,115,100,67,122,97,87,104,49,168,150,216,171,142,3,235,4,1,119,4,116,101,120,116,39,0,204,195,206,156,1,4,6,48,100,51,52,82,50,2,39,0,204,195,206,156,1,4,6,45,71,115,81,49,95,2,4,0,150,216,171,142,3,240,4,4,49,50,51,32,134,150,216,171,142,3,244,4,7,109,101,110,116,105,111,110,51,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,132,150,216,171,142,3,245,4,1,36,134,150,216,171,142,3,246,4,7,109,101,110,116,105,111,110,4,110,117,108,108,132,150,216,171,142,3,247,4,6,32,32,101,114,32,32,33,0,204,195,206,156,1,1,6,49,71,114,87,76,99,1,0,7,33,0,204,195,206,156,1,3,6,72,105,104,101,52,114,1,193,164,202,219,213,10,28,199,130,209,189,2,60,1,168,164,202,219,213,10,117,1,119,151,1,123,34,108,101,118,101,108,34,58,50,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,109,101,110,116,105,111,110,34,58,123,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,57,84,49,54,58,49,51,58,52,57,46,52,49,49,49,54,53,34,44,34,116,121,112,101,34,58,34,100,97,116,101,34,125,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,44,123,34,105,110,115,101,114,116,34,58,34,32,32,101,114,32,32,34,125,93,125,4,0,150,216,171,142,3,239,4,1,35,0,1,132,150,216,171,142,3,137,5,1,35,0,1,132,150,216,171,142,3,139,5,1,35,0,1,39,0,204,195,206,156,1,4,6,115,99,68,45,119,114,2,39,0,204,195,206,156,1,1,6,67,72,115,77,79,98,1,40,0,150,216,171,142,3,144,5,2,105,100,1,119,6,67,72,115,77,79,98,40,0,150,216,171,142,3,144,5,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,150,216,171,142,3,144,5,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,150,216,171,142,3,144,5,8,99,104,105,108,100,114,101,110,1,119,6,97,107,121,80,104,45,33,0,150,216,171,142,3,144,5,4,100,97,116,97,1,40,0,150,216,171,142,3,144,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,144,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,97,107,121,80,104,45,0,200,164,202,219,213,10,28,150,216,171,142,3,135,5,1,119,6,67,72,115,77,79,98,4,0,150,216,171,142,3,143,5,1,49,161,150,216,171,142,3,149,5,1,132,150,216,171,142,3,154,5,1,50,161,150,216,171,142,3,155,5,1,132,150,216,171,142,3,156,5,1,51,161,150,216,171,142,3,157,5,1,168,150,216,171,142,3,5,1,119,11,123,34,100,101,112,116,104,34,58,54,125,39,0,204,195,206,156,1,4,6,112,79,69,118,75,110,2,39,0,204,195,206,156,1,4,6,80,49,49,121,116,108,2,4,0,150,216,171,142,3,162,5,3,49,50,51,33,0,204,195,206,156,1,1,6,97,79,72,54,79,66,1,0,7,33,0,204,195,206,156,1,3,6,105,89,77,80,45,116,1,193,150,216,171,142,3,135,5,199,130,209,189,2,60,1,161,150,216,171,142,3,159,5,1,168,150,216,171,142,3,176,5,1,119,38,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,44,34,108,101,118,101,108,34,58,51,125,161,199,130,209,189,2,212,3,1,161,199,130,209,189,2,232,3,1,161,199,130,209,189,2,159,4,1,161,150,216,171,142,3,179,5,1,161,199,130,209,189,2,144,4,1,161,150,216,171,142,3,181,5,1,161,150,216,171,142,3,182,5,1,161,150,216,171,142,3,180,5,2,161,150,216,171,142,3,183,5,1,161,150,216,171,142,3,184,5,1,161,150,216,171,142,3,186,5,1,161,199,130,209,189,2,252,3,1,161,150,216,171,142,3,188,5,1,161,150,216,171,142,3,189,5,1,39,0,204,195,206,156,1,4,6,70,76,85,90,75,54,2,39,0,204,195,206,156,1,4,6,69,53,84,66,120,118,2,39,0,204,195,206,156,1,1,6,103,79,106,51,90,68,1,40,0,150,216,171,142,3,195,5,2,105,100,1,119,6,103,79,106,51,90,68,40,0,150,216,171,142,3,195,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,195,5,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,195,5,8,99,104,105,108,100,114,101,110,1,119,6,116,51,112,87,101,56,33,0,150,216,171,142,3,195,5,4,100,97,116,97,1,40,0,150,216,171,142,3,195,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,195,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,116,51,112,87,101,56,0,136,199,130,209,189,2,148,4,1,119,6,103,79,106,51,90,68,39,0,204,195,206,156,1,1,6,88,56,80,113,67,120,1,40,0,150,216,171,142,3,205,5,2,105,100,1,119,6,88,56,80,113,67,120,40,0,150,216,171,142,3,205,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,205,5,6,112,97,114,101,110,116,1,119,6,103,79,106,51,90,68,40,0,150,216,171,142,3,205,5,8,99,104,105,108,100,114,101,110,1,119,6,76,55,82,84,78,106,33,0,150,216,171,142,3,205,5,4,100,97,116,97,1,40,0,150,216,171,142,3,205,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,205,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,76,55,82,84,78,106,0,8,0,150,216,171,142,3,203,5,1,119,6,88,56,80,113,67,120,39,0,204,195,206,156,1,1,6,74,48,69,48,67,66,1,40,0,150,216,171,142,3,215,5,2,105,100,1,119,6,74,48,69,48,67,66,40,0,150,216,171,142,3,215,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,215,5,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,215,5,8,99,104,105,108,100,114,101,110,1,119,6,73,120,120,49,82,88,33,0,150,216,171,142,3,215,5,4,100,97,116,97,1,40,0,150,216,171,142,3,215,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,215,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,73,120,120,49,82,88,0,136,150,216,171,142,3,204,5,1,119,6,74,48,69,48,67,66,39,0,204,195,206,156,1,1,6,75,78,45,115,87,88,1,40,0,150,216,171,142,3,225,5,2,105,100,1,119,6,75,78,45,115,87,88,40,0,150,216,171,142,3,225,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,225,5,6,112,97,114,101,110,116,1,119,6,74,48,69,48,67,66,40,0,150,216,171,142,3,225,5,8,99,104,105,108,100,114,101,110,1,119,6,75,115,100,83,116,74,33,0,150,216,171,142,3,225,5,4,100,97,116,97,1,40,0,150,216,171,142,3,225,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,225,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,75,115,100,83,116,74,0,8,0,150,216,171,142,3,223,5,1,119,6,75,78,45,115,87,88,161,150,216,171,142,3,192,5,1,4,0,150,216,171,142,3,193,5,1,55,161,150,216,171,142,3,210,5,1,132,150,216,171,142,3,236,5,1,55,161,150,216,171,142,3,237,5,1,132,150,216,171,142,3,238,5,1,55,161,150,216,171,142,3,239,5,1,39,0,204,195,206,156,1,4,6,71,52,107,110,49,95,2,39,0,204,195,206,156,1,4,6,98,52,97,80,80,53,2,39,0,204,195,206,156,1,4,6,80,111,114,82,81,79,2,161,150,216,171,142,3,235,5,1,39,0,204,195,206,156,1,1,6,80,53,88,89,98,115,1,40,0,150,216,171,142,3,246,5,2,105,100,1,119,6,80,53,88,89,98,115,40,0,150,216,171,142,3,246,5,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,246,5,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,246,5,8,99,104,105,108,100,114,101,110,1,119,6,89,55,81,88,109,84,33,0,150,216,171,142,3,246,5,4,100,97,116,97,1,40,0,150,216,171,142,3,246,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,246,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,89,55,81,88,109,84,0,200,199,130,209,189,2,236,3,199,130,209,189,2,128,4,1,119,6,80,53,88,89,98,115,39,0,204,195,206,156,1,1,6,57,49,85,122,51,51,1,40,0,150,216,171,142,3,128,6,2,105,100,1,119,6,57,49,85,122,51,51,40,0,150,216,171,142,3,128,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,128,6,6,112,97,114,101,110,116,1,119,6,80,53,88,89,98,115,40,0,150,216,171,142,3,128,6,8,99,104,105,108,100,114,101,110,1,119,6,88,73,86,101,114,105,33,0,150,216,171,142,3,128,6,4,100,97,116,97,1,40,0,150,216,171,142,3,128,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,128,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,88,73,86,101,114,105,0,8,0,150,216,171,142,3,254,5,1,119,6,57,49,85,122,51,51,161,150,216,171,142,3,245,5,1,39,0,204,195,206,156,1,1,6,97,105,73,55,114,78,1,40,0,150,216,171,142,3,139,6,2,105,100,1,119,6,97,105,73,55,114,78,40,0,150,216,171,142,3,139,6,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,139,6,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,139,6,8,99,104,105,108,100,114,101,110,1,119,6,70,83,77,57,101,119,33,0,150,216,171,142,3,139,6,4,100,97,116,97,1,40,0,150,216,171,142,3,139,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,139,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,70,83,77,57,101,119,0,200,199,130,209,189,2,148,4,150,216,171,142,3,204,5,1,119,6,97,105,73,55,114,78,39,0,204,195,206,156,1,1,6,48,117,114,80,56,120,1,40,0,150,216,171,142,3,149,6,2,105,100,1,119,6,48,117,114,80,56,120,40,0,150,216,171,142,3,149,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,149,6,6,112,97,114,101,110,116,1,119,6,97,105,73,55,114,78,40,0,150,216,171,142,3,149,6,8,99,104,105,108,100,114,101,110,1,119,6,98,90,114,57,106,101,33,0,150,216,171,142,3,149,6,4,100,97,116,97,1,40,0,150,216,171,142,3,149,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,149,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,98,90,114,57,106,101,0,8,0,150,216,171,142,3,147,6,1,119,6,48,117,114,80,56,120,39,0,204,195,206,156,1,1,6,100,114,110,97,115,68,1,40,0,150,216,171,142,3,159,6,2,105,100,1,119,6,100,114,110,97,115,68,40,0,150,216,171,142,3,159,6,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,150,216,171,142,3,159,6,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,150,216,171,142,3,159,6,8,99,104,105,108,100,114,101,110,1,119,6,76,114,45,49,81,54,33,0,150,216,171,142,3,159,6,4,100,97,116,97,1,40,0,150,216,171,142,3,159,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,159,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,76,114,45,49,81,54,0,136,150,216,171,142,3,224,5,1,119,6,100,114,110,97,115,68,39,0,204,195,206,156,1,1,6,72,69,79,54,86,72,1,40,0,150,216,171,142,3,169,6,2,105,100,1,119,6,72,69,79,54,86,72,40,0,150,216,171,142,3,169,6,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,150,216,171,142,3,169,6,6,112,97,114,101,110,116,1,119,6,100,114,110,97,115,68,40,0,150,216,171,142,3,169,6,8,99,104,105,108,100,114,101,110,1,119,6,71,118,57,87,108,76,33,0,150,216,171,142,3,169,6,4,100,97,116,97,1,40,0,150,216,171,142,3,169,6,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,150,216,171,142,3,169,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,71,118,57,87,108,76,0,8,0,150,216,171,142,3,167,6,1,119,6,72,69,79,54,86,72,4,0,150,216,171,142,3,242,5,1,49,161,150,216,171,142,3,133,6,1,132,150,216,171,142,3,179,6,1,48,161,150,216,171,142,3,180,6,1,132,150,216,171,142,3,181,6,1,49,161,150,216,171,142,3,182,6,1,132,150,216,171,142,3,183,6,1,48,161,150,216,171,142,3,184,6,1,161,150,216,171,142,3,187,5,1,161,150,216,171,142,3,191,5,1,161,150,216,171,142,3,220,5,1,161,150,216,171,142,3,138,6,1,39,0,204,195,206,156,1,4,6,54,73,68,55,103,118,2,4,0,150,216,171,142,3,191,6,1,49,168,199,130,209,189,2,169,4,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,34,125,93,125,39,0,204,195,206,156,1,4,6,77,84,68,68,110,107,2,4,0,150,216,171,142,3,194,6,1,50,168,199,130,209,189,2,242,3,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,50,34,125,93,125,39,0,204,195,206,156,1,4,6,88,108,87,102,45,70,2,4,0,150,216,171,142,3,197,6,1,51,168,150,216,171,142,3,186,6,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,51,34,125,93,125,39,0,204,195,206,156,1,4,6,57,98,65,107,106,109,2,4,0,150,216,171,142,3,200,6,1,52,168,199,130,209,189,2,134,4,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,52,34,125,93,125,39,0,204,195,206,156,1,4,6,99,112,85,122,107,121,2,4,0,150,216,171,142,3,203,6,1,53,168,199,130,209,189,2,177,4,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,53,34,125,93,125,39,0,204,195,206,156,1,4,6,81,102,72,107,77,77,2,4,0,150,216,171,142,3,206,6,1,54,168,150,216,171,142,3,154,6,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,54,34,125,93,125,39,0,204,195,206,156,1,4,6,119,113,82,74,112,76,2,4,0,150,216,171,142,3,209,6,1,55,168,150,216,171,142,3,241,5,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,55,34,125,93,125,39,0,204,195,206,156,1,4,6,69,70,82,71,121,80,2,4,0,150,216,171,142,3,212,6,1,56,168,150,216,171,142,3,230,5,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,56,34,125,93,125,39,0,204,195,206,156,1,4,6,104,109,90,99,72,101,2,1,0,150,216,171,142,3,215,6,1,161,150,216,171,142,3,174,6,2,132,150,216,171,142,3,216,6,1,57,168,150,216,171,142,3,218,6,1,119,26,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,57,34,125,93,125,39,0,204,195,206,156,1,4,6,56,117,111,87,49,119,2,4,0,150,216,171,142,3,221,6,4,119,105,116,104,168,199,130,209,189,2,146,3,1,119,61,123,34,97,108,105,103,110,34,58,34,114,105,103,104,116,34,44,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,119,105,116,104,34,125,93,125,39,0,204,195,206,156,1,4,6,109,55,80,110,81,54,2,4,0,150,216,171,142,3,227,6,3,108,111,110,129,150,216,171,142,3,230,6,14,132,150,216,171,142,3,244,6,44,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,134,150,216,171,142,3,160,7,11,102,111,110,116,95,102,97,109,105,108,121,22,34,65,68,76,97,77,68,105,115,112,108,97,121,95,114,101,103,117,108,97,114,34,132,150,216,171,142,3,161,7,9,116,101,120,116,110,103,32,116,101,134,150,216,171,142,3,170,7,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,132,150,216,171,142,3,171,7,16,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,129,150,216,171,142,3,187,7,6,132,150,216,171,142,3,193,7,92,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,161,199,130,209,189,2,213,2,1,196,150,216,171,142,3,187,7,150,216,171,142,3,188,7,1,76,161,150,216,171,142,3,158,8,1,196,150,216,171,142,3,193,7,150,216,171,142,3,194,7,1,101,161,150,216,171,142,3,160,8,1,70,204,195,206,156,1,135,7,11,102,111,110,116,95,102,97,109,105,108,121,22,34,65,98,114,105,108,70,97,116,102,97,99,101,95,114,101,103,117,108,97,114,34,193,150,216,171,142,3,163,8,204,195,206,156,1,135,7,3,198,150,216,171,142,3,166,8,204,195,206,156,1,135,7,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,161,199,130,209,189,2,25,1,161,199,130,209,189,2,26,1,161,199,130,209,189,2,27,1,198,150,216,171,142,3,230,6,150,216,171,142,3,231,6,11,102,111,110,116,95,102,97,109,105,108,121,22,34,65,68,76,97,77,68,105,115,112,108,97,121,95,114,101,103,117,108,97,114,34,196,150,216,171,142,3,171,8,150,216,171,142,3,231,6,14,103,32,116,101,120,116,110,103,32,116,101,120,116,110,198,150,216,171,142,3,185,8,150,216,171,142,3,231,6,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,161,150,216,171,142,3,162,8,1,16,146,175,139,236,2,0,161,227,211,144,195,8,0,1,161,227,211,144,195,8,1,1,161,227,211,144,195,8,2,1,161,227,211,144,195,8,3,1,161,227,211,144,195,8,4,1,161,227,211,144,195,8,5,1,161,227,211,144,195,8,11,1,161,227,211,144,195,8,7,1,161,227,211,144,195,8,8,1,161,227,211,144,195,8,9,1,161,146,175,139,236,2,6,2,39,0,204,195,206,156,1,4,6,66,66,65,103,65,56,2,6,0,146,175,139,236,2,12,11,102,111,110,116,95,102,97,109,105,108,121,15,34,65,68,76,97,77,32,68,105,115,112,108,97,121,34,132,146,175,139,236,2,13,183,1,108,111,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,76,101,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,107,107,109,134,146,175,139,236,2,196,1,11,102,111,110,116,95,102,97,109,105,108,121,4,110,117,108,108,168,192,187,174,206,8,222,5,1,119,141,2,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,102,97,109,105,108,121,34,58,34,65,68,76,97,77,32,68,105,115,112,108,97,121,34,125,44,34,105,110,115,101,114,116,34,58,34,108,111,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,76,101,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,110,103,32,116,101,120,116,107,107,109,34,125,93,125,20,168,215,223,235,2,0,161,150,216,171,142,3,168,8,1,161,150,216,171,142,3,169,8,1,161,150,216,171,142,3,170,8,1,196,150,216,171,142,3,166,8,150,216,171,142,3,167,8,3,87,101,108,132,224,159,166,178,15,26,16,99,111,109,101,32,116,111,32,65,112,112,70,108,111,119,121,39,0,204,195,206,156,1,4,6,74,98,104,77,53,50,2,4,0,168,215,223,235,2,22,20,72,101,114,101,32,97,114,101,32,116,104,101,32,98,97,115,105,99,115,32,168,168,215,223,235,2,0,1,119,120,123,34,100,101,108,116,97,34,58,91,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,110,116,95,102,97,109,105,108,121,34,58,34,65,98,114,105,108,70,97,116,102,97,99,101,95,114,101,103,117,108,97,114,34,125,44,34,105,110,115,101,114,116,34,58,34,87,101,108,34,125,44,123,34,105,110,115,101,114,116,34,58,34,99,111,109,101,32,116,111,32,65,112,112,70,108,111,119,121,34,125,93,44,34,108,101,118,101,108,34,58,49,125,168,168,215,223,235,2,1,1,119,10,119,88,107,79,72,81,49,50,99,111,168,168,215,223,235,2,2,1,119,4,116,101,120,116,167,204,195,206,156,1,213,1,1,40,0,168,215,223,235,2,46,2,105,100,1,119,10,97,115,74,118,54,70,114,65,82,97,40,0,168,215,223,235,2,46,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,168,215,223,235,2,46,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,168,215,223,235,2,46,8,99,104,105,108,100,114,101,110,1,119,6,51,107,67,87,106,70,40,0,168,215,223,235,2,46,4,100,97,116,97,1,119,55,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,72,101,114,101,32,97,114,101,32,116,104,101,32,98,97,115,105,99,115,32,34,125,93,44,34,108,101,118,101,108,34,58,50,125,40,0,168,215,223,235,2,46,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,168,215,223,235,2,46,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,51,107,67,87,106,70,0,200,204,195,206,156,1,232,1,199,130,209,189,2,181,3,1,119,10,97,115,74,118,54,70,114,65,82,97,1,192,246,139,213,2,0,161,239,239,208,251,10,16,35,1,190,183,139,210,2,0,161,241,147,239,232,6,3,110,2,237,140,187,206,2,0,161,190,183,139,210,2,109,17,161,237,140,187,206,2,16,4,137,6,199,130,209,189,2,0,39,0,204,195,206,156,1,4,6,88,116,53,112,118,55,2,4,0,199,130,209,189,2,0,9,229,144,140,228,184,128,228,184,170,129,199,130,209,189,2,3,5,161,178,187,245,161,14,10,6,132,199,130,209,189,2,8,1,110,161,199,130,209,189,2,14,1,132,199,130,209,189,2,15,1,105,168,199,130,209,189,2,16,1,119,36,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,229,144,140,228,184,128,228,184,170,110,105,34,125,93,125,161,224,159,166,178,15,27,1,161,224,159,166,178,15,28,1,161,224,159,166,178,15,29,1,161,199,130,209,189,2,19,1,161,199,130,209,189,2,20,1,161,199,130,209,189,2,21,1,161,199,130,209,189,2,22,1,161,199,130,209,189,2,23,1,161,199,130,209,189,2,24,1,0,3,39,0,204,195,206,156,1,4,6,82,74,97,73,54,107,2,4,0,199,130,209,189,2,31,1,116,161,228,242,134,215,15,11,1,132,199,130,209,189,2,32,1,111,161,199,130,209,189,2,33,1,132,199,130,209,189,2,34,1,100,161,199,130,209,189,2,35,1,132,199,130,209,189,2,36,1,111,161,199,130,209,189,2,37,1,132,199,130,209,189,2,38,1,32,161,199,130,209,189,2,39,1,132,199,130,209,189,2,40,1,108,161,199,130,209,189,2,41,1,132,199,130,209,189,2,42,1,105,161,199,130,209,189,2,43,1,132,199,130,209,189,2,44,1,115,161,199,130,209,189,2,45,1,132,199,130,209,189,2,46,1,116,161,199,130,209,189,2,47,1,39,0,204,195,206,156,1,4,6,55,80,118,106,121,81,2,39,0,204,195,206,156,1,1,6,71,118,88,50,102,110,1,40,0,199,130,209,189,2,51,2,105,100,1,119,6,71,118,88,50,102,110,40,0,199,130,209,189,2,51,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,199,130,209,189,2,51,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,51,8,99,104,105,108,100,114,101,110,1,119,6,111,112,68,102,54,95,33,0,199,130,209,189,2,51,4,100,97,116,97,1,40,0,199,130,209,189,2,51,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,51,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,111,112,68,102,54,95,0,200,198,223,206,159,1,135,1,198,223,206,159,1,116,1,119,6,71,118,88,50,102,110,161,199,130,209,189,2,49,1,4,0,199,130,209,189,2,50,1,99,161,199,130,209,189,2,56,1,132,199,130,209,189,2,62,1,104,161,199,130,209,189,2,63,1,132,199,130,209,189,2,64,1,101,161,199,130,209,189,2,65,1,132,199,130,209,189,2,66,1,99,161,199,130,209,189,2,67,1,132,199,130,209,189,2,68,1,107,161,199,130,209,189,2,69,1,132,199,130,209,189,2,70,1,101,161,199,130,209,189,2,71,1,132,199,130,209,189,2,72,1,100,161,199,130,209,189,2,73,1,132,199,130,209,189,2,74,1,32,161,199,130,209,189,2,75,1,132,199,130,209,189,2,76,1,116,161,199,130,209,189,2,77,1,132,199,130,209,189,2,78,1,111,161,199,130,209,189,2,79,1,132,199,130,209,189,2,80,1,100,161,199,130,209,189,2,81,1,132,199,130,209,189,2,82,1,111,161,199,130,209,189,2,83,1,132,199,130,209,189,2,84,1,32,161,199,130,209,189,2,85,1,132,199,130,209,189,2,86,1,108,161,199,130,209,189,2,87,1,132,199,130,209,189,2,88,1,105,161,199,130,209,189,2,89,1,132,199,130,209,189,2,90,1,115,161,199,130,209,189,2,91,1,132,199,130,209,189,2,92,1,116,161,199,130,209,189,2,93,1,39,0,204,195,206,156,1,4,6,117,115,117,45,118,111,2,39,0,204,195,206,156,1,1,6,86,90,80,95,77,113,1,40,0,199,130,209,189,2,97,2,105,100,1,119,6,86,90,80,95,77,113,40,0,199,130,209,189,2,97,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,199,130,209,189,2,97,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,97,8,99,104,105,108,100,114,101,110,1,119,6,54,55,76,56,102,50,33,0,199,130,209,189,2,97,4,100,97,116,97,1,40,0,199,130,209,189,2,97,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,97,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,54,55,76,56,102,50,0,200,199,130,209,189,2,60,198,223,206,159,1,116,1,119,6,86,90,80,95,77,113,161,199,130,209,189,2,95,1,4,0,199,130,209,189,2,96,1,108,161,199,130,209,189,2,102,1,132,199,130,209,189,2,108,1,111,161,199,130,209,189,2,109,1,132,199,130,209,189,2,110,1,110,161,199,130,209,189,2,111,1,132,199,130,209,189,2,112,1,103,161,199,130,209,189,2,113,1,132,199,130,209,189,2,114,1,32,161,199,130,209,189,2,115,1,132,199,130,209,189,2,116,1,116,161,199,130,209,189,2,117,1,132,199,130,209,189,2,118,1,101,161,199,130,209,189,2,119,1,132,199,130,209,189,2,120,1,120,161,199,130,209,189,2,121,1,132,199,130,209,189,2,122,1,116,161,199,130,209,189,2,123,1,129,199,130,209,189,2,124,1,161,199,130,209,189,2,125,2,132,199,130,209,189,2,126,7,110,103,32,116,101,120,116,161,199,130,209,189,2,128,1,1,132,199,130,209,189,2,135,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,136,1,1,132,199,130,209,189,2,143,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,144,1,1,132,199,130,209,189,2,151,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,152,1,1,132,199,130,209,189,2,159,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,160,1,1,132,199,130,209,189,2,167,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,168,1,1,132,199,130,209,189,2,175,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,176,1,1,132,199,130,209,189,2,183,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,184,1,1,132,199,130,209,189,2,191,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,192,1,1,132,199,130,209,189,2,199,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,200,1,1,132,199,130,209,189,2,207,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,208,1,1,132,199,130,209,189,2,215,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,216,1,1,132,199,130,209,189,2,223,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,224,1,1,132,199,130,209,189,2,231,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,232,1,1,132,199,130,209,189,2,239,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,240,1,1,132,199,130,209,189,2,247,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,248,1,1,132,199,130,209,189,2,255,1,7,110,103,32,116,101,120,116,161,199,130,209,189,2,128,2,1,132,199,130,209,189,2,135,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,136,2,1,132,199,130,209,189,2,143,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,144,2,1,132,199,130,209,189,2,151,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,152,2,1,132,199,130,209,189,2,159,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,160,2,1,132,199,130,209,189,2,167,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,168,2,1,132,199,130,209,189,2,175,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,176,2,1,132,199,130,209,189,2,183,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,184,2,1,132,199,130,209,189,2,191,2,7,110,103,32,116,101,120,116,161,199,130,209,189,2,192,2,1,161,199,130,209,189,2,107,1,39,0,204,195,206,156,1,4,6,55,74,97,87,111,56,2,39,0,204,195,206,156,1,1,6,54,87,56,99,101,88,1,40,0,199,130,209,189,2,203,2,2,105,100,1,119,6,54,87,56,99,101,88,40,0,199,130,209,189,2,203,2,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,199,130,209,189,2,203,2,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,203,2,8,99,104,105,108,100,114,101,110,1,119,6,105,55,111,99,51,56,33,0,199,130,209,189,2,203,2,4,100,97,116,97,1,40,0,199,130,209,189,2,203,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,203,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,105,55,111,99,51,56,0,200,199,130,209,189,2,106,198,223,206,159,1,116,1,119,6,54,87,56,99,101,88,161,199,130,209,189,2,200,2,1,132,199,130,209,189,2,94,1,32,161,199,130,209,189,2,201,2,1,129,199,130,209,189,2,214,2,1,161,199,130,209,189,2,215,2,1,129,199,130,209,189,2,216,2,1,161,199,130,209,189,2,217,2,1,129,199,130,209,189,2,218,2,1,161,199,130,209,189,2,219,2,1,129,199,130,209,189,2,220,2,1,161,199,130,209,189,2,221,2,5,129,199,130,209,189,2,222,2,1,161,199,130,209,189,2,227,2,1,129,199,130,209,189,2,228,2,1,161,199,130,209,189,2,229,2,1,129,199,130,209,189,2,230,2,1,161,199,130,209,189,2,231,2,1,129,199,130,209,189,2,232,2,1,161,199,130,209,189,2,233,2,1,129,199,130,209,189,2,234,2,1,161,199,130,209,189,2,235,2,1,129,199,130,209,189,2,236,2,1,161,199,130,209,189,2,237,2,1,129,199,130,209,189,2,238,2,1,161,199,130,209,189,2,239,2,1,134,199,130,209,189,2,240,2,7,102,111,114,109,117,108,97,9,34,102,111,114,109,117,108,97,34,132,199,130,209,189,2,242,2,1,36,134,199,130,209,189,2,243,2,7,102,111,114,109,117,108,97,4,110,117,108,108,168,199,130,209,189,2,241,2,1,119,108,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,101,99,107,101,100,32,116,111,100,111,32,108,105,115,116,32,34,125,44,123,34,97,116,116,114,105,98,117,116,101,115,34,58,123,34,102,111,114,109,117,108,97,34,58,34,102,111,114,109,117,108,97,34,125,44,34,105,110,115,101,114,116,34,58,34,36,34,125,93,44,34,99,104,101,99,107,101,100,34,58,116,114,117,101,125,1,0,199,130,209,189,2,202,2,1,161,199,130,209,189,2,208,2,1,129,199,130,209,189,2,246,2,1,161,199,130,209,189,2,247,2,1,129,199,130,209,189,2,248,2,1,161,199,130,209,189,2,249,2,1,129,199,130,209,189,2,250,2,1,161,199,130,209,189,2,251,2,1,129,199,130,209,189,2,252,2,1,161,199,130,209,189,2,253,2,1,129,199,130,209,189,2,254,2,1,161,199,130,209,189,2,255,2,1,129,199,130,209,189,2,128,3,1,161,199,130,209,189,2,129,3,8,132,199,130,209,189,2,130,3,1,119,161,199,130,209,189,2,138,3,1,132,199,130,209,189,2,139,3,1,105,161,199,130,209,189,2,140,3,1,132,199,130,209,189,2,141,3,1,116,161,199,130,209,189,2,142,3,1,132,199,130,209,189,2,143,3,1,104,161,199,130,209,189,2,144,3,1,39,0,204,195,206,156,1,4,6,55,99,74,88,114,112,2,39,0,204,195,206,156,1,1,6,86,111,54,70,109,81,1,40,0,199,130,209,189,2,148,3,2,105,100,1,119,6,86,111,54,70,109,81,40,0,199,130,209,189,2,148,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,148,3,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,199,130,209,189,2,148,3,8,99,104,105,108,100,114,101,110,1,119,6,106,82,78,118,55,111,33,0,199,130,209,189,2,148,3,4,100,97,116,97,1,40,0,199,130,209,189,2,148,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,148,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,106,82,78,118,55,111,0,136,171,236,222,251,5,206,3,1,119,6,86,111,54,70,109,81,4,0,199,130,209,189,2,147,3,4,240,159,152,131,168,199,130,209,189,2,153,3,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,240,159,152,131,34,125,93,125,39,0,204,195,206,156,1,4,6,103,89,121,119,78,121,2,33,0,204,195,206,156,1,1,6,84,67,99,110,98,71,1,0,7,33,0,204,195,206,156,1,3,6,82,117,68,55,67,100,1,193,204,195,206,156,1,232,1,198,223,206,159,1,149,1,1,39,0,204,195,206,156,1,1,6,101,77,66,121,99,80,1,40,0,199,130,209,189,2,172,3,2,105,100,1,119,6,101,77,66,121,99,80,40,0,199,130,209,189,2,172,3,2,116,121,1,119,7,111,117,116,108,105,110,101,40,0,199,130,209,189,2,172,3,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,172,3,8,99,104,105,108,100,114,101,110,1,119,6,112,72,116,98,67,52,33,0,199,130,209,189,2,172,3,4,100,97,116,97,1,40,0,199,130,209,189,2,172,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,172,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,112,72,116,98,67,52,0,200,204,195,206,156,1,232,1,199,130,209,189,2,171,3,1,119,6,101,77,66,121,99,80,39,0,204,195,206,156,1,4,6,95,97,88,90,88,80,2,33,0,204,195,206,156,1,1,6,81,89,119,70,83,48,1,0,7,33,0,204,195,206,156,1,3,6,88,110,80,104,117,89,1,193,199,130,209,189,2,171,3,198,223,206,159,1,149,1,1,39,0,204,195,206,156,1,4,6,110,90,88,77,89,67,2,39,0,204,195,206,156,1,4,6,85,99,120,53,52,69,2,39,0,204,195,206,156,1,4,6,69,82,71,102,107,88,2,39,0,204,195,206,156,1,4,6,71,108,50,57,116,102,2,39,0,204,195,206,156,1,1,6,120,49,100,100,111,87,1,40,0,199,130,209,189,2,197,3,2,105,100,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,197,3,2,116,121,1,119,5,116,97,98,108,101,40,0,199,130,209,189,2,197,3,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,197,3,8,99,104,105,108,100,114,101,110,1,119,6,100,49,110,86,107,119,33,0,199,130,209,189,2,197,3,4,100,97,116,97,1,40,0,199,130,209,189,2,197,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,197,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,100,49,110,86,107,119,0,200,199,130,209,189,2,171,3,199,130,209,189,2,192,3,1,119,6,120,49,100,100,111,87,39,0,204,195,206,156,1,1,6,121,57,72,73,118,95,1,40,0,199,130,209,189,2,207,3,2,105,100,1,119,6,121,57,72,73,118,95,40,0,199,130,209,189,2,207,3,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,207,3,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,207,3,8,99,104,105,108,100,114,101,110,1,119,6,78,104,69,49,119,116,33,0,199,130,209,189,2,207,3,4,100,97,116,97,1,40,0,199,130,209,189,2,207,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,207,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,78,104,69,49,119,116,0,8,0,199,130,209,189,2,205,3,1,119,6,121,57,72,73,118,95,39,0,204,195,206,156,1,1,6,48,83,82,103,66,118,1,40,0,199,130,209,189,2,217,3,2,105,100,1,119,6,48,83,82,103,66,118,40,0,199,130,209,189,2,217,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,217,3,6,112,97,114,101,110,116,1,119,6,121,57,72,73,118,95,40,0,199,130,209,189,2,217,3,8,99,104,105,108,100,114,101,110,1,119,6,107,108,100,67,117,111,33,0,199,130,209,189,2,217,3,4,100,97,116,97,1,40,0,199,130,209,189,2,217,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,217,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,107,108,100,67,117,111,0,8,0,199,130,209,189,2,215,3,1,119,6,48,83,82,103,66,118,39,0,204,195,206,156,1,1,6,95,90,90,78,53,99,1,40,0,199,130,209,189,2,227,3,2,105,100,1,119,6,95,90,90,78,53,99,40,0,199,130,209,189,2,227,3,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,227,3,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,227,3,8,99,104,105,108,100,114,101,110,1,119,6,103,89,69,98,121,107,33,0,199,130,209,189,2,227,3,4,100,97,116,97,1,40,0,199,130,209,189,2,227,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,227,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,103,89,69,98,121,107,0,136,199,130,209,189,2,216,3,1,119,6,95,90,90,78,53,99,39,0,204,195,206,156,1,1,6,77,106,74,57,74,76,1,40,0,199,130,209,189,2,237,3,2,105,100,1,119,6,77,106,74,57,74,76,40,0,199,130,209,189,2,237,3,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,237,3,6,112,97,114,101,110,116,1,119,6,95,90,90,78,53,99,40,0,199,130,209,189,2,237,3,8,99,104,105,108,100,114,101,110,1,119,6,95,102,81,84,95,110,33,0,199,130,209,189,2,237,3,4,100,97,116,97,1,40,0,199,130,209,189,2,237,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,237,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,95,102,81,84,95,110,0,8,0,199,130,209,189,2,235,3,1,119,6,77,106,74,57,74,76,39,0,204,195,206,156,1,1,6,78,77,45,104,67,70,1,40,0,199,130,209,189,2,247,3,2,105,100,1,119,6,78,77,45,104,67,70,40,0,199,130,209,189,2,247,3,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,247,3,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,247,3,8,99,104,105,108,100,114,101,110,1,119,6,117,118,68,83,80,101,33,0,199,130,209,189,2,247,3,4,100,97,116,97,1,40,0,199,130,209,189,2,247,3,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,247,3,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,117,118,68,83,80,101,0,136,199,130,209,189,2,236,3,1,119,6,78,77,45,104,67,70,39,0,204,195,206,156,1,1,6,69,70,66,45,52,82,1,40,0,199,130,209,189,2,129,4,2,105,100,1,119,6,69,70,66,45,52,82,40,0,199,130,209,189,2,129,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,129,4,6,112,97,114,101,110,116,1,119,6,78,77,45,104,67,70,40,0,199,130,209,189,2,129,4,8,99,104,105,108,100,114,101,110,1,119,6,81,81,77,50,48,66,33,0,199,130,209,189,2,129,4,4,100,97,116,97,1,40,0,199,130,209,189,2,129,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,129,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,81,81,77,50,48,66,0,8,0,199,130,209,189,2,255,3,1,119,6,69,70,66,45,52,82,39,0,204,195,206,156,1,1,6,98,100,95,105,68,101,1,40,0,199,130,209,189,2,139,4,2,105,100,1,119,6,98,100,95,105,68,101,40,0,199,130,209,189,2,139,4,2,116,121,1,119,10,116,97,98,108,101,47,99,101,108,108,40,0,199,130,209,189,2,139,4,6,112,97,114,101,110,116,1,119,6,120,49,100,100,111,87,40,0,199,130,209,189,2,139,4,8,99,104,105,108,100,114,101,110,1,119,6,105,80,89,69,52,56,33,0,199,130,209,189,2,139,4,4,100,97,116,97,1,40,0,199,130,209,189,2,139,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,139,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,105,80,89,69,52,56,0,136,199,130,209,189,2,128,4,1,119,6,98,100,95,105,68,101,39,0,204,195,206,156,1,1,6,55,51,88,69,103,80,1,40,0,199,130,209,189,2,149,4,2,105,100,1,119,6,55,51,88,69,103,80,40,0,199,130,209,189,2,149,4,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,149,4,6,112,97,114,101,110,116,1,119,6,98,100,95,105,68,101,40,0,199,130,209,189,2,149,4,8,99,104,105,108,100,114,101,110,1,119,6,115,45,80,102,105,89,33,0,199,130,209,189,2,149,4,4,100,97,116,97,1,40,0,199,130,209,189,2,149,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,149,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,115,45,80,102,105,89,0,8,0,199,130,209,189,2,147,4,1,119,6,55,51,88,69,103,80,161,199,130,209,189,2,202,3,1,4,0,199,130,209,189,2,193,3,1,56,161,199,130,209,189,2,222,3,1,132,199,130,209,189,2,160,4,1,56,161,199,130,209,189,2,161,4,1,132,199,130,209,189,2,162,4,1,56,161,199,130,209,189,2,163,4,1,132,199,130,209,189,2,164,4,1,56,161,199,130,209,189,2,165,4,1,132,199,130,209,189,2,166,4,1,56,161,199,130,209,189,2,167,4,1,4,0,199,130,209,189,2,196,3,1,57,161,199,130,209,189,2,154,4,1,132,199,130,209,189,2,170,4,1,57,161,199,130,209,189,2,171,4,1,132,199,130,209,189,2,172,4,1,57,161,199,130,209,189,2,173,4,1,132,199,130,209,189,2,174,4,1,57,161,199,130,209,189,2,175,4,1,0,4,39,0,204,195,206,156,1,4,6,56,85,53,118,100,78,2,39,0,204,195,206,156,1,1,6,78,99,104,45,81,78,1,40,0,199,130,209,189,2,183,4,2,105,100,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,183,4,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,183,4,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,183,4,8,99,104,105,108,100,114,101,110,1,119,6,122,97,90,84,55,68,33,0,199,130,209,189,2,183,4,4,100,97,116,97,1,40,0,199,130,209,189,2,183,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,183,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,122,97,90,84,55,68,0,200,204,195,206,156,1,246,1,204,195,206,156,1,247,1,1,119,6,78,99,104,45,81,78,1,0,199,130,209,189,2,182,4,1,161,199,130,209,189,2,188,4,1,129,199,130,209,189,2,193,4,1,161,199,130,209,189,2,194,4,1,129,199,130,209,189,2,195,4,1,161,199,130,209,189,2,196,4,1,39,0,204,195,206,156,1,4,6,75,102,57,98,106,87,2,33,0,204,195,206,156,1,1,6,119,73,53,75,113,116,1,0,7,33,0,204,195,206,156,1,3,6,115,76,56,78,88,117,1,193,204,195,206,156,1,247,1,204,195,206,156,1,248,1,1,39,0,204,195,206,156,1,4,6,48,72,111,66,111,70,2,39,0,204,195,206,156,1,1,6,84,67,90,121,70,52,1,40,0,199,130,209,189,2,211,4,2,105,100,1,119,6,84,67,90,121,70,52,40,0,199,130,209,189,2,211,4,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,211,4,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,211,4,8,99,104,105,108,100,114,101,110,1,119,6,108,99,89,77,103,95,33,0,199,130,209,189,2,211,4,4,100,97,116,97,1,40,0,199,130,209,189,2,211,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,211,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,108,99,89,77,103,95,0,8,0,199,130,209,189,2,191,4,1,119,6,84,67,90,121,70,52,1,0,199,130,209,189,2,210,4,1,161,199,130,209,189,2,216,4,1,129,199,130,209,189,2,221,4,1,161,199,130,209,189,2,222,4,1,129,199,130,209,189,2,223,4,1,161,199,130,209,189,2,224,4,1,39,0,204,195,206,156,1,4,6,108,73,54,101,68,85,2,33,0,204,195,206,156,1,1,6,67,118,56,72,55,83,1,0,7,33,0,204,195,206,156,1,3,6,107,119,71,100,66,65,1,129,199,130,209,189,2,220,4,1,39,0,204,195,206,156,1,4,6,57,83,80,71,121,88,2,39,0,204,195,206,156,1,1,6,52,119,120,102,90,72,1,40,0,199,130,209,189,2,239,4,2,105,100,1,119,6,52,119,120,102,90,72,40,0,199,130,209,189,2,239,4,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,239,4,6,112,97,114,101,110,116,1,119,6,84,67,90,121,70,52,40,0,199,130,209,189,2,239,4,8,99,104,105,108,100,114,101,110,1,119,6,118,103,105,70,69,106,33,0,199,130,209,189,2,239,4,4,100,97,116,97,1,40,0,199,130,209,189,2,239,4,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,239,4,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,118,103,105,70,69,106,0,8,0,199,130,209,189,2,219,4,1,119,6,52,119,120,102,90,72,1,0,199,130,209,189,2,238,4,1,161,199,130,209,189,2,244,4,1,129,199,130,209,189,2,249,4,1,161,199,130,209,189,2,250,4,1,129,199,130,209,189,2,251,4,1,161,199,130,209,189,2,252,4,1,39,0,204,195,206,156,1,4,6,106,81,55,52,49,100,2,39,0,204,195,206,156,1,1,6,109,102,89,53,57,121,1,40,0,199,130,209,189,2,128,5,2,105,100,1,119,6,109,102,89,53,57,121,40,0,199,130,209,189,2,128,5,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,128,5,6,112,97,114,101,110,116,1,119,6,84,67,90,121,70,52,40,0,199,130,209,189,2,128,5,8,99,104,105,108,100,114,101,110,1,119,6,71,116,121,76,66,108,33,0,199,130,209,189,2,128,5,4,100,97,116,97,1,40,0,199,130,209,189,2,128,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,128,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,71,116,121,76,66,108,0,136,199,130,209,189,2,248,4,1,119,6,109,102,89,53,57,121,1,0,199,130,209,189,2,255,4,1,161,199,130,209,189,2,133,5,1,129,199,130,209,189,2,138,5,1,161,199,130,209,189,2,139,5,1,129,199,130,209,189,2,140,5,1,161,199,130,209,189,2,141,5,1,39,0,204,195,206,156,1,4,6,99,82,52,54,74,83,2,33,0,204,195,206,156,1,1,6,95,95,82,90,106,107,1,0,7,33,0,204,195,206,156,1,3,6,117,113,87,99,122,50,1,129,199,130,209,189,2,137,5,1,4,0,199,130,209,189,2,144,5,1,49,0,1,132,199,130,209,189,2,155,5,1,50,0,1,132,199,130,209,189,2,157,5,1,51,0,1,39,0,204,195,206,156,1,4,6,84,108,76,116,78,119,2,1,0,199,130,209,189,2,161,5,3,39,0,204,195,206,156,1,1,6,87,57,68,108,99,56,1,40,0,199,130,209,189,2,165,5,2,105,100,1,119,6,87,57,68,108,99,56,40,0,199,130,209,189,2,165,5,2,116,121,1,119,13,98,117,108,108,101,116,101,100,95,108,105,115,116,40,0,199,130,209,189,2,165,5,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,165,5,8,99,104,105,108,100,114,101,110,1,119,6,71,113,89,119,74,81,33,0,199,130,209,189,2,165,5,4,100,97,116,97,1,40,0,199,130,209,189,2,165,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,165,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,71,113,89,119,74,81,0,136,199,130,209,189,2,237,4,1,119,6,87,57,68,108,99,56,129,199,130,209,189,2,164,5,1,161,199,130,209,189,2,170,5,1,129,199,130,209,189,2,175,5,1,161,199,130,209,189,2,176,5,1,129,199,130,209,189,2,177,5,1,161,199,130,209,189,2,178,5,1,39,0,204,195,206,156,1,4,6,105,45,118,52,52,66,2,33,0,204,195,206,156,1,1,6,116,72,104,110,105,69,1,0,7,33,0,204,195,206,156,1,3,6,79,69,107,76,69,106,1,129,199,130,209,189,2,174,5,1,1,0,199,130,209,189,2,181,5,1,0,1,129,199,130,209,189,2,192,5,1,0,3,132,199,130,209,189,2,194,5,1,62,0,1,39,0,204,195,206,156,1,4,6,76,115,116,55,78,103,2,39,0,204,195,206,156,1,1,6,113,90,76,56,88,88,1,40,0,199,130,209,189,2,201,5,2,105,100,1,119,6,113,90,76,56,88,88,40,0,199,130,209,189,2,201,5,2,116,121,1,119,11,116,111,103,103,108,101,95,108,105,115,116,40,0,199,130,209,189,2,201,5,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,199,130,209,189,2,201,5,8,99,104,105,108,100,114,101,110,1,119,6,49,98,68,104,69,101,33,0,199,130,209,189,2,201,5,4,100,97,116,97,1,40,0,199,130,209,189,2,201,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,201,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,49,98,68,104,69,101,0,200,199,130,209,189,2,174,5,199,130,209,189,2,191,5,1,119,6,113,90,76,56,88,88,1,0,199,130,209,189,2,200,5,1,161,199,130,209,189,2,206,5,1,129,199,130,209,189,2,211,5,1,161,199,130,209,189,2,212,5,1,129,199,130,209,189,2,213,5,1,161,199,130,209,189,2,214,5,1,39,0,204,195,206,156,1,4,6,88,103,107,99,56,110,2,39,0,204,195,206,156,1,1,6,105,66,98,109,87,48,1,40,0,199,130,209,189,2,218,5,2,105,100,1,119,6,105,66,98,109,87,48,40,0,199,130,209,189,2,218,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,218,5,6,112,97,114,101,110,116,1,119,6,113,90,76,56,88,88,40,0,199,130,209,189,2,218,5,8,99,104,105,108,100,114,101,110,1,119,6,72,95,104,114,75,71,33,0,199,130,209,189,2,218,5,4,100,97,116,97,1,40,0,199,130,209,189,2,218,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,218,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,72,95,104,114,75,71,0,8,0,199,130,209,189,2,209,5,1,119,6,105,66,98,109,87,48,161,199,130,209,189,2,216,5,1,1,0,199,130,209,189,2,217,5,1,161,199,130,209,189,2,223,5,1,129,199,130,209,189,2,229,5,1,161,199,130,209,189,2,230,5,1,129,199,130,209,189,2,231,5,1,161,199,130,209,189,2,232,5,1,39,0,204,195,206,156,1,4,6,52,90,104,112,86,73,2,33,0,204,195,206,156,1,1,6,78,79,116,108,71,74,1,0,7,33,0,204,195,206,156,1,3,6,52,107,104,115,81,48,1,129,199,130,209,189,2,227,5,1,39,0,204,195,206,156,1,4,6,74,98,106,103,98,105,2,39,0,204,195,206,156,1,1,6,55,71,119,105,74,83,1,40,0,199,130,209,189,2,247,5,2,105,100,1,119,6,55,71,119,105,74,83,40,0,199,130,209,189,2,247,5,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,247,5,6,112,97,114,101,110,116,1,119,6,105,66,98,109,87,48,40,0,199,130,209,189,2,247,5,8,99,104,105,108,100,114,101,110,1,119,6,99,53,87,50,53,102,33,0,199,130,209,189,2,247,5,4,100,97,116,97,1,40,0,199,130,209,189,2,247,5,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,247,5,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,99,53,87,50,53,102,0,8,0,199,130,209,189,2,226,5,1,119,6,55,71,119,105,74,83,1,0,199,130,209,189,2,246,5,1,161,199,130,209,189,2,252,5,1,129,199,130,209,189,2,129,6,1,161,199,130,209,189,2,130,6,1,129,199,130,209,189,2,131,6,1,161,199,130,209,189,2,132,6,1,39,0,204,195,206,156,1,4,6,118,87,56,68,45,102,2,33,0,204,195,206,156,1,1,6,99,88,73,114,105,45,1,0,7,33,0,204,195,206,156,1,3,6,122,70,104,98,74,88,1,129,199,130,209,189,2,128,6,1,39,0,204,195,206,156,1,4,6,86,65,80,82,86,55,2,33,0,204,195,206,156,1,1,6,99,72,102,57,114,111,1,0,7,33,0,204,195,206,156,1,3,6,70,112,56,103,98,56,1,129,199,130,209,189,2,245,5,1,4,0,199,130,209,189,2,146,6,1,49,0,1,132,199,130,209,189,2,157,6,1,50,0,1,132,199,130,209,189,2,159,6,1,51,0,1,39,0,204,195,206,156,1,4,6,95,70,68,79,103,89,2,4,0,199,130,209,189,2,163,6,3,49,50,51,33,0,204,195,206,156,1,1,6,84,69,81,71,120,89,1,0,7,33,0,204,195,206,156,1,3,6,72,120,102,70,78,49,1,129,199,130,209,189,2,191,5,1,68,199,130,209,189,2,193,4,1,98,161,199,130,209,189,2,198,4,1,132,199,130,209,189,2,197,4,1,117,161,199,130,209,189,2,178,6,1,129,199,130,209,189,2,179,6,1,132,199,130,209,189,2,181,6,1,108,161,199,130,209,189,2,180,6,2,132,199,130,209,189,2,182,6,1,108,161,199,130,209,189,2,184,6,1,132,199,130,209,189,2,185,6,1,101,161,199,130,209,189,2,186,6,1,132,199,130,209,189,2,187,6,1,116,161,199,130,209,189,2,188,6,1,132,199,130,209,189,2,189,6,1,101,161,199,130,209,189,2,190,6,1,132,199,130,209,189,2,191,6,1,100,161,199,130,209,189,2,192,6,1,132,199,130,209,189,2,193,6,1,32,161,199,130,209,189,2,194,6,1,132,199,130,209,189,2,195,6,1,108,161,199,130,209,189,2,196,6,1,132,199,130,209,189,2,197,6,1,105,161,199,130,209,189,2,198,6,1,132,199,130,209,189,2,199,6,1,115,161,199,130,209,189,2,200,6,1,132,199,130,209,189,2,201,6,1,116,168,199,130,209,189,2,202,6,1,119,38,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,98,117,108,108,101,116,101,100,32,108,105,115,116,34,125,93,125,68,199,130,209,189,2,221,4,1,99,161,199,130,209,189,2,226,4,1,132,199,130,209,189,2,225,4,1,104,161,199,130,209,189,2,206,6,1,132,199,130,209,189,2,207,6,1,105,161,199,130,209,189,2,208,6,1,132,199,130,209,189,2,209,6,1,108,161,199,130,209,189,2,210,6,1,132,199,130,209,189,2,211,6,1,100,161,199,130,209,189,2,212,6,1,129,199,130,209,189,2,213,6,1,161,199,130,209,189,2,214,6,2,132,199,130,209,189,2,215,6,1,45,161,199,130,209,189,2,217,6,1,132,199,130,209,189,2,218,6,1,49,168,199,130,209,189,2,219,6,1,119,32,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,34,125,93,125,68,199,130,209,189,2,249,4,1,99,161,199,130,209,189,2,254,4,1,132,199,130,209,189,2,253,4,1,104,161,199,130,209,189,2,223,6,1,132,199,130,209,189,2,224,6,1,105,161,199,130,209,189,2,225,6,1,132,199,130,209,189,2,226,6,1,108,161,199,130,209,189,2,227,6,1,132,199,130,209,189,2,228,6,1,100,161,199,130,209,189,2,229,6,1,132,199,130,209,189,2,230,6,1,45,161,199,130,209,189,2,231,6,1,132,199,130,209,189,2,232,6,1,49,161,199,130,209,189,2,233,6,1,132,199,130,209,189,2,234,6,1,45,161,199,130,209,189,2,235,6,1,132,199,130,209,189,2,236,6,1,49,168,199,130,209,189,2,237,6,1,119,34,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,45,49,34,125,93,125,68,199,130,209,189,2,138,5,1,99,161,199,130,209,189,2,143,5,1,132,199,130,209,189,2,142,5,1,104,161,199,130,209,189,2,241,6,1,132,199,130,209,189,2,242,6,1,105,161,199,130,209,189,2,243,6,1,132,199,130,209,189,2,244,6,1,108,161,199,130,209,189,2,245,6,1,132,199,130,209,189,2,246,6,1,100,161,199,130,209,189,2,247,6,1,132,199,130,209,189,2,248,6,1,45,161,199,130,209,189,2,249,6,1,132,199,130,209,189,2,250,6,1,49,161,199,130,209,189,2,251,6,1,132,199,130,209,189,2,252,6,1,45,161,199,130,209,189,2,253,6,1,132,199,130,209,189,2,254,6,1,50,168,199,130,209,189,2,255,6,1,119,34,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,45,50,34,125,93,125,68,199,130,209,189,2,162,5,1,99,161,199,130,209,189,2,180,5,1,132,199,130,209,189,2,179,5,1,104,161,199,130,209,189,2,131,7,1,132,199,130,209,189,2,132,7,1,105,161,199,130,209,189,2,133,7,1,132,199,130,209,189,2,134,7,1,108,161,199,130,209,189,2,135,7,1,132,199,130,209,189,2,136,7,1,100,161,199,130,209,189,2,137,7,1,132,199,130,209,189,2,138,7,1,45,161,199,130,209,189,2,139,7,1,132,199,130,209,189,2,140,7,1,50,168,199,130,209,189,2,141,7,1,119,32,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,50,34,125,93,125,65,199,130,209,189,2,211,5,1,161,199,130,209,189,2,228,5,1,129,199,130,209,189,2,215,5,1,161,199,130,209,189,2,145,7,1,129,199,130,209,189,2,146,7,1,161,199,130,209,189,2,147,7,1,129,199,130,209,189,2,148,7,1,161,199,130,209,189,2,149,7,1,129,199,130,209,189,2,150,7,1,161,199,130,209,189,2,151,7,1,129,199,130,209,189,2,152,7,1,161,199,130,209,189,2,153,7,1,129,199,130,209,189,2,154,7,1,161,199,130,209,189,2,155,7,8,132,199,130,209,189,2,156,7,1,116,161,199,130,209,189,2,164,7,1,132,199,130,209,189,2,165,7,1,111,161,199,130,209,189,2,166,7,1,132,199,130,209,189,2,167,7,1,103,161,199,130,209,189,2,168,7,1,132,199,130,209,189,2,169,7,1,103,161,199,130,209,189,2,170,7,1,132,199,130,209,189,2,171,7,1,108,161,199,130,209,189,2,172,7,1,132,199,130,209,189,2,173,7,1,101,161,199,130,209,189,2,174,7,1,132,199,130,209,189,2,175,7,1,32,161,199,130,209,189,2,176,7,1,132,199,130,209,189,2,177,7,1,108,161,199,130,209,189,2,178,7,1,132,199,130,209,189,2,179,7,1,105,161,199,130,209,189,2,180,7,1,132,199,130,209,189,2,181,7,1,115,161,199,130,209,189,2,182,7,1,132,199,130,209,189,2,183,7,1,116,168,199,130,209,189,2,184,7,1,119,54,123,34,99,111,108,108,97,112,115,101,100,34,58,102,97,108,115,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,116,111,103,103,108,101,32,108,105,115,116,34,125,93,125,68,199,130,209,189,2,229,5,1,99,161,199,130,209,189,2,234,5,1,132,199,130,209,189,2,233,5,1,104,161,199,130,209,189,2,188,7,1,132,199,130,209,189,2,189,7,1,105,161,199,130,209,189,2,190,7,1,132,199,130,209,189,2,191,7,1,108,161,199,130,209,189,2,192,7,1,132,199,130,209,189,2,193,7,1,100,161,199,130,209,189,2,194,7,1,132,199,130,209,189,2,195,7,1,45,161,199,130,209,189,2,196,7,1,129,199,130,209,189,2,197,7,1,161,199,130,209,189,2,198,7,2,132,199,130,209,189,2,199,7,1,49,168,199,130,209,189,2,201,7,1,119,32,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,34,125,93,125,68,199,130,209,189,2,129,6,1,99,161,199,130,209,189,2,134,6,1,132,199,130,209,189,2,133,6,1,104,161,199,130,209,189,2,205,7,1,132,199,130,209,189,2,206,7,1,105,161,199,130,209,189,2,207,7,1,132,199,130,209,189,2,208,7,1,108,161,199,130,209,189,2,209,7,1,132,199,130,209,189,2,210,7,1,100,161,199,130,209,189,2,211,7,1,132,199,130,209,189,2,212,7,1,45,161,199,130,209,189,2,213,7,1,132,199,130,209,189,2,214,7,1,49,161,199,130,209,189,2,215,7,1,129,199,130,209,189,2,216,7,1,161,199,130,209,189,2,217,7,1,129,199,130,209,189,2,218,7,1,161,199,130,209,189,2,219,7,3,129,199,130,209,189,2,220,7,1,161,199,130,209,189,2,223,7,1,129,199,130,209,189,2,224,7,1,161,199,130,209,189,2,225,7,3,132,199,130,209,189,2,226,7,1,45,161,199,130,209,189,2,229,7,1,132,199,130,209,189,2,230,7,1,49,168,199,130,209,189,2,231,7,1,119,34,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,99,104,105,108,100,45,49,45,49,34,125,93,125,39,0,204,195,206,156,1,4,6,55,88,55,105,70,103,2,39,0,204,195,206,156,1,1,6,101,79,68,109,108,65,1,40,0,199,130,209,189,2,235,7,2,105,100,1,119,6,101,79,68,109,108,65,40,0,199,130,209,189,2,235,7,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,199,130,209,189,2,235,7,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,199,130,209,189,2,235,7,8,99,104,105,108,100,114,101,110,1,119,6,109,112,74,69,74,90,33,0,199,130,209,189,2,235,7,4,100,97,116,97,1,40,0,199,130,209,189,2,235,7,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,199,130,209,189,2,235,7,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,109,112,74,69,74,90,0,200,204,195,206,156,1,242,1,204,195,206,156,1,243,1,1,119,6,101,79,68,109,108,65,168,204,195,206,156,1,164,1,1,119,79,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,75,101,121,98,111,97,114,100,32,115,104,111,114,116,99,117,116,115,44,32,109,97,114,107,100,111,119,110,44,32,97,110,100,32,99,111,100,101,32,98,108,111,99,107,34,125,93,44,34,108,101,118,101,108,34,58,50,125,168,204,195,206,156,1,165,1,1,119,10,97,98,100,49,105,117,71,81,109,68,168,204,195,206,156,1,166,1,1,119,4,116,101,120,116,1,0,199,130,209,189,2,234,7,1,161,199,130,209,189,2,240,7,1,168,199,130,209,189,2,249,7,1,119,12,123,34,100,101,108,116,97,34,58,91,93,125,132,199,130,209,189,2,48,1,32,161,199,130,209,189,2,61,1,129,199,130,209,189,2,251,7,1,161,199,130,209,189,2,252,7,1,134,199,130,209,189,2,253,7,7,109,101,110,116,105,111,110,51,123,34,116,121,112,101,34,58,34,100,97,116,101,34,44,34,100,97,116,101,34,58,34,50,48,50,52,45,48,52,45,49,56,84,49,52,58,50,53,58,51,50,46,52,53,55,50,55,55,34,125,132,199,130,209,189,2,255,7,1,36,134,199,130,209,189,2,128,8,7,109,101,110,116,105,111,110,4,110,117,108,108,161,199,130,209,189,2,254,7,1,132,199,130,209,189,2,129,8,1,109,161,199,130,209,189,2,130,8,1,132,199,130,209,189,2,131,8,1,101,161,199,130,209,189,2,132,8,1,132,199,130,209,189,2,133,8,1,110,161,199,130,209,189,2,134,8,1,129,199,130,209,189,2,135,8,1,132,199,130,209,189,2,137,8,1,116,161,199,130,209,189,2,136,8,2,1,236,158,128,159,2,0,161,219,200,174,197,9,24,4,1,245,181,155,135,2,0,161,151,234,142,238,11,26,23,176,1,146,216,250,133,2,0,161,243,138,171,183,10,60,1,161,243,138,171,183,10,61,1,161,243,138,171,183,10,62,1,161,243,138,171,183,10,71,1,161,243,138,171,183,10,63,1,161,243,138,171,183,10,64,1,161,243,138,171,183,10,65,1,161,146,216,250,133,2,3,1,161,243,138,171,183,10,67,1,161,243,138,171,183,10,68,1,161,243,138,171,183,10,69,1,161,146,216,250,133,2,7,1,161,243,138,171,183,10,84,1,161,243,138,171,183,10,85,1,161,243,138,171,183,10,86,1,161,243,138,171,183,10,95,3,161,243,138,171,183,10,91,1,161,243,138,171,183,10,92,1,161,243,138,171,183,10,93,1,161,243,138,171,183,10,87,1,161,243,138,171,183,10,88,1,161,243,138,171,183,10,89,1,161,243,138,171,183,10,96,1,161,243,138,171,183,10,97,1,161,243,138,171,183,10,98,1,161,243,138,171,183,10,107,1,161,243,138,171,183,10,100,1,161,243,138,171,183,10,101,1,161,243,138,171,183,10,102,1,161,146,216,250,133,2,27,1,161,243,138,171,183,10,104,1,161,243,138,171,183,10,105,1,161,243,138,171,183,10,106,1,161,146,216,250,133,2,31,1,161,243,138,171,183,10,108,1,161,243,138,171,183,10,109,1,161,243,138,171,183,10,110,1,161,243,138,171,183,10,119,1,161,243,138,171,183,10,112,1,161,243,138,171,183,10,113,1,161,243,138,171,183,10,114,1,161,146,216,250,133,2,39,1,161,243,138,171,183,10,116,1,161,243,138,171,183,10,117,1,161,243,138,171,183,10,118,1,161,146,216,250,133,2,43,1,161,243,138,171,183,10,120,1,161,243,138,171,183,10,121,1,161,243,138,171,183,10,122,1,161,243,138,171,183,10,123,1,161,243,138,171,183,10,124,1,161,243,138,171,183,10,125,1,161,243,138,171,183,10,131,1,2,161,243,138,171,183,10,127,1,161,243,138,171,183,10,128,1,1,161,243,138,171,183,10,129,1,1,161,146,216,250,133,2,55,1,161,243,138,171,183,10,132,1,1,161,243,138,171,183,10,133,1,1,161,243,138,171,183,10,134,1,1,161,243,138,171,183,10,143,1,1,161,243,138,171,183,10,136,1,1,161,243,138,171,183,10,137,1,1,161,243,138,171,183,10,138,1,1,161,146,216,250,133,2,63,1,161,243,138,171,183,10,140,1,1,161,243,138,171,183,10,141,1,1,161,243,138,171,183,10,142,1,1,161,146,216,250,133,2,67,1,161,243,138,171,183,10,144,1,1,161,243,138,171,183,10,145,1,1,161,243,138,171,183,10,146,1,1,161,243,138,171,183,10,155,1,1,161,243,138,171,183,10,148,1,1,161,243,138,171,183,10,149,1,1,161,243,138,171,183,10,150,1,1,161,146,216,250,133,2,75,1,161,243,138,171,183,10,152,1,1,161,243,138,171,183,10,153,1,1,161,243,138,171,183,10,154,1,1,161,146,216,250,133,2,79,1,161,243,138,171,183,10,156,1,1,161,243,138,171,183,10,157,1,1,161,243,138,171,183,10,158,1,1,161,243,138,171,183,10,167,1,1,161,243,138,171,183,10,160,1,1,161,243,138,171,183,10,161,1,1,161,243,138,171,183,10,162,1,1,161,146,216,250,133,2,87,1,161,243,138,171,183,10,164,1,1,161,243,138,171,183,10,165,1,1,161,243,138,171,183,10,166,1,1,161,146,216,250,133,2,91,1,161,243,138,171,183,10,168,1,1,161,243,138,171,183,10,169,1,1,161,243,138,171,183,10,170,1,1,161,243,138,171,183,10,179,1,1,161,243,138,171,183,10,176,1,1,161,243,138,171,183,10,177,1,1,161,243,138,171,183,10,178,1,1,161,146,216,250,133,2,99,1,161,243,138,171,183,10,172,1,1,161,243,138,171,183,10,173,1,1,161,243,138,171,183,10,174,1,1,161,146,216,250,133,2,103,1,161,243,138,171,183,10,180,1,1,161,243,138,171,183,10,181,1,1,161,243,138,171,183,10,182,1,1,161,243,138,171,183,10,191,1,1,161,243,138,171,183,10,188,1,1,161,243,138,171,183,10,189,1,1,161,243,138,171,183,10,190,1,1,161,146,216,250,133,2,111,1,161,243,138,171,183,10,184,1,1,161,243,138,171,183,10,185,1,1,161,243,138,171,183,10,186,1,1,161,146,216,250,133,2,115,1,161,243,138,171,183,10,192,1,1,161,243,138,171,183,10,193,1,1,161,243,138,171,183,10,194,1,1,161,243,138,171,183,10,203,1,1,161,243,138,171,183,10,196,1,1,161,243,138,171,183,10,197,1,1,161,243,138,171,183,10,198,1,1,161,146,216,250,133,2,123,1,161,243,138,171,183,10,200,1,1,161,243,138,171,183,10,201,1,1,161,243,138,171,183,10,202,1,1,161,146,216,250,133,2,127,1,161,243,138,171,183,10,204,1,1,161,243,138,171,183,10,205,1,1,161,243,138,171,183,10,206,1,1,161,243,138,171,183,10,215,1,1,161,243,138,171,183,10,209,1,1,161,243,138,171,183,10,210,1,1,161,243,138,171,183,10,211,1,1,161,146,216,250,133,2,135,1,1,161,243,138,171,183,10,212,1,1,161,243,138,171,183,10,213,1,1,161,243,138,171,183,10,214,1,1,161,146,216,250,133,2,139,1,1,161,243,138,171,183,10,216,1,1,161,243,138,171,183,10,217,1,1,161,243,138,171,183,10,218,1,1,161,243,138,171,183,10,227,1,1,161,243,138,171,183,10,220,1,1,161,243,138,171,183,10,221,1,1,161,243,138,171,183,10,222,1,1,161,146,216,250,133,2,147,1,1,161,243,138,171,183,10,224,1,1,161,243,138,171,183,10,225,1,1,161,243,138,171,183,10,226,1,1,161,146,216,250,133,2,151,1,1,161,243,138,171,183,10,228,1,1,161,243,138,171,183,10,229,1,1,161,243,138,171,183,10,230,1,1,161,243,138,171,183,10,239,1,1,161,243,138,171,183,10,232,1,1,161,243,138,171,183,10,233,1,1,161,243,138,171,183,10,234,1,1,161,146,216,250,133,2,159,1,1,161,243,138,171,183,10,236,1,1,161,243,138,171,183,10,237,1,1,161,243,138,171,183,10,238,1,1,161,146,216,250,133,2,163,1,1,161,146,216,250,133,2,156,1,1,161,146,216,250,133,2,157,1,1,161,146,216,250,133,2,158,1,1,161,146,216,250,133,2,160,1,1,161,146,216,250,133,2,161,1,1,161,146,216,250,133,2,162,1,1,161,146,216,250,133,2,167,1,1,161,146,216,250,133,2,164,1,1,161,146,216,250,133,2,165,1,1,161,146,216,250,133,2,166,1,1,161,146,216,250,133,2,174,1,2,9,172,254,181,239,1,0,39,0,204,195,206,156,1,4,6,108,45,56,109,101,45,2,4,0,172,254,181,239,1,0,4,104,106,107,100,161,198,223,206,159,1,153,1,1,132,172,254,181,239,1,4,2,39,100,161,172,254,181,239,1,5,1,132,172,254,181,239,1,7,2,39,100,161,172,254,181,239,1,8,1,132,172,254,181,239,1,10,2,39,100,161,172,254,181,239,1,11,1,1,153,236,182,220,1,0,161,195,254,251,180,11,57,4,10,155,213,159,176,1,0,161,131,182,180,202,12,50,1,161,131,182,180,202,12,51,1,161,131,182,180,202,12,52,1,161,155,213,159,176,1,0,1,161,155,213,159,176,1,1,1,161,155,213,159,176,1,2,1,129,131,182,180,202,12,43,1,161,155,213,159,176,1,3,1,161,155,213,159,176,1,4,1,161,155,213,159,176,1,5,1,179,1,198,223,206,159,1,0,39,0,204,195,206,156,1,4,6,57,70,53,89,108,75,2,4,0,198,223,206,159,1,0,13,103,104,104,104,229,143,145,230,140,165,229,165,189,168,171,236,222,251,5,166,2,1,119,38,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,103,104,104,104,229,143,145,230,140,165,229,165,189,34,125,93,125,39,0,204,195,206,156,1,4,6,89,50,51,82,99,105,2,4,0,198,223,206,159,1,9,12,229,185,178,230,180,187,229,147,136,229,147,136,168,171,236,222,251,5,240,3,1,119,37,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,229,185,178,230,180,187,229,147,136,229,147,136,34,125,93,125,0,3,39,0,204,195,206,156,1,4,6,72,90,117,111,112,102,2,33,0,204,195,206,156,1,1,6,67,102,80,66,48,85,1,0,7,33,0,204,195,206,156,1,3,6,81,117,121,48,102,66,1,193,171,236,222,251,5,196,1,171,236,222,251,5,170,2,1,1,0,198,223,206,159,1,18,3,0,2,129,198,223,206,159,1,31,1,0,4,39,0,204,195,206,156,1,4,6,48,82,103,55,103,55,2,33,0,204,195,206,156,1,1,6,72,51,76,88,97,79,1,0,7,33,0,204,195,206,156,1,3,6,75,83,56,80,116,80,1,193,171,236,222,251,5,196,1,198,223,206,159,1,28,1,39,0,204,195,206,156,1,4,6,105,90,51,118,76,100,2,33,0,204,195,206,156,1,1,6,121,102,76,72,69,119,1,0,7,33,0,204,195,206,156,1,3,6,48,80,108,53,77,98,1,193,171,236,222,251,5,196,1,198,223,206,159,1,49,1,39,0,204,195,206,156,1,4,6,72,97,76,66,45,86,2,33,0,204,195,206,156,1,1,6,98,65,77,76,51,82,1,0,7,33,0,204,195,206,156,1,3,6,81,83,99,52,51,111,1,193,171,236,222,251,5,196,1,198,223,206,159,1,60,1,39,0,204,195,206,156,1,4,6,98,86,122,115,102,101,2,39,0,204,195,206,156,1,1,6,52,90,113,105,51,76,1,40,0,198,223,206,159,1,73,2,105,100,1,119,6,52,90,113,105,51,76,40,0,198,223,206,159,1,73,2,116,121,1,119,5,113,117,111,116,101,40,0,198,223,206,159,1,73,6,112,97,114,101,110,116,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,198,223,206,159,1,73,8,99,104,105,108,100,114,101,110,1,119,6,98,50,103,102,70,95,33,0,198,223,206,159,1,73,4,100,97,116,97,1,40,0,198,223,206,159,1,73,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,73,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,98,50,103,102,70,95,0,200,171,236,222,251,5,196,1,198,223,206,159,1,71,1,119,6,52,90,113,105,51,76,4,0,198,223,206,159,1,72,6,231,155,145,230,142,167,168,198,223,206,159,1,78,1,119,31,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,231,155,145,230,142,167,34,125,93,125,193,204,195,206,156,1,244,5,204,195,206,156,1,245,5,3,161,204,195,206,156,1,137,1,1,161,204,195,206,156,1,138,1,1,161,204,195,206,156,1,139,1,1,39,0,204,195,206,156,1,4,6,50,101,101,116,51,53,2,33,0,204,195,206,156,1,1,6,77,103,77,119,109,49,1,0,7,33,0,204,195,206,156,1,3,6,52,76,51,66,86,49,1,193,204,195,206,156,1,232,1,204,195,206,156,1,233,1,1,0,3,39,0,204,195,206,156,1,4,6,100,87,119,54,116,114,2,39,0,204,195,206,156,1,1,6,77,89,55,45,90,70,1,40,0,198,223,206,159,1,107,2,105,100,1,119,6,77,89,55,45,90,70,40,0,198,223,206,159,1,107,2,116,121,1,119,5,113,117,111,116,101,40,0,198,223,206,159,1,107,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,107,8,99,104,105,108,100,114,101,110,1,119,6,112,88,122,66,110,100,33,0,198,223,206,159,1,107,4,100,97,116,97,1,40,0,198,223,206,159,1,107,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,107,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,112,88,122,66,110,100,0,200,204,195,206,156,1,232,1,198,223,206,159,1,102,1,119,6,77,89,55,45,90,70,4,0,198,223,206,159,1,106,9,229,144,140,228,184,128,228,184,170,161,198,223,206,159,1,112,1,132,198,223,206,159,1,119,3,106,106,106,161,198,223,206,159,1,120,1,39,0,204,195,206,156,1,4,6,71,121,120,95,72,54,2,33,0,204,195,206,156,1,1,6,83,101,74,81,114,75,1,0,7,33,0,204,195,206,156,1,3,6,122,116,99,78,71,87,1,193,204,195,206,156,1,232,1,198,223,206,159,1,116,1,0,3,39,0,204,195,206,156,1,4,6,51,107,108,102,97,80,2,39,0,204,195,206,156,1,1,6,85,72,48,53,51,70,1,40,0,198,223,206,159,1,140,1,2,105,100,1,119,6,85,72,48,53,51,70,40,0,198,223,206,159,1,140,1,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,198,223,206,159,1,140,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,140,1,8,99,104,105,108,100,114,101,110,1,119,6,52,75,90,73,113,76,33,0,198,223,206,159,1,140,1,4,100,97,116,97,1,40,0,198,223,206,159,1,140,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,140,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,52,75,90,73,113,76,0,200,204,195,206,156,1,232,1,198,223,206,159,1,135,1,1,119,6,85,72,48,53,51,70,4,0,198,223,206,159,1,139,1,3,104,106,107,161,198,223,206,159,1,145,1,1,39,0,204,195,206,156,1,1,6,114,78,78,65,105,82,1,40,0,198,223,206,159,1,154,1,2,105,100,1,119,6,114,78,78,65,105,82,40,0,198,223,206,159,1,154,1,2,116,121,1,119,13,109,97,116,104,95,101,113,117,97,116,105,111,110,40,0,198,223,206,159,1,154,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,154,1,8,99,104,105,108,100,114,101,110,1,119,6,69,82,69,45,78,66,33,0,198,223,206,159,1,154,1,4,100,97,116,97,1,40,0,198,223,206,159,1,154,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,154,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,69,82,69,45,78,66,0,200,204,195,206,156,1,240,1,204,195,206,156,1,241,1,1,119,6,114,78,78,65,105,82,168,198,223,206,159,1,159,1,1,119,24,123,34,102,111,114,109,117,108,97,34,58,34,105,231,156,139,231,187,143,230,181,142,34,125,39,0,204,195,206,156,1,1,6,68,114,122,68,111,83,1,40,0,198,223,206,159,1,165,1,2,105,100,1,119,6,68,114,122,68,111,83,40,0,198,223,206,159,1,165,1,2,116,121,1,119,5,105,109,97,103,101,40,0,198,223,206,159,1,165,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,198,223,206,159,1,165,1,8,99,104,105,108,100,114,101,110,1,119,6,57,68,97,108,108,97,33,0,198,223,206,159,1,165,1,4,100,97,116,97,1,40,0,198,223,206,159,1,165,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,165,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,57,68,97,108,108,97,0,200,204,195,206,156,1,251,1,204,195,206,156,1,252,1,1,119,6,68,114,122,68,111,83,161,198,223,206,159,1,170,1,1,39,0,204,195,206,156,1,4,6,102,80,55,52,75,113,2,33,0,204,195,206,156,1,1,6,84,120,69,107,78,52,1,0,7,33,0,204,195,206,156,1,3,6,104,109,65,56,45,115,1,193,204,195,206,156,1,244,1,204,195,206,156,1,245,1,1,39,0,204,195,206,156,1,4,6,118,105,52,104,122,104,2,39,0,204,195,206,156,1,1,6,95,98,119,81,76,101,1,40,0,198,223,206,159,1,188,1,2,105,100,1,119,6,95,98,119,81,76,101,40,0,198,223,206,159,1,188,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,188,1,6,112,97,114,101,110,116,1,119,10,101,110,68,45,73,83,100,100,99,55,40,0,198,223,206,159,1,188,1,8,99,104,105,108,100,114,101,110,1,119,6,104,102,109,108,88,52,33,0,198,223,206,159,1,188,1,4,100,97,116,97,1,40,0,198,223,206,159,1,188,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,188,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,104,102,109,108,88,52,0,8,0,204,195,206,156,1,23,1,119,6,95,98,119,81,76,101,4,0,198,223,206,159,1,187,1,3,105,106,106,168,198,223,206,159,1,193,1,1,119,28,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,105,106,106,34,125,93,125,39,0,204,195,206,156,1,4,6,55,83,79,113,80,69,2,33,0,204,195,206,156,1,1,6,75,119,55,52,104,73,1,0,7,33,0,204,195,206,156,1,3,6,80,82,74,72,65,95,1,129,198,223,206,159,1,197,1,1,39,0,204,195,206,156,1,4,6,78,97,78,121,113,76,2,39,0,204,195,206,156,1,1,6,72,90,88,98,113,104,1,40,0,198,223,206,159,1,214,1,2,105,100,1,119,6,72,90,88,98,113,104,40,0,198,223,206,159,1,214,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,214,1,6,112,97,114,101,110,116,1,119,6,95,98,119,81,76,101,40,0,198,223,206,159,1,214,1,8,99,104,105,108,100,114,101,110,1,119,6,110,98,72,85,90,106,33,0,198,223,206,159,1,214,1,4,100,97,116,97,1,40,0,198,223,206,159,1,214,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,214,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,110,98,72,85,90,106,0,8,0,198,223,206,159,1,196,1,1,119,6,72,90,88,98,113,104,4,0,198,223,206,159,1,213,1,4,106,107,110,98,168,198,223,206,159,1,219,1,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,106,107,110,98,34,125,93,125,39,0,204,195,206,156,1,4,6,57,56,55,97,106,50,2,33,0,204,195,206,156,1,1,6,110,117,56,75,122,68,1,0,7,33,0,204,195,206,156,1,3,6,85,56,79,113,105,78,1,129,198,223,206,159,1,223,1,1,39,0,204,195,206,156,1,4,6,88,116,82,99,45,53,2,39,0,204,195,206,156,1,1,6,88,52,88,118,49,84,1,40,0,198,223,206,159,1,241,1,2,105,100,1,119,6,88,52,88,118,49,84,40,0,198,223,206,159,1,241,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,241,1,6,112,97,114,101,110,116,1,119,6,72,90,88,98,113,104,40,0,198,223,206,159,1,241,1,8,99,104,105,108,100,114,101,110,1,119,6,119,77,90,48,100,71,33,0,198,223,206,159,1,241,1,4,100,97,116,97,1,40,0,198,223,206,159,1,241,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,241,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,119,77,90,48,100,71,0,8,0,198,223,206,159,1,222,1,1,119,6,88,52,88,118,49,84,4,0,198,223,206,159,1,240,1,6,232,191,155,230,173,165,161,198,223,206,159,1,246,1,1,132,198,223,206,159,1,252,1,6,230,156,186,228,188,154,168,198,223,206,159,1,253,1,1,119,37,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,232,191,155,230,173,165,230,156,186,228,188,154,34,125,93,125,39,0,204,195,206,156,1,4,6,121,85,99,121,82,100,2,39,0,204,195,206,156,1,1,6,100,121,76,82,53,100,1,40,0,198,223,206,159,1,130,2,2,105,100,1,119,6,100,121,76,82,53,100,40,0,198,223,206,159,1,130,2,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,198,223,206,159,1,130,2,6,112,97,114,101,110,116,1,119,6,72,90,88,98,113,104,40,0,198,223,206,159,1,130,2,8,99,104,105,108,100,114,101,110,1,119,6,55,89,79,70,48,116,33,0,198,223,206,159,1,130,2,4,100,97,116,97,1,40,0,198,223,206,159,1,130,2,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,198,223,206,159,1,130,2,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,55,89,79,70,48,116,0,136,198,223,206,159,1,250,1,1,119,6,100,121,76,82,53,100,4,0,198,223,206,159,1,129,2,12,230,150,164,230,150,164,232,174,161,232,190,131,168,198,223,206,159,1,135,2,1,119,37,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,230,150,164,230,150,164,232,174,161,232,190,131,34,125,93,125,231,2,204,195,206,156,1,0,39,1,4,100,97,116,97,8,100,111,99,117,109,101,110,116,1,39,0,204,195,206,156,1,0,6,98,108,111,99,107,115,1,39,0,204,195,206,156,1,0,4,109,101,116,97,1,39,0,204,195,206,156,1,2,12,99,104,105,108,100,114,101,110,95,109,97,112,1,39,0,204,195,206,156,1,2,8,116,101,120,116,95,109,97,112,1,40,0,204,195,206,156,1,0,7,112,97,103,101,95,105,100,1,119,10,109,54,120,76,118,72,89,48,76,107,39,0,204,195,206,156,1,1,10,77,48,104,84,99,67,120,66,88,82,1,40,0,204,195,206,156,1,6,2,105,100,1,119,10,77,48,104,84,99,67,120,66,88,82,40,0,204,195,206,156,1,6,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,6,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,6,8,99,104,105,108,100,114,101,110,1,119,10,49,87,78,107,89,75,118,109,105,50,33,0,204,195,206,156,1,6,4,100,97,116,97,1,33,0,204,195,206,156,1,6,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,6,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,49,87,78,107,89,75,118,109,105,50,0,39,0,204,195,206,156,1,1,10,101,110,68,45,73,83,100,100,99,55,1,40,0,204,195,206,156,1,15,2,105,100,1,119,10,101,110,68,45,73,83,100,100,99,55,40,0,204,195,206,156,1,15,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,204,195,206,156,1,15,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,15,8,99,104,105,108,100,114,101,110,1,119,10,103,106,110,76,109,66,89,118,68,65,40,0,204,195,206,156,1,15,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,15,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,102,56,54,108,88,117,88,74,101,54,40,0,204,195,206,156,1,15,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,103,106,110,76,109,66,89,118,68,65,0,39,0,204,195,206,156,1,1,10,113,115,110,89,82,48,74,72,74,56,1,40,0,204,195,206,156,1,24,2,105,100,1,119,10,113,115,110,89,82,48,74,72,74,56,40,0,204,195,206,156,1,24,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,24,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,24,8,99,104,105,108,100,114,101,110,1,119,10,116,79,53,122,78,78,73,82,69,100,40,0,204,195,206,156,1,24,4,100,97,116,97,1,119,17,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,40,0,204,195,206,156,1,24,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,51,72,115,115,121,121,66,84,57,50,40,0,204,195,206,156,1,24,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,116,79,53,122,78,78,73,82,69,100,0,39,0,204,195,206,156,1,1,10,75,54,50,76,100,101,119,53,95,121,1,40,0,204,195,206,156,1,33,2,105,100,1,119,10,75,54,50,76,100,101,119,53,95,121,40,0,204,195,206,156,1,33,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,204,195,206,156,1,33,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,33,8,99,104,105,108,100,114,101,110,1,119,10,57,118,109,120,98,73,71,120,109,73,40,0,204,195,206,156,1,33,4,100,97,116,97,1,119,11,123,34,108,101,118,101,108,34,58,50,125,40,0,204,195,206,156,1,33,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,72,116,114,88,117,57,102,65,95,107,40,0,204,195,206,156,1,33,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,57,118,109,120,98,73,71,120,109,73,0,39,0,204,195,206,156,1,1,10,117,51,120,66,95,83,69,116,53,68,1,40,0,204,195,206,156,1,42,2,105,100,1,119,10,117,51,120,66,95,83,69,116,53,68,40,0,204,195,206,156,1,42,2,116,121,1,119,7,99,97,108,108,111,117,116,40,0,204,195,206,156,1,42,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,42,8,99,104,105,108,100,114,101,110,1,119,10,50,88,118,55,52,84,105,73,70,108,40,0,204,195,206,156,1,42,4,100,97,116,97,1,119,15,123,34,105,99,111,110,34,58,34,240,159,165,176,34,125,40,0,204,195,206,156,1,42,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,108,119,101,104,75,79,117,78,68,67,40,0,204,195,206,156,1,42,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,50,88,118,55,52,84,105,73,70,108,0,39,0,204,195,206,156,1,1,10,78,73,76,105,97,84,121,72,108,112,1,40,0,204,195,206,156,1,51,2,105,100,1,119,10,78,73,76,105,97,84,121,72,108,112,40,0,204,195,206,156,1,51,2,116,121,1,119,5,113,117,111,116,101,40,0,204,195,206,156,1,51,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,51,8,99,104,105,108,100,114,101,110,1,119,10,109,82,95,75,65,57,45,108,110,78,33,0,204,195,206,156,1,51,4,100,97,116,97,1,33,0,204,195,206,156,1,51,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,51,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,109,82,95,75,65,57,45,108,110,78,0,33,0,204,195,206,156,1,1,10,99,108,78,111,66,75,99,119,73,82,1,0,7,33,0,204,195,206,156,1,3,10,117,117,65,100,55,95,119,72,72,106,1,39,0,204,195,206,156,1,1,10,78,89,54,108,121,101,57,108,88,51,1,40,0,204,195,206,156,1,69,2,105,100,1,119,10,78,89,54,108,121,101,57,108,88,51,40,0,204,195,206,156,1,69,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,69,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,69,8,99,104,105,108,100,114,101,110,1,119,10,108,77,72,53,73,113,54,77,68,78,40,0,204,195,206,156,1,69,4,100,97,116,97,1,119,17,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,40,0,204,195,206,156,1,69,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,109,69,119,56,90,66,102,95,100,68,40,0,204,195,206,156,1,69,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,108,77,72,53,73,113,54,77,68,78,0,39,0,204,195,206,156,1,1,10,101,104,73,115,79,74,69,114,55,73,1,40,0,204,195,206,156,1,78,2,105,100,1,119,10,101,104,73,115,79,74,69,114,55,73,40,0,204,195,206,156,1,78,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,204,195,206,156,1,78,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,78,8,99,104,105,108,100,114,101,110,1,119,10,56,116,67,52,100,103,121,98,57,55,33,0,204,195,206,156,1,78,4,100,97,116,97,1,33,0,204,195,206,156,1,78,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,78,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,56,116,67,52,100,103,121,98,57,55,0,39,0,204,195,206,156,1,1,10,68,90,114,95,72,118,106,65,78,107,1,40,0,204,195,206,156,1,87,2,105,100,1,119,10,68,90,114,95,72,118,106,65,78,107,40,0,204,195,206,156,1,87,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,87,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,87,8,99,104,105,108,100,114,101,110,1,119,10,119,95,65,55,90,114,77,89,86,122,40,0,204,195,206,156,1,87,4,100,97,116,97,1,119,17,123,34,99,104,101,99,107,101,100,34,58,102,97,108,115,101,125,40,0,204,195,206,156,1,87,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,54,74,108,118,72,71,53,111,120,90,40,0,204,195,206,156,1,87,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,119,95,65,55,90,114,77,89,86,122,0,33,0,204,195,206,156,1,1,10,105,90,113,50,95,68,72,49,50,69,1,0,7,33,0,204,195,206,156,1,3,10,119,54,53,71,114,77,54,109,119,69,1,39,0,204,195,206,156,1,1,10,48,105,122,109,122,95,86,65,55,70,1,40,0,204,195,206,156,1,105,2,105,100,1,119,10,48,105,122,109,122,95,86,65,55,70,40,0,204,195,206,156,1,105,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,204,195,206,156,1,105,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,105,8,99,104,105,108,100,114,101,110,1,119,10,65,90,49,50,53,79,88,51,65,97,40,0,204,195,206,156,1,105,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,105,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,109,73,73,113,81,111,118,74,105,101,40,0,204,195,206,156,1,105,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,65,90,49,50,53,79,88,51,65,97,0,39,0,204,195,206,156,1,1,10,55,107,121,57,118,72,100,98,90,90,1,40,0,204,195,206,156,1,114,2,105,100,1,119,10,55,107,121,57,118,72,100,98,90,90,40,0,204,195,206,156,1,114,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,114,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,114,8,99,104,105,108,100,114,101,110,1,119,10,118,122,73,48,69,73,102,97,111,55,33,0,204,195,206,156,1,114,4,100,97,116,97,1,33,0,204,195,206,156,1,114,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,114,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,118,122,73,48,69,73,102,97,111,55,0,39,0,204,195,206,156,1,1,10,76,77,51,100,74,90,103,105,119,106,1,40,0,204,195,206,156,1,123,2,105,100,1,119,10,76,77,51,100,74,90,103,105,119,106,40,0,204,195,206,156,1,123,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,204,195,206,156,1,123,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,123,8,99,104,105,108,100,114,101,110,1,119,10,65,49,72,80,70,85,72,104,51,86,40,0,204,195,206,156,1,123,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,123,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,120,116,103,85,69,74,52,104,81,95,40,0,204,195,206,156,1,123,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,65,49,72,80,70,85,72,104,51,86,0,39,0,204,195,206,156,1,1,10,109,73,66,54,73,106,49,57,52,77,1,40,0,204,195,206,156,1,132,1,2,105,100,1,119,10,109,73,66,54,73,106,49,57,52,77,40,0,204,195,206,156,1,132,1,2,116,121,1,119,9,116,111,100,111,95,108,105,115,116,40,0,204,195,206,156,1,132,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,132,1,8,99,104,105,108,100,114,101,110,1,119,10,121,56,100,54,52,108,75,54,81,109,33,0,204,195,206,156,1,132,1,4,100,97,116,97,1,33,0,204,195,206,156,1,132,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,132,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,121,56,100,54,52,108,75,54,81,109,0,39,0,204,195,206,156,1,1,10,109,79,82,56,99,51,71,108,104,101,1,40,0,204,195,206,156,1,141,1,2,105,100,1,119,10,109,79,82,56,99,51,71,108,104,101,40,0,204,195,206,156,1,141,1,2,116,121,1,119,13,110,117,109,98,101,114,101,100,95,108,105,115,116,40,0,204,195,206,156,1,141,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,141,1,8,99,104,105,108,100,114,101,110,1,119,10,75,50,75,54,117,121,80,56,108,65,40,0,204,195,206,156,1,141,1,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,141,1,11,101,120,116,101,114,110,97,108,95,105,100,1,119,10,52,97,84,122,117,113,66,107,110,70,40,0,204,195,206,156,1,141,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,119,4,116,101,120,116,39,0,204,195,206,156,1,3,10,75,50,75,54,117,121,80,56,108,65,0,39,0,204,195,206,156,1,1,10,118,110,69,86,85,50,114,57,65,88,1,40,0,204,195,206,156,1,150,1,2,105,100,1,119,10,118,110,69,86,85,50,114,57,65,88,40,0,204,195,206,156,1,150,1,2,116,121,1,119,4,99,111,100,101,40,0,204,195,206,156,1,150,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,150,1,8,99,104,105,108,100,114,101,110,1,119,10,75,119,115,101,107,79,85,115,115,57,33,0,204,195,206,156,1,150,1,4,100,97,116,97,1,33,0,204,195,206,156,1,150,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,150,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,75,119,115,101,107,79,85,115,115,57,0,39,0,204,195,206,156,1,1,10,104,87,121,95,110,110,79,73,101,108,1,40,0,204,195,206,156,1,159,1,2,105,100,1,119,10,104,87,121,95,110,110,79,73,101,108,40,0,204,195,206,156,1,159,1,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,204,195,206,156,1,159,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,159,1,8,99,104,105,108,100,114,101,110,1,119,10,95,74,97,104,108,70,88,117,82,109,33,0,204,195,206,156,1,159,1,4,100,97,116,97,1,33,0,204,195,206,156,1,159,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,159,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,95,74,97,104,108,70,88,117,82,109,0,33,0,204,195,206,156,1,1,10,71,45,117,115,79,56,75,107,81,81,1,0,7,33,0,204,195,206,156,1,3,10,56,112,113,84,95,112,120,118,65,78,1,33,0,204,195,206,156,1,1,10,87,114,65,73,121,89,90,76,79,110,1,0,7,33,0,204,195,206,156,1,3,10,89,100,82,106,88,106,109,55,118,114,1,33,0,204,195,206,156,1,1,10,95,90,102,110,119,90,114,87,68,105,1,0,7,33,0,204,195,206,156,1,3,10,49,86,117,68,73,110,45,56,100,114,1,39,0,204,195,206,156,1,1,10,82,50,56,82,106,69,66,70,99,71,1,40,0,204,195,206,156,1,195,1,2,105,100,1,119,10,82,50,56,82,106,69,66,70,99,71,40,0,204,195,206,156,1,195,1,2,116,121,1,119,7,100,105,118,105,100,101,114,40,0,204,195,206,156,1,195,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,195,1,8,99,104,105,108,100,114,101,110,1,119,10,119,115,98,50,74,101,113,52,87,71,40,0,204,195,206,156,1,195,1,4,100,97,116,97,1,119,2,123,125,40,0,204,195,206,156,1,195,1,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,204,195,206,156,1,195,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,10,119,115,98,50,74,101,113,52,87,71,0,39,0,204,195,206,156,1,1,10,109,54,120,76,118,72,89,48,76,107,1,40,0,204,195,206,156,1,204,1,2,105,100,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,204,1,2,116,121,1,119,4,112,97,103,101,40,0,204,195,206,156,1,204,1,6,112,97,114,101,110,116,1,119,0,40,0,204,195,206,156,1,204,1,8,99,104,105,108,100,114,101,110,1,119,10,120,68,48,121,90,73,118,109,51,115,33,0,204,195,206,156,1,204,1,4,100,97,116,97,1,33,0,204,195,206,156,1,204,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,204,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,120,68,48,121,90,73,118,109,51,115,0,33,0,204,195,206,156,1,1,10,97,115,74,118,54,70,114,65,82,97,1,0,7,33,0,204,195,206,156,1,3,10,68,75,70,79,99,81,75,54,52,72,1,39,0,204,195,206,156,1,1,10,119,70,86,108,107,88,117,108,104,74,1,40,0,204,195,206,156,1,222,1,2,105,100,1,119,10,119,70,86,108,107,88,117,108,104,74,40,0,204,195,206,156,1,222,1,2,116,121,1,119,7,104,101,97,100,105,110,103,40,0,204,195,206,156,1,222,1,6,112,97,114,101,110,116,1,119,10,109,54,120,76,118,72,89,48,76,107,40,0,204,195,206,156,1,222,1,8,99,104,105,108,100,114,101,110,1,119,10,69,113,72,71,75,105,54,115,68,53,33,0,204,195,206,156,1,222,1,4,100,97,116,97,1,33,0,204,195,206,156,1,222,1,11,101,120,116,101,114,110,97,108,95,105,100,1,33,0,204,195,206,156,1,222,1,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,39,0,204,195,206,156,1,3,10,69,113,72,71,75,105,54,115,68,53,0,8,0,204,195,206,156,1,212,1,1,119,10,119,70,86,108,107,88,117,108,104,74,129,204,195,206,156,1,231,1,1,136,204,195,206,156,1,232,1,6,119,10,109,73,66,54,73,106,49,57,52,77,119,10,78,89,54,108,121,101,57,108,88,51,119,10,68,90,114,95,72,118,106,65,78,107,119,10,113,115,110,89,82,48,74,72,74,56,119,10,55,107,121,57,118,72,100,98,90,90,119,10,77,48,104,84,99,67,120,66,88,82,129,204,195,206,156,1,238,1,1,136,204,195,206,156,1,239,1,1,119,10,82,50,56,82,106,69,66,70,99,71,129,204,195,206,156,1,240,1,1,136,204,195,206,156,1,241,1,1,119,10,104,87,121,95,110,110,79,73,101,108,136,204,195,206,156,1,242,1,2,119,10,48,105,122,109,122,95,86,65,55,70,119,10,101,110,68,45,73,83,100,100,99,55,136,204,195,206,156,1,244,1,2,119,10,109,79,82,56,99,51,71,108,104,101,119,10,118,110,69,86,85,50,114,57,65,88,129,204,195,206,156,1,246,1,1,136,204,195,206,156,1,247,1,3,119,10,75,54,50,76,100,101,119,53,95,121,119,10,78,73,76,105,97,84,121,72,108,112,119,10,101,104,73,115,79,74,69,114,55,73,136,204,195,206,156,1,250,1,1,119,10,117,51,120,66,95,83,69,116,53,68,129,204,195,206,156,1,251,1,1,136,204,195,206,156,1,252,1,1,119,10,76,77,51,100,74,90,103,105,119,106,129,204,195,206,156,1,253,1,1,39,0,204,195,206,156,1,4,10,97,98,100,49,105,117,71,81,109,68,2,4,0,204,195,206,156,1,255,1,44,75,101,121,98,111,97,114,100,32,115,104,111,114,116,99,117,116,115,44,32,109,97,114,107,100,111,119,110,44,32,97,110,100,32,99,111,100,101,32,98,108,111,99,107,39,0,204,195,206,156,1,4,10,54,74,108,118,72,71,53,111,120,90,2,4,0,204,195,206,156,1,172,2,20,65,115,32,115,111,111,110,32,97,115,32,121,111,117,32,116,121,112,101,32,134,204,195,206,156,1,192,2,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,48,48,98,53,102,102,34,134,204,195,206,156,1,193,2,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,194,2,1,47,134,204,195,206,156,1,195,2,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,134,204,195,206,156,1,196,2,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,197,2,28,32,97,32,109,101,110,117,32,119,105,108,108,32,112,111,112,32,117,112,46,32,83,101,108,101,99,116,32,134,204,195,206,156,1,225,2,8,98,103,95,99,111,108,111,114,12,34,48,120,52,100,57,99,50,55,98,48,34,132,204,195,206,156,1,226,2,15,100,105,102,102,101,114,101,110,116,32,116,121,112,101,115,134,204,195,206,156,1,241,2,8,98,103,95,99,111,108,111,114,4,110,117,108,108,132,204,195,206,156,1,242,2,31,32,111,102,32,99,111,110,116,101,110,116,32,98,108,111,99,107,115,32,121,111,117,32,99,97,110,32,97,100,100,46,39,0,204,195,206,156,1,4,10,51,72,115,115,121,121,66,84,57,50,2,4,0,204,195,206,156,1,146,3,5,84,121,112,101,32,134,204,195,206,156,1,151,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,152,3,1,47,134,204,195,206,156,1,153,3,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,154,3,13,32,102,111,108,108,111,119,101,100,32,98,121,32,134,204,195,206,156,1,167,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,168,3,7,47,98,117,108,108,101,116,134,204,195,206,156,1,175,3,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,176,3,4,32,111,114,32,134,204,195,206,156,1,180,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,181,3,4,47,110,117,109,134,204,195,206,156,1,185,3,4,99,111,100,101,4,110,117,108,108,198,204,195,206,156,1,185,3,204,195,206,156,1,186,3,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,187,3,204,195,206,156,1,186,3,18,32,116,111,32,99,114,101,97,116,101,32,97,32,108,105,115,116,46,198,204,195,206,156,1,205,3,204,195,206,156,1,186,3,4,99,111,100,101,4,116,114,117,101,33,0,204,195,206,156,1,4,10,84,82,53,102,106,82,122,115,114,105,1,39,0,204,195,206,156,1,4,10,119,86,82,81,117,71,111,121,116,48,2,4,0,204,195,206,156,1,208,3,6,67,108,105,99,107,32,134,204,195,206,156,1,214,3,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,215,3,1,63,134,204,195,206,156,1,216,3,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,217,3,41,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,114,105,103,104,116,32,102,111,114,32,104,101,108,112,32,97,110,100,32,115,117,112,112,111,114,116,129,204,195,206,156,1,130,4,1,39,0,204,195,206,156,1,4,10,107,106,48,68,49,121,121,88,78,119,2,39,0,204,195,206,156,1,4,10,120,116,103,85,69,74,52,104,81,95,2,39,0,204,195,206,156,1,4,10,112,70,113,76,55,45,79,83,121,86,2,33,0,204,195,206,156,1,4,10,102,114,97,74,99,70,55,54,70,99,1,39,0,204,195,206,156,1,4,10,122,77,121,109,67,97,118,83,107,102,2,4,0,204,195,206,156,1,136,4,6,67,108,105,99,107,32,134,204,195,206,156,1,142,4,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,143,4,11,43,32,78,101,119,32,80,97,103,101,32,134,204,195,206,156,1,154,4,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,155,4,50,98,117,116,116,111,110,32,97,116,32,116,104,101,32,98,111,116,116,111,109,32,111,102,32,121,111,117,114,32,115,105,100,101,98,97,114,32,116,111,32,97,100,100,32,97,32,110,101,119,32,129,204,195,206,156,1,205,4,4,132,204,195,206,156,1,209,4,1,46,39,0,204,195,206,156,1,4,10,72,116,114,88,117,57,102,65,95,107,2,4,0,204,195,206,156,1,211,4,18,72,97,118,101,32,97,32,113,117,101,115,116,105,111,110,226,157,147,39,0,204,195,206,156,1,4,10,49,112,115,100,67,122,97,87,104,49,2,4,0,204,195,206,156,1,228,4,30,47,47,32,84,104,105,115,32,105,115,32,116,104,101,32,109,97,105,110,32,102,117,110,99,116,105,111,110,46,10,129,204,195,206,156,1,130,5,77,39,0,204,195,206,156,1,4,10,119,79,108,117,99,85,55,51,73,76,2,1,0,204,195,206,156,1,208,5,36,129,204,195,206,156,1,244,5,1,33,0,204,195,206,156,1,4,10,69,72,117,95,67,112,120,53,67,103,1,39,0,204,195,206,156,1,4,10,98,113,76,109,98,57,111,45,109,109,2,4,0,204,195,206,156,1,247,5,6,67,108,105,99,107,32,134,204,195,206,156,1,253,5,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,254,5,1,43,134,204,195,206,156,1,255,5,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,128,6,1,32,129,204,195,206,156,1,129,6,4,132,204,195,206,156,1,133,6,37,32,116,111,32,97,110,121,32,112,97,103,101,32,116,105,116,108,101,32,105,110,32,116,104,101,32,115,105,100,101,98,97,114,32,116,111,32,134,204,195,206,156,1,170,6,10,102,111,110,116,95,99,111,108,111,114,12,34,48,120,102,102,56,52,50,55,101,48,34,132,204,195,206,156,1,171,6,7,113,117,105,99,107,108,121,134,204,195,206,156,1,178,6,10,102,111,110,116,95,99,111,108,111,114,4,110,117,108,108,132,204,195,206,156,1,179,6,1,32,129,204,195,206,156,1,180,6,3,132,204,195,206,156,1,183,6,16,32,97,32,110,101,119,32,115,117,98,112,97,103,101,44,32,134,204,195,206,156,1,199,6,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,200,6,8,68,111,99,117,109,101,110,116,134,204,195,206,156,1,208,6,4,99,111,100,101,4,110,117,108,108,198,204,195,206,156,1,208,6,204,195,206,156,1,209,6,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,210,6,204,195,206,156,1,209,6,2,44,32,198,204,195,206,156,1,212,6,204,195,206,156,1,209,6,4,99,111,100,101,4,116,114,117,101,196,204,195,206,156,1,213,6,204,195,206,156,1,209,6,4,71,114,105,100,198,204,195,206,156,1,217,6,204,195,206,156,1,209,6,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,218,6,204,195,206,156,1,209,6,5,44,32,111,114,32,198,204,195,206,156,1,223,6,204,195,206,156,1,209,6,4,99,111,100,101,4,116,114,117,101,196,204,195,206,156,1,224,6,204,195,206,156,1,209,6,12,75,97,110,98,97,110,32,66,111,97,114,100,198,204,195,206,156,1,236,6,204,195,206,156,1,209,6,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,237,6,204,195,206,156,1,209,6,1,46,198,204,195,206,156,1,238,6,204,195,206,156,1,209,6,4,99,111,100,101,4,116,114,117,101,39,0,204,195,206,156,1,4,10,102,56,54,108,88,117,88,74,101,54,2,4,0,204,195,206,156,1,240,6,9,77,97,114,107,100,111,119,110,32,134,204,195,206,156,1,249,6,4,104,114,101,102,67,34,104,116,116,112,115,58,47,47,97,112,112,102,108,111,119,121,46,103,105,116,98,111,111,107,46,105,111,47,100,111,99,115,47,101,115,115,101,110,116,105,97,108,45,100,111,99,117,109,101,110,116,97,116,105,111,110,47,109,97,114,107,100,111,119,110,34,132,204,195,206,156,1,250,6,9,114,101,102,101,114,101,110,99,101,134,204,195,206,156,1,131,7,4,104,114,101,102,4,110,117,108,108,33,0,204,195,206,156,1,4,10,89,74,119,52,70,81,88,106,110,84,1,39,0,204,195,206,156,1,4,10,119,88,107,79,72,81,49,50,99,111,2,1,0,204,195,206,156,1,134,7,20,33,0,204,195,206,156,1,4,10,65,108,73,86,97,121,54,119,80,104,1,0,19,39,0,204,195,206,156,1,4,10,109,69,119,56,90,66,102,95,100,68,2,6,0,204,195,206,156,1,175,7,8,98,103,95,99,111,108,111,114,12,34,48,120,52,100,102,102,101,98,51,98,34,132,204,195,206,156,1,176,7,10,72,105,103,104,108,105,103,104,116,32,134,204,195,206,156,1,186,7,8,98,103,95,99,111,108,111,114,4,110,117,108,108,132,204,195,206,156,1,187,7,38,97,110,121,32,116,101,120,116,44,32,97,110,100,32,117,115,101,32,116,104,101,32,101,100,105,116,105,110,103,32,109,101,110,117,32,116,111,32,134,204,195,206,156,1,225,7,6,105,116,97,108,105,99,4,116,114,117,101,132,204,195,206,156,1,226,7,5,115,116,121,108,101,134,204,195,206,156,1,231,7,6,105,116,97,108,105,99,4,110,117,108,108,132,204,195,206,156,1,232,7,1,32,134,204,195,206,156,1,233,7,4,98,111,108,100,4,116,114,117,101,132,204,195,206,156,1,234,7,4,121,111,117,114,134,204,195,206,156,1,238,7,4,98,111,108,100,4,110,117,108,108,132,204,195,206,156,1,239,7,1,32,134,204,195,206,156,1,240,7,9,117,110,100,101,114,108,105,110,101,4,116,114,117,101,132,204,195,206,156,1,241,7,7,119,114,105,116,105,110,103,134,204,195,206,156,1,248,7,9,117,110,100,101,114,108,105,110,101,4,110,117,108,108,132,204,195,206,156,1,249,7,1,32,134,204,195,206,156,1,250,7,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,251,7,7,104,111,119,101,118,101,114,134,204,195,206,156,1,130,8,4,99,111,100,101,4,110,117,108,108,132,204,195,206,156,1,131,8,5,32,121,111,117,32,134,204,195,206,156,1,136,8,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,116,114,117,101,132,204,195,206,156,1,137,8,5,108,105,107,101,46,134,204,195,206,156,1,142,8,13,115,116,114,105,107,101,116,104,114,111,117,103,104,4,110,117,108,108,33,0,204,195,206,156,1,4,10,98,122,103,70,79,75,118,99,117,89,1,39,0,204,195,206,156,1,4,10,52,97,84,122,117,113,66,107,110,70,2,4,0,204,195,206,156,1,145,8,5,84,121,112,101,32,134,204,195,206,156,1,150,8,4,99,111,100,101,4,116,114,117,101,132,204,195,206,156,1,151,8,5,47,99,111,100,101,134,204,195,206,156,1,156,8,4,99,111,100,101,4,110,117,108,108,198,204,195,206,156,1,156,8,204,195,206,156,1,157,8,4,99,111,100,101,5,102,97,108,115,101,196,204,195,206,156,1,158,8,204,195,206,156,1,157,8,23,32,116,111,32,105,110,115,101,114,116,32,97,32,99,111,100,101,32,98,108,111,99,107,198,204,195,206,156,1,181,8,204,195,206,156,1,157,8,4,99,111,100,101,4,116,114,117,101,39,0,204,195,206,156,1,4,10,108,119,101,104,75,79,117,78,68,67,2,4,0,204,195,206,156,1,183,8,27,10,76,105,107,101,32,65,112,112,70,108,111,119,121,63,32,70,111,108,108,111,119,32,117,115,58,10,134,204,195,206,156,1,210,8,4,104,114,101,102,41,34,104,116,116,112,115,58,47,47,103,105,116,104,117,98,46,99,111,109,47,65,112,112,70,108,111,119,121,45,73,79,47,65,112,112,70,108,111,119,121,34,132,204,195,206,156,1,211,8,6,71,105,116,72,117,98,134,204,195,206,156,1,217,8,4,104,114,101,102,4,110,117,108,108,132,204,195,206,156,1,218,8,1,10,134,204,195,206,156,1,219,8,4,104,114,101,102,30,34,104,116,116,112,115,58,47,47,116,119,105,116,116,101,114,46,99,111,109,47,97,112,112,102,108,111,119,121,34,132,204,195,206,156,1,220,8,7,84,119,105,116,116,101,114,134,204,195,206,156,1,227,8,4,104,114,101,102,4,110,117,108,108,132,204,195,206,156,1,228,8,12,58,32,64,97,112,112,102,108,111,119,121,10,134,204,195,206,156,1,240,8,4,104,114,101,102,33,34,104,116,116,112,115,58,47,47,98,108,111,103,45,97,112,112,102,108,111,119,121,46,103,104,111,115,116,46,105,111,47,34,132,204,195,206,156,1,241,8,10,78,101,119,115,108,101,116,116,101,114,134,204,195,206,156,1,251,8,4,104,114,101,102,4,110,117,108,108,132,204,195,206,156,1,252,8,1,10,39,0,204,195,206,156,1,4,10,109,73,73,113,81,111,118,74,105,101,2,4,0,204,195,206,156,1,254,8,19,75,101,121,98,111,97,114,100,32,115,104,111,114,116,99,117,116,115,32,134,204,195,206,156,1,145,9,4,104,114,101,102,68,34,104,116,116,112,115,58,47,47,97,112,112,102,108,111,119,121,46,103,105,116,98,111,111,107,46,105,111,47,100,111,99,115,47,101,115,115,101,110,116,105,97,108,45,100,111,99,117,109,101,110,116,97,116,105,111,110,47,115,104,111,114,116,99,117,116,115,34,132,204,195,206,156,1,146,9,5,103,117,105,100,101,134,204,195,206,156,1,151,9,4,104,114,101,102,4,110,117,108,108,2,131,159,159,151,1,0,161,237,140,187,206,2,16,1,161,237,140,187,206,2,20,71,1,141,178,210,127,0,0,3,1,206,214,243,86,0,161,236,158,128,159,2,3,178,1,62,194,228,144,71,0,161,243,138,171,183,10,246,1,1,161,243,138,171,183,10,247,1,1,161,243,138,171,183,10,248,1,1,161,131,128,202,229,9,0,1,161,194,228,144,71,0,1,161,194,228,144,71,1,1,161,194,228,144,71,2,1,161,194,228,144,71,3,1,39,0,204,195,206,156,1,4,6,114,114,111,103,100,98,2,33,0,204,195,206,156,1,1,6,85,95,66,110,68,101,1,0,7,33,0,204,195,206,156,1,3,6,79,70,89,50,114,113,1,193,199,130,209,189,2,174,5,199,130,209,189,2,210,5,1,1,0,194,228,144,71,8,1,0,1,129,194,228,144,71,19,1,0,3,39,0,204,195,206,156,1,4,6,103,109,54,79,74,117,2,33,0,204,195,206,156,1,1,6,114,78,78,121,56,74,1,0,7,33,0,204,195,206,156,1,3,6,88,101,115,97,82,119,1,193,199,130,209,189,2,174,5,194,228,144,71,18,1,4,0,194,228,144,71,25,1,62,0,1,39,0,204,195,206,156,1,4,6,99,82,86,69,118,53,2,39,0,204,195,206,156,1,1,6,109,55,85,85,85,68,1,40,0,194,228,144,71,39,2,105,100,1,119,6,109,55,85,85,85,68,40,0,194,228,144,71,39,2,116,121,1,119,11,116,111,103,103,108,101,95,108,105,115,116,40,0,194,228,144,71,39,6,112,97,114,101,110,116,1,119,6,78,99,104,45,81,78,40,0,194,228,144,71,39,8,99,104,105,108,100,114,101,110,1,119,6,120,53,79,107,74,71,33,0,194,228,144,71,39,4,100,97,116,97,1,40,0,194,228,144,71,39,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,194,228,144,71,39,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,120,53,79,107,74,71,0,200,199,130,209,189,2,174,5,194,228,144,71,35,1,119,6,109,55,85,85,85,68,4,0,194,228,144,71,38,1,49,161,194,228,144,71,44,1,132,194,228,144,71,49,1,50,161,194,228,144,71,50,1,132,194,228,144,71,51,1,51,161,194,228,144,71,52,1,39,0,204,195,206,156,1,4,6,105,72,102,106,109,56,2,39,0,204,195,206,156,1,1,6,73,121,89,76,77,104,1,40,0,194,228,144,71,56,2,105,100,1,119,6,73,121,89,76,77,104,40,0,194,228,144,71,56,2,116,121,1,119,9,112,97,114,97,103,114,97,112,104,40,0,194,228,144,71,56,6,112,97,114,101,110,116,1,119,6,109,55,85,85,85,68,40,0,194,228,144,71,56,8,99,104,105,108,100,114,101,110,1,119,6,79,76,111,88,102,98,33,0,194,228,144,71,56,4,100,97,116,97,1,40,0,194,228,144,71,56,11,101,120,116,101,114,110,97,108,95,105,100,1,126,40,0,194,228,144,71,56,13,101,120,116,101,114,110,97,108,95,116,121,112,101,1,126,39,0,204,195,206,156,1,3,6,79,76,111,88,102,98,0,8,0,194,228,144,71,47,1,119,6,73,121,89,76,77,104,161,194,228,144,71,54,1,4,0,194,228,144,71,55,1,52,161,194,228,144,71,61,1,132,194,228,144,71,67,1,52,161,194,228,144,71,68,1,132,194,228,144,71,69,1,52,161,194,228,144,71,70,1,132,194,228,144,71,71,1,52,168,194,228,144,71,72,1,119,29,123,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,52,52,52,52,34,125,93,125,168,194,228,144,71,66,1,119,45,123,34,99,111,108,108,97,112,115,101,100,34,58,116,114,117,101,44,34,100,101,108,116,97,34,58,91,123,34,105,110,115,101,114,116,34,58,34,49,50,51,34,125,93,125,1,185,164,169,62,0,161,198,234,131,228,11,49,90,1,229,154,194,35,0,161,136,172,186,168,4,181,6,178,1,1,218,255,204,32,0,161,150,152,188,203,6,19,21,1,183,182,135,14,0,161,207,210,187,205,12,7,227,2,73,131,159,159,151,1,1,0,72,132,236,218,251,9,1,0,14,131,182,180,202,12,1,0,53,131,128,202,229,9,1,0,1,133,181,204,218,3,8,15,1,17,2,20,1,22,1,24,1,26,1,28,1,30,1,136,172,186,168,4,1,0,182,6,136,199,176,231,9,1,20,10,140,167,201,161,14,1,0,10,141,151,160,163,4,1,0,24,142,211,188,164,13,1,0,15,141,178,210,127,1,0,3,145,224,235,133,7,1,0,3,146,209,153,247,13,1,0,186,1,146,216,250,133,2,1,0,180,1,146,175,139,236,2,1,0,12,150,152,188,203,6,1,0,20,151,234,142,238,11,1,0,27,150,216,171,142,3,87,0,171,3,172,3,3,176,3,3,180,3,3,184,3,3,188,3,3,192,3,3,196,3,3,200,3,3,204,3,3,208,3,3,212,3,3,216,3,3,220,3,3,224,3,3,228,3,3,232,3,3,236,3,3,240,3,3,244,3,3,248,3,3,253,3,3,129,4,3,133,4,3,137,4,3,141,4,3,145,4,3,149,4,3,153,4,3,157,4,3,161,4,3,165,4,3,169,4,3,173,4,3,177,4,3,181,4,3,185,4,3,189,4,3,193,4,3,197,4,3,201,4,3,205,4,3,209,4,3,213,4,3,217,4,3,221,4,3,225,4,3,229,4,7,254,4,10,138,5,1,140,5,1,142,5,1,149,5,1,155,5,1,157,5,1,159,5,1,166,5,11,178,5,15,200,5,1,210,5,1,220,5,1,230,5,1,235,5,1,237,5,1,239,5,1,241,5,1,245,5,1,251,5,1,133,6,1,138,6,1,144,6,1,154,6,1,164,6,1,174,6,1,180,6,1,182,6,1,184,6,1,186,6,5,216,6,3,231,6,14,188,7,6,158,8,1,160,8,1,162,8,1,164,8,3,168,8,3,187,8,1,153,236,182,220,1,1,0,4,151,254,242,152,9,11,5,8,14,1,17,1,19,3,32,1,37,16,54,23,89,2,97,1,102,21,134,1,8,155,213,159,176,1,1,0,10,161,234,157,145,5,1,0,7,164,202,219,213,10,18,19,10,31,10,42,1,44,10,55,1,57,1,59,1,61,3,67,1,77,7,85,1,87,1,89,1,91,1,93,1,95,1,97,1,117,1,165,131,171,211,15,1,0,20,168,215,223,235,2,1,0,3,171,236,222,251,5,69,9,5,15,11,27,8,36,3,40,4,45,8,54,8,63,3,72,3,76,3,80,3,84,3,88,3,92,3,96,3,102,3,106,10,120,10,131,1,10,142,1,10,153,1,10,169,1,1,176,1,2,179,1,1,181,1,1,187,1,10,201,1,1,207,1,10,222,1,10,237,1,17,131,2,10,146,2,10,166,2,1,172,2,10,186,2,1,192,2,10,207,2,10,222,2,10,237,2,10,252,2,10,139,3,10,150,3,18,169,3,15,185,3,1,202,3,1,208,3,1,210,3,1,212,3,1,240,3,1,245,3,10,128,4,4,137,4,1,142,4,7,150,4,6,157,4,6,164,4,6,171,4,6,178,4,6,185,4,6,192,4,6,199,4,1,201,4,4,206,4,7,214,4,6,221,4,6,228,4,6,235,4,6,242,4,1,249,4,1,172,254,181,239,1,4,5,1,8,1,11,1,14,1,174,203,157,214,7,1,0,6,176,238,158,139,14,1,0,175,2,177,239,218,225,4,1,0,3,178,187,245,161,14,2,8,1,10,1,180,189,170,253,8,2,6,1,10,1,181,150,190,222,14,15,1,8,10,10,21,10,32,10,59,1,65,1,67,1,69,1,71,1,73,1,80,1,85,1,87,1,89,1,91,1,181,156,253,158,6,1,0,4,183,182,135,14,1,0,227,2,184,146,243,216,14,1,0,7,185,164,169,62,1,0,90,183,213,134,255,8,1,0,28,190,183,139,210,2,1,0,110,192,246,139,213,2,1,0,35,192,187,174,206,8,3,1,74,76,220,3,222,5,1,194,228,144,71,13,0,8,9,16,26,10,37,1,44,1,50,1,52,1,54,1,61,1,66,1,68,1,70,1,72,1,195,254,251,180,11,1,0,58,197,205,192,233,12,1,0,9,198,223,206,159,1,25,15,3,19,20,40,10,51,10,62,10,78,1,86,6,93,13,112,1,120,1,124,1,126,13,145,1,1,153,1,1,159,1,1,170,1,1,175,1,1,177,1,10,193,1,1,203,1,10,219,1,1,230,1,10,246,1,1,253,1,1,135,2,1,198,234,131,228,11,1,0,50,199,130,209,189,2,203,1,4,11,16,1,19,12,33,1,35,1,37,1,39,1,41,1,43,1,45,1,47,1,49,1,56,1,61,1,63,1,65,1,67,1,69,1,71,1,73,1,75,1,77,1,79,1,81,1,83,1,85,1,87,1,89,1,91,1,93,1,95,1,102,1,107,1,109,1,111,1,113,1,115,1,117,1,119,1,121,1,123,1,125,4,136,1,1,144,1,1,152,1,1,160,1,1,168,1,1,176,1,1,184,1,1,192,1,1,200,1,1,208,1,1,216,1,1,224,1,1,232,1,1,240,1,1,248,1,1,128,2,1,136,2,1,144,2,1,152,2,1,160,2,1,168,2,1,176,2,1,184,2,1,192,2,1,200,2,2,208,2,1,213,2,1,215,2,27,246,2,21,140,3,1,142,3,1,144,3,1,146,3,1,153,3,1,162,3,10,177,3,1,183,3,10,202,3,1,212,3,1,222,3,1,232,3,1,242,3,1,252,3,1,134,4,1,144,4,1,154,4,1,159,4,1,161,4,1,163,4,1,165,4,1,167,4,1,169,4,1,171,4,1,173,4,1,175,4,1,177,4,5,188,4,1,193,4,6,200,4,10,216,4,1,221,4,6,228,4,10,244,4,1,249,4,6,133,5,1,138,5,6,145,5,10,156,5,1,158,5,1,160,5,1,162,5,3,170,5,1,175,5,6,182,5,16,199,5,1,206,5,1,211,5,6,223,5,1,228,5,7,236,5,10,252,5,1,129,6,6,136,6,10,147,6,10,158,6,1,160,6,1,162,6,1,167,6,10,178,6,1,180,6,2,183,6,2,186,6,1,188,6,1,190,6,1,192,6,1,194,6,1,196,6,1,198,6,1,200,6,1,202,6,1,206,6,1,208,6,1,210,6,1,212,6,1,214,6,4,219,6,1,223,6,1,225,6,1,227,6,1,229,6,1,231,6,1,233,6,1,235,6,1,237,6,1,241,6,1,243,6,1,245,6,1,247,6,1,249,6,1,251,6,1,253,6,1,255,6,1,131,7,1,133,7,1,135,7,1,137,7,1,139,7,1,141,7,1,144,7,21,166,7,1,168,7,1,170,7,1,172,7,1,174,7,1,176,7,1,178,7,1,180,7,1,182,7,1,184,7,1,188,7,1,190,7,1,192,7,1,194,7,1,196,7,1,198,7,4,205,7,1,207,7,1,209,7,1,211,7,1,213,7,1,215,7,1,217,7,13,231,7,1,240,7,1,248,7,2,252,7,3,130,8,1,132,8,1,134,8,1,136,8,2,139,8,2,204,195,206,156,1,30,11,3,56,3,60,9,83,3,96,9,119,3,137,1,3,155,1,3,164,1,3,168,1,27,209,1,3,213,1,9,227,1,3,232,1,1,239,1,1,241,1,1,247,1,1,252,1,1,254,1,1,207,3,1,131,4,1,135,4,1,206,4,4,131,5,77,209,5,38,130,6,4,181,6,3,133,7,1,135,7,40,144,8,1,206,214,243,86,1,0,178,1,207,210,187,205,12,1,0,8,208,203,223,226,9,1,0,81,207,231,154,196,9,1,0,3,217,168,198,159,4,1,0,7,218,255,204,32,1,0,21,219,200,174,197,9,1,0,25,220,225,223,240,3,8,0,4,7,3,11,24,41,1,46,2,51,1,53,3,59,1,223,215,172,155,15,1,0,5,224,159,166,178,15,1,0,30,226,167,254,250,5,3,8,1,10,1,12,1,227,211,144,195,8,1,0,12,228,242,134,215,15,4,5,1,7,1,9,1,11,1,229,154,194,35,1,0,178,1,226,235,133,189,11,1,0,7,236,158,128,159,2,1,0,4,237,140,187,206,2,1,0,21,236,253,128,205,3,1,0,9,239,239,208,251,10,1,0,17,240,179,157,219,7,1,0,4,241,147,239,232,6,1,0,4,238,153,239,204,9,7,0,3,4,3,8,3,30,1,32,1,46,1,48,1,243,138,171,183,10,1,0,252,1,245,181,155,135,2,1,0,23,247,212,219,208,10,1,0,46],"version":0,"object_id":"26d5c8c1-1c66-459c-bc6c-f4da1a663348"},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/fixtures/user_workspace.json b/frontend/appflowy_web_app/cypress/fixtures/user_workspace.json index 6961f6f1c4..277b4c972c 100644 --- a/frontend/appflowy_web_app/cypress/fixtures/user_workspace.json +++ b/frontend/appflowy_web_app/cypress/fixtures/user_workspace.json @@ -1,61 +1 @@ -{ - "data": { - "user_profile": { - "uid": 304120109071339520, - "uuid": "cbff060a-196d-415a-aa80-759c01886466", - "email": "lu@appflowy.io", - "password": "", - "name": "Kilu", - "metadata": { - "icon_url": "🇽🇰" - }, - "encryption_sign": null, - "latest_workspace_id": "9eebea03-3ed5-4298-86b2-a7f77856d48b", - "updated_at": 1715847453 - }, - "visiting_workspace": { - "workspace_id": "9eebea03-3ed5-4298-86b2-a7f77856d48b", - "database_storage_id": "375874be-7a4f-4b7c-8b89-1dc9a39838f4", - "owner_uid": 304120109071339520, - "owner_name": "Kilu", - "workspace_type": 0, - "workspace_name": "Kilu Works", - "created_at": "2024-03-13T07:23:10.275174Z", - "icon": "😆" - }, - "workspaces": [ - { - "workspace_id": "81570fa8-8be9-4b2d-9f1c-1ef4f34079a8", - "database_storage_id": "6c1f1a2c-e8d5-4bc2-917f-495bce862abb", - "owner_uid": 311828434584080384, - "owner_name": "Zack Zi Xiang Fu", - "workspace_type": 0, - "workspace_name": "My Workspace", - "created_at": "2024-04-03T13:53:18.295918Z", - "icon": "" - }, - { - "workspace_id": "fcb503f9-9287-4de4-8de0-ea191e680968", - "database_storage_id": "ae1b82a5-2b93-45c7-901a-f9357c544534", - "owner_uid": 276169796100296704, - "owner_name": "Annie Anqi Wang", - "workspace_type": 0, - "workspace_name": "AppFlowy Test", - "created_at": "2023-12-27T04:18:36.372013Z", - "icon": "" - }, - { - "workspace_id": "9eebea03-3ed5-4298-86b2-a7f77856d48b", - "database_storage_id": "375874be-7a4f-4b7c-8b89-1dc9a39838f4", - "owner_uid": 304120109071339520, - "owner_name": "Kilu", - "workspace_type": 0, - "workspace_name": "Kilu Works", - "created_at": "2024-03-13T07:23:10.275174Z", - "icon": "😆" - } - ] - }, - "code": 0, - "message": "Operation completed successfully." -} \ No newline at end of file +{"data":{"user_profile":{"uid":304120109071339520,"uuid":"cbff060a-196d-415a-aa80-759c01886466","email":"lu@appflowy.io","password":"","name":"Kilu","metadata":{"icon_url":"🇽🇰"},"encryption_sign":null,"latest_workspace_id":"9eebea03-3ed5-4298-86b2-a7f77856d48b","updated_at":1715847453},"visiting_workspace":{"workspace_id":"9eebea03-3ed5-4298-86b2-a7f77856d48b","database_storage_id":"375874be-7a4f-4b7c-8b89-1dc9a39838f4","owner_uid":304120109071339520,"owner_name":"Kilu","workspace_type":0,"workspace_name":"Kilu Works","created_at":"2024-03-13T07:23:10.275174Z","icon":"😆"},"workspaces":[{"workspace_id":"81570fa8-8be9-4b2d-9f1c-1ef4f34079a8","database_storage_id":"6c1f1a2c-e8d5-4bc2-917f-495bce862abb","owner_uid":311828434584080384,"owner_name":"Zack Zi Xiang Fu","workspace_type":0,"workspace_name":"My Workspace","created_at":"2024-04-03T13:53:18.295918Z","icon":""},{"workspace_id":"fcb503f9-9287-4de4-8de0-ea191e680968","database_storage_id":"ae1b82a5-2b93-45c7-901a-f9357c544534","owner_uid":276169796100296704,"owner_name":"Annie Anqi Wang","workspace_type":0,"workspace_name":"AppFlowy Test","created_at":"2023-12-27T04:18:36.372013Z","icon":""},{"workspace_id":"9eebea03-3ed5-4298-86b2-a7f77856d48b","database_storage_id":"375874be-7a4f-4b7c-8b89-1dc9a39838f4","owner_uid":304120109071339520,"owner_name":"Kilu","workspace_type":0,"workspace_name":"Kilu Works","created_at":"2024-03-13T07:23:10.275174Z","icon":"😆"}]},"code":0,"message":"Operation completed successfully."} \ No newline at end of file diff --git a/frontend/appflowy_web_app/cypress/support/commands.ts b/frontend/appflowy_web_app/cypress/support/commands.ts index b275a842c5..f78768001f 100644 --- a/frontend/appflowy_web_app/cypress/support/commands.ts +++ b/frontend/appflowy_web_app/cypress/support/commands.ts @@ -25,9 +25,14 @@ // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) // - +import { YDoc } from '@/application/collab.type'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore +import { JSDatabaseService } from '@/application/services/js-services/database.service'; +import { JSDocumentService } from '@/application/services/js-services/document.service'; +import { applyYDoc } from '@/application/ydoc/apply'; +import * as Y from 'yjs'; + Cypress.Commands.add('mockAPI', () => { cy.fixture('sign_in_success').then((json) => { cy.intercept('GET', `/api/user/verify/${json.access_token}`, { @@ -45,3 +50,71 @@ Cypress.Commands.add('mockAPI', () => { // cy.mockAPI(); // }); +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +Cypress.Commands.add('mockCurrentWorkspace', () => { + cy.fixture('current_workspace').then((workspace) => { + cy.stub(JSDatabaseService.prototype, 'currentWorkspace').resolves(workspace); + }); +}); + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +Cypress.Commands.add('mockGetWorkspaceDatabases', () => { + cy.fixture('database/databases').then((databases) => { + cy.stub(JSDatabaseService.prototype, 'getWorkspaceDatabases').resolves(databases); + }); +}); + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +Cypress.Commands.add('mockDatabase', () => { + cy.mockCurrentWorkspace(); + cy.mockGetWorkspaceDatabases(); + + const ids = [ + '4c658817-20db-4f56-b7f9-0637a22dfeb6', + 'ce267d12-3b61-4ebb-bb03-d65272f5f817', + 'ad7dc45b-44b5-498f-bfa2-0f43bf05cc0d', + ]; + + const mockOpenDatabase = cy.stub(JSDatabaseService.prototype, 'openDatabase'); + + ids.forEach((id) => { + cy.fixture(`database/${id}`).then((database) => { + cy.fixture(`database/rows/${id}`).then((rows) => { + const doc = new Y.Doc(); + const rootRowsDoc = new Y.Doc(); + const rowsFolder: Y.Map = rootRowsDoc.getMap(); + const databaseState = new Uint8Array(database.data.doc_state); + + applyYDoc(doc, databaseState); + + Object.keys(rows).forEach((key) => { + const data = rows[key]; + const rowDoc = new Y.Doc(); + + applyYDoc(rowDoc, new Uint8Array(data)); + rowsFolder.set(key, rowDoc); + }); + mockOpenDatabase.withArgs(id).resolves({ + databaseDoc: doc, + rows: rowsFolder, + }); + }); + }); + }); +}); + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +Cypress.Commands.add('mockDocument', (id: string) => { + cy.fixture(`document/${id}`).then((subDocument) => { + const doc = new Y.Doc(); + const state = new Uint8Array(subDocument.data.doc_state); + + applyYDoc(doc, state); + + cy.stub(JSDocumentService.prototype, 'openDocument').withArgs(id).resolves(doc); + }); +}); diff --git a/frontend/appflowy_web_app/cypress/support/component.ts b/frontend/appflowy_web_app/cypress/support/component.ts index a6ca9728e3..c34213c8e2 100644 --- a/frontend/appflowy_web_app/cypress/support/component.ts +++ b/frontend/appflowy_web_app/cypress/support/component.ts @@ -14,6 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: +import '@cypress/code-coverage/support'; import './commands'; import './document'; // Alternatively you can use CommonJS syntax: @@ -31,6 +32,10 @@ declare global { interface Chainable { mount: typeof mount; mockAPI: () => void; + mockDatabase: () => void; + mockCurrentWorkspace: () => void; + mockGetWorkspaceDatabases: () => void; + mockDocument: (id: string) => void; } } } @@ -39,3 +44,4 @@ Cypress.Commands.add('mount', mount); // Example use: // cy.mount() + diff --git a/frontend/appflowy_web_app/index.html b/frontend/appflowy_web_app/index.html index 5480f37859..3d8bc89cd6 100644 --- a/frontend/appflowy_web_app/index.html +++ b/frontend/appflowy_web_app/index.html @@ -3,15 +3,44 @@ - + + AppFlowy
+ diff --git a/frontend/appflowy_web_app/jest.config.cjs b/frontend/appflowy_web_app/jest.config.cjs index 0d20a53241..b21b3c1ae3 100644 --- a/frontend/appflowy_web_app/jest.config.cjs +++ b/frontend/appflowy_web_app/jest.config.cjs @@ -17,4 +17,7 @@ module.exports = { '(.*)/node_modules/nanoid/.+\\.(j|t)sx?$': 'ts-jest', }, 'transformIgnorePatterns': [`/node_modules/(?!${esModules})`], + testMatch: ['**/*.test.ts'], + coverageDirectory: '/coverage/jest', + collectCoverage: true, }; \ No newline at end of file diff --git a/frontend/appflowy_web_app/package.json b/frontend/appflowy_web_app/package.json index 6eeb31ee09..09dbe21254 100644 --- a/frontend/appflowy_web_app/package.json +++ b/frontend/appflowy_web_app/package.json @@ -12,14 +12,17 @@ "lint": "pnpm run sync:i18n && tsc --noEmit --project tsconfig.web.json && eslint --ext .js,.ts,.tsx . --ignore-path .eslintignore.web", "start": "vite preview --port 3000", "tauri:dev": "tauri dev", - "css:variables": "node style-dictionary/config.cjs", + "css:variables": "node scripts/generateTailwindColors.cjs", "sync:i18n": "node scripts/i18n.cjs", "link:client-api": "rm -rf node_modules/.vite && node scripts/create-symlink.cjs", "analyze": "cross-env ANALYZE_MODE=true vite build", "cypress:open": "cypress open", "test": "pnpm run test:unit && pnpm run test:components", "test:components": "cypress run --component --browser chrome --headless", - "test:unit": "jest" + "test:unit": "jest --coverage", + "test:cy": "cypress run", + "merge-coverage": "node scripts/merge-coverage.cjs", + "coverage": "pnpm run test:unit && pnpm run test:components && pnpm run merge-coverage" }, "dependencies": { "@appflowyinc/client-api-wasm": "0.0.3", @@ -38,6 +41,7 @@ "@types/react-swipeable-views": "^0.13.4", "async-retry": "^1.3.3", "axios": "^1.6.8", + "colorthief": "^2.4.0", "dayjs": "^1.11.9", "decimal.js": "^10.4.3", "emoji-mart": "^5.5.2", @@ -63,6 +67,7 @@ "react-big-calendar": "^1.8.5", "react-color": "^2.19.3", "react-custom-scrollbars": "^4.2.1", + "react-custom-scrollbars-2": "^4.5.0", "react-datepicker": "^4.23.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.13", @@ -84,16 +89,19 @@ "slate": "^0.101.4", "slate-history": "^0.100.0", "slate-react": "^0.101.3", + "smooth-scroll-into-view-if-needed": "^2.0.2", "ts-results": "^3.3.0", "unsplash-js": "^7.0.19", "utf8": "^3.0.0", "validator": "^13.11.0", - "valtio": "^1.12.1", "vite-plugin-wasm": "^3.3.0", "y-indexeddb": "9.0.12", "yjs": "^13.6.14" }, "devDependencies": { + "@cypress/code-coverage": "^3.12.39", + "@istanbuljs/nyc-config-babel": "^3.0.0", + "@istanbuljs/nyc-config-typescript": "^1.0.2", "@svgr/plugin-svgo": "^8.0.1", "@tauri-apps/cli": "^1.5.11", "@types/google-protobuf": "^3.15.12", @@ -131,7 +139,9 @@ "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.6", + "istanbul-lib-coverage": "^3.2.2", "jest-environment-jsdom": "^29.6.2", + "nyc": "^15.1.0", "postcss": "^8.4.21", "prettier": "2.8.4", "prettier-plugin-tailwindcss": "^0.2.2", @@ -146,6 +156,7 @@ "vite": "^5.2.0", "vite-plugin-compression2": "^1.0.0", "vite-plugin-importer": "^0.2.5", + "vite-plugin-istanbul": "^6.0.2", "vite-plugin-svgr": "^3.2.0", "vite-plugin-terminal": "^1.2.0", "vite-plugin-total-bundle-size": "^1.0.7" diff --git a/frontend/appflowy_web_app/pnpm-lock.yaml b/frontend/appflowy_web_app/pnpm-lock.yaml index 7796ae7db8..b3e7c8496a 100644 --- a/frontend/appflowy_web_app/pnpm-lock.yaml +++ b/frontend/appflowy_web_app/pnpm-lock.yaml @@ -1,58 +1,57 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - dependencies: '@appflowyinc/client-api-wasm': specifier: 0.0.3 version: 0.0.3 '@atlaskit/primitives': specifier: ^5.5.3 - version: 5.5.3(@types/react@18.2.66)(react@18.2.0) + version: 5.7.0(@types/react@18.2.66)(react@18.2.0) '@emoji-mart/data': specifier: ^1.1.2 - version: 1.1.2 + version: 1.2.1 '@emoji-mart/react': specifier: ^1.1.1 - version: 1.1.1(emoji-mart@5.5.2)(react@18.2.0) + version: 1.1.1(emoji-mart@5.6.0)(react@18.2.0) '@emotion/react': specifier: ^11.10.6 - version: 11.10.6(@types/react@18.2.66)(react@18.2.0) + version: 11.11.4(@types/react@18.2.66)(react@18.2.0) '@emotion/styled': specifier: ^11.10.6 - version: 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) '@jest/globals': specifier: ^29.7.0 version: 29.7.0 '@mui/icons-material': specifier: ^5.11.11 - version: 5.11.11(@mui/material@6.0.0-alpha.2)(@types/react@18.2.66)(react@18.2.0) + version: 5.15.18(@mui/material@6.0.0-alpha.2)(@types/react@18.2.66)(react@18.2.0) '@mui/material': specifier: 6.0.0-alpha.2 - version: 6.0.0-alpha.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + version: 6.0.0-alpha.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) '@mui/x-date-pickers-pro': specifier: ^6.18.2 - version: 6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0) + version: 6.20.0(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0) '@reduxjs/toolkit': specifier: 2.0.0 - version: 2.0.0(react-redux@8.0.5)(react@18.2.0) + version: 2.0.0(react-redux@8.1.3)(react@18.2.0) '@slate-yjs/core': specifier: ^1.0.2 - version: 1.0.2(slate@0.101.4)(yjs@13.6.14) + version: 1.0.2(slate@0.101.5)(yjs@13.6.15) '@tauri-apps/api': specifier: ^1.5.3 - version: 1.5.3 + version: 1.5.6 '@types/react-swipeable-views': specifier: ^0.13.4 - version: 0.13.4 + version: 0.13.5 async-retry: specifier: ^1.3.3 version: 1.3.3 axios: specifier: ^1.6.8 - version: 1.6.8 + version: 1.7.2 + colorthief: + specifier: ^2.4.0 + version: 2.4.0 dayjs: specifier: ^1.11.9 version: 1.11.9 @@ -61,25 +60,25 @@ dependencies: version: 10.4.3 emoji-mart: specifier: ^5.5.2 - version: 5.5.2 + version: 5.6.0 emoji-regex: specifier: ^10.2.1 - version: 10.2.1 + version: 10.3.0 events: specifier: ^3.3.0 version: 3.3.0 google-protobuf: specifier: ^3.15.12 - version: 3.16.0 + version: 3.21.2 i18next: specifier: ^22.4.10 - version: 22.4.10 + version: 22.5.1 i18next-browser-languagedetector: specifier: ^7.0.1 - version: 7.0.1 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 is-hotkey: specifier: ^0.2.0 version: 0.2.0 @@ -88,16 +87,16 @@ dependencies: version: 29.5.0(@types/node@20.11.30) js-base64: specifier: ^3.7.5 - version: 3.7.5 + version: 3.7.7 katex: specifier: ^0.16.7 - version: 0.16.7 + version: 0.16.10 lodash-es: specifier: ^4.17.21 version: 4.17.21 nanoid: specifier: ^4.0.0 - version: 4.0.0 + version: 4.0.2 numeral: specifier: ^2.0.6 version: 2.0.6 @@ -121,16 +120,19 @@ dependencies: version: 13.1.1(react-dom@18.2.0)(react@18.2.0) react-big-calendar: specifier: ^1.8.5 - version: 1.8.5(react-dom@18.2.0)(react@18.2.0) + version: 1.12.2(react-dom@18.2.0)(react@18.2.0) react-color: specifier: ^2.19.3 version: 2.19.3(react@18.2.0) react-custom-scrollbars: specifier: ^4.2.1 version: 4.2.1(react-dom@18.2.0)(react@18.2.0) + react-custom-scrollbars-2: + specifier: ^4.5.0 + version: 4.5.0(react-dom@18.2.0)(react@18.2.0) react-datepicker: specifier: ^4.23.0 - version: 4.23.0(react-dom@18.2.0)(react@18.2.0) + version: 4.25.0(react-dom@18.2.0)(react@18.2.0) react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) @@ -142,7 +144,7 @@ dependencies: version: 2.4.1(csstype@3.1.3)(react-dom@18.2.0)(react@18.2.0) react-i18next: specifier: ^14.1.0 - version: 14.1.0(i18next@22.4.10)(react-dom@18.2.0)(react@18.2.0) + version: 14.1.2(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) react-katex: specifier: ^3.0.1 version: 3.0.1(prop-types@15.8.1)(react@18.2.0) @@ -151,10 +153,10 @@ dependencies: version: 2.5.2(react-dom@18.2.0)(react@18.2.0) react-redux: specifier: ^8.0.5 - version: 8.0.5(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + version: 8.1.3(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) react-router-dom: specifier: ^6.22.3 - version: 6.22.3(react-dom@18.2.0)(react@18.2.0) + version: 6.23.1(react-dom@18.2.0)(react@18.2.0) react-swipeable-views: specifier: ^0.14.0 version: 0.14.0(react@18.2.0) @@ -163,7 +165,7 @@ dependencies: version: 4.4.5(react-dom@18.2.0)(react@18.2.0) react-virtualized-auto-sizer: specifier: ^1.0.20 - version: 1.0.20(react-dom@18.2.0)(react@18.2.0) + version: 1.0.24(react-dom@18.2.0)(react@18.2.0) react-vtree: specifier: ^2.0.4 version: 2.0.4(@types/react-window@1.8.8)(react-dom@18.2.0)(react-window@1.8.10)(react@18.2.0) @@ -172,7 +174,7 @@ dependencies: version: 1.8.10(react-dom@18.2.0)(react@18.2.0) react18-input-otp: specifier: ^1.1.2 - version: 1.1.2(react-dom@18.2.0)(react@18.2.0) + version: 1.1.4(react-dom@18.2.0)(react@18.2.0) redux: specifier: ^4.2.1 version: 4.2.1 @@ -181,16 +183,19 @@ dependencies: version: 7.8.0 sass: specifier: ^1.70.0 - version: 1.70.0 + version: 1.77.2 slate: specifier: ^0.101.4 - version: 0.101.4 + version: 0.101.5 slate-history: specifier: ^0.100.0 - version: 0.100.0(slate@0.101.4) + version: 0.100.0(slate@0.101.5) slate-react: specifier: ^0.101.3 - version: 0.101.3(react-dom@18.2.0)(react@18.2.0)(slate@0.101.4) + version: 0.101.6(react-dom@18.2.0)(react@18.2.0)(slate@0.101.5) + smooth-scroll-into-view-if-needed: + specifier: ^2.0.2 + version: 2.0.2 ts-results: specifier: ^3.3.0 version: 3.3.0 @@ -202,21 +207,27 @@ dependencies: version: 3.0.0 validator: specifier: ^13.11.0 - version: 13.11.0 - valtio: - specifier: ^1.12.1 - version: 1.12.1(@types/react@18.2.66)(react@18.2.0) + version: 13.12.0 vite-plugin-wasm: specifier: ^3.3.0 version: 3.3.0(vite@5.2.0) y-indexeddb: specifier: 9.0.12 - version: 9.0.12(yjs@13.6.14) + version: 9.0.12(yjs@13.6.15) yjs: specifier: ^13.6.14 - version: 13.6.14 + version: 13.6.15 devDependencies: + '@cypress/code-coverage': + specifier: ^3.12.39 + version: 3.12.39(@babel/core@7.24.3)(@babel/preset-env@7.24.6)(babel-loader@9.1.3)(cypress@13.7.2)(webpack@5.91.0) + '@istanbuljs/nyc-config-babel': + specifier: ^3.0.0 + version: 3.0.0(@babel/register@7.24.6)(babel-plugin-istanbul@6.1.1) + '@istanbuljs/nyc-config-typescript': + specifier: ^1.0.2 + version: 1.0.2(nyc@15.1.0) '@svgr/plugin-svgo': specifier: ^8.0.1 version: 8.0.1(@svgr/core@8.1.0)(typescript@4.9.5) @@ -328,9 +339,15 @@ devDependencies: eslint-plugin-react-refresh: specifier: ^0.4.6 version: 0.4.6(eslint@8.57.0) + istanbul-lib-coverage: + specifier: ^3.2.2 + version: 3.2.2 jest-environment-jsdom: specifier: ^29.6.2 version: 29.6.2 + nyc: + specifier: ^15.1.0 + version: 15.1.0 postcss: specifier: ^8.4.21 version: 8.4.21 @@ -366,13 +383,16 @@ devDependencies: version: 9.0.0 vite: specifier: ^5.2.0 - version: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + version: 5.2.0(@types/node@20.11.30)(sass@1.77.2) vite-plugin-compression2: specifier: ^1.0.0 version: 1.0.0 vite-plugin-importer: specifier: ^0.2.5 version: 0.2.5 + vite-plugin-istanbul: + specifier: ^6.0.2 + version: 6.0.2(vite@5.2.0) vite-plugin-svgr: specifier: ^3.2.0 version: 3.2.0(typescript@4.9.5)(vite@5.2.0) @@ -410,27 +430,27 @@ packages: tslib: 2.6.2 dev: false - /@atlaskit/analytics-next@9.2.3(react@18.2.0): - resolution: {integrity: sha512-zTtM6xHTNNMO0dxiPrsxMko6BawEh4wN0wWSvMdQXdnusvvWNEE8rnpjn23kS4M08bYWIEstRbgoPLx6VQisug==} + /@atlaskit/analytics-next@9.3.0(react@18.2.0): + resolution: {integrity: sha512-mR5CndP92k2gFl8sWu4DJZZEpEQ4bnp5Z3fWCZE1oySiOKK8iM+KzKH4FMCaSUGOhWW6/5VeuXCcXvaogaAmsA==} peerDependencies: react: ^16.8.0 dependencies: '@atlaskit/analytics-next-stable-react-context': 1.0.1(react@18.2.0) '@atlaskit/platform-feature-flags': 0.2.5 - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.1 prop-types: 15.8.1 react: 18.2.0 use-memo-one: 1.1.3(react@18.2.0) dev: false - /@atlaskit/app-provider@1.3.0(react@18.2.0): - resolution: {integrity: sha512-0bHfIbXyCbYjuv0zMyHPyuCcyW5IIVCBsNbYEbEl9w5P9hChPyewNrz1VkNPRQBg18DF1zxIIsNyZOEuQjvs7Q==} + /@atlaskit/app-provider@1.3.2(react@18.2.0): + resolution: {integrity: sha512-tvyMNrydTyu5yJK78zUjqbJwgNRdW5nQ31imWFav5PvWXwc36lfGiTXRX/JIxJNBC3rBJ0gLAyrrb9YMzyWcTw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ~18.2.0 dependencies: - '@atlaskit/tokens': 1.43.0(react@18.2.0) - '@babel/runtime': 7.24.4 - bind-event-listener: 2.1.1 + '@atlaskit/tokens': 1.49.1(react@18.2.0) + '@babel/runtime': 7.24.1 + bind-event-listener: 3.0.0 react: 18.2.0 transitivePeerDependencies: - supports-color @@ -441,21 +461,21 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ~18.2.0 dependencies: - '@atlaskit/tokens': 1.43.0(react@18.2.0) - '@babel/runtime': 7.24.4 + '@atlaskit/tokens': 1.49.1(react@18.2.0) + '@babel/runtime': 7.24.1 '@compiled/react': 0.17.1(react@18.2.0) react: 18.2.0 transitivePeerDependencies: - supports-color dev: false - /@atlaskit/ds-lib@2.3.0(react@18.2.0): - resolution: {integrity: sha512-ULU9ZTVBvlQ9QUwKXhCju3/fUWT79zdX5omNYOIL3nUrAtBCPX7inNpIJ/D4Lx35O6XSWJRKuNFL5tR75FEYKQ==} + /@atlaskit/ds-lib@2.3.1(react@18.2.0): + resolution: {integrity: sha512-DVUE3hYLhdEZy4NnsxqiCqKC5Ym3CM/DGRQlnSPcABFNL0N0FfTXso3pLpkJnMZBtEnd2pn13mPJ2VQlSISRuw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ~18.2.0 dependencies: - '@babel/runtime': 7.24.4 - bind-event-listener: 2.1.1 + '@babel/runtime': 7.24.1 + bind-event-listener: 3.0.0 react: 18.2.0 dev: false @@ -464,32 +484,32 @@ packages: peerDependencies: react: ^16.8.0 dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.1 react: 18.2.0 dev: false /@atlaskit/platform-feature-flags@0.2.5: resolution: {integrity: sha512-0fD2aDxn2mE59D4acUhVib+YF2HDYuuPH50aYwpQdcV/CsVkAaJsMKy8WhWSulcRFeMYp72kfIfdy0qGdRB7Uw==} dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.1 dev: false - /@atlaskit/primitives@5.5.3(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-UnKx0N/Jeo5Z61wFm5U2OkJM3bcb1qpKUHYrxzmSVe+QfQvBbJ/U5882WMnwQYq9rqYR2NcFvRNyT8Lf/L4FRQ==} + /@atlaskit/primitives@5.7.0(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-eCLyHN1BllNpwqA2YqCmYpqwoiNVcW3R6bHrpKmsW8uvPE/+Bd45hOiPwvCPJUPyK1ZNMfnkegWKkoxcmjMYIQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@atlaskit/analytics-next': 9.2.3(react@18.2.0) - '@atlaskit/app-provider': 1.3.0(react@18.2.0) + '@atlaskit/analytics-next': 9.3.0(react@18.2.0) + '@atlaskit/app-provider': 1.3.2(react@18.2.0) '@atlaskit/css': 0.1.0(react@18.2.0) - '@atlaskit/ds-lib': 2.3.0(react@18.2.0) + '@atlaskit/ds-lib': 2.3.1(react@18.2.0) '@atlaskit/interaction-context': 2.1.4(react@18.2.0) - '@atlaskit/tokens': 1.43.0(react@18.2.0) - '@atlaskit/visually-hidden': 1.2.5(@types/react@18.2.66)(react@18.2.0) - '@babel/runtime': 7.24.4 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@atlaskit/tokens': 1.49.1(react@18.2.0) + '@atlaskit/visually-hidden': 1.3.0(@types/react@18.2.66)(react@18.2.0) + '@babel/runtime': 7.24.1 + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) '@emotion/serialize': 1.1.4 - bind-event-listener: 2.1.1 + bind-event-listener: 3.0.0 react: 18.2.0 tiny-invariant: 1.3.3 transitivePeerDependencies: @@ -497,29 +517,29 @@ packages: - supports-color dev: false - /@atlaskit/tokens@1.43.0(react@18.2.0): - resolution: {integrity: sha512-3rRxGRnJGQBVKGqNqy+Zuad3xuDZ7uD+aFGRcU2OpLuIpiFLX95agDZ9w0HGzNiDw9eWi2f1j8Uzq06AyaRqTw==} + /@atlaskit/tokens@1.49.1(react@18.2.0): + resolution: {integrity: sha512-3SuhRMPUTU6b+nv0zVoGsNoqrUMtwQ/4iBbKhwaylRITanFxlxBwzW8XCCnn4sp1S2JupiT5BksI0h6jRoKN9Q==} peerDependencies: - react: ^16.8.0 + react: ^16.8.0 || ^17.0.0 || ~18.2.0 dependencies: - '@atlaskit/ds-lib': 2.3.0(react@18.2.0) + '@atlaskit/ds-lib': 2.3.1(react@18.2.0) '@atlaskit/platform-feature-flags': 0.2.5 - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.1 '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 - bind-event-listener: 2.1.1 + bind-event-listener: 3.0.0 react: 18.2.0 transitivePeerDependencies: - supports-color dev: false - /@atlaskit/visually-hidden@1.2.5(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-khxJB6456uMS1IkwnsH0ZTYGVAnE83aoGarz388I0zPydOZdNeeEdwsRPFOn9mua88Ez+rL0OEWV22k6XRUf6A==} + /@atlaskit/visually-hidden@1.3.0(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-iOHCxRnhNV3gnqOHuyLOnsFibfHpr1T28XUPYZjtN9bDQbn1GdSDYLoIHnLK+2enqdILirsuUWi93mWM3dCCwg==} peerDependencies: - react: ^16.8.0 + react: ^16.8.0 || ^17.0.0 || ~18.2.0 dependencies: - '@babel/runtime': 7.24.4 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@babel/runtime': 7.24.1 + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) react: 18.2.0 transitivePeerDependencies: - '@types/react' @@ -532,10 +552,23 @@ packages: '@babel/highlight': 7.24.2 picocolors: 1.0.0 + /@babel/code-frame@7.24.6: + resolution: {integrity: sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.6 + picocolors: 1.0.0 + dev: true + /@babel/compat-data@7.24.1: resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.24.6: + resolution: {integrity: sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/core@7.24.3: resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} engines: {node: '>=6.9.0'} @@ -567,6 +600,20 @@ packages: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + /@babel/helper-annotate-as-pure@7.24.6: + resolution: {integrity: sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.24.6: + resolution: {integrity: sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + /@babel/helper-compilation-targets@7.23.6: resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} @@ -577,10 +624,71 @@ packages: lru-cache: 5.1.1 semver: 6.3.1 + /@babel/helper-compilation-targets@7.24.6: + resolution: {integrity: sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.24.6 + '@babel/helper-validator-option': 7.24.6 + browserslist: 4.23.0 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-create-class-features-plugin@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-function-name': 7.24.6 + '@babel/helper-member-expression-to-functions': 7.24.6 + '@babel/helper-optimise-call-expression': 7.24.6 + '@babel/helper-replace-supers': 7.24.6(@babel/core@7.24.3) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + semver: 6.3.1 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-annotate-as-pure': 7.24.6 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.3): + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-compilation-targets': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + debug: 4.3.4(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} + /@babel/helper-environment-visitor@7.24.6: + resolution: {integrity: sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-function-name@7.23.0: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} @@ -588,18 +696,47 @@ packages: '@babel/template': 7.24.0 '@babel/types': 7.24.0 + /@babel/helper-function-name@7.24.6: + resolution: {integrity: sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.6 + '@babel/types': 7.24.6 + dev: true + /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 + /@babel/helper-hoist-variables@7.24.6: + resolution: {integrity: sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + + /@babel/helper-member-expression-to-functions@7.24.6: + resolution: {integrity: sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + /@babel/helper-module-imports@7.24.3: resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 + /@babel/helper-module-imports@7.24.6: + resolution: {integrity: sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} @@ -613,34 +750,129 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 + /@babel/helper-module-transforms@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-simple-access': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + dev: true + + /@babel/helper-optimise-call-expression@7.24.6: + resolution: {integrity: sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + /@babel/helper-plugin-utils@7.24.0: resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} engines: {node: '>=6.9.0'} + /@babel/helper-plugin-utils@7.24.6: + resolution: {integrity: sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-wrap-function': 7.24.6 + dev: true + + /@babel/helper-replace-supers@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-member-expression-to-functions': 7.24.6 + '@babel/helper-optimise-call-expression': 7.24.6 + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 + /@babel/helper-simple-access@7.24.6: + resolution: {integrity: sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.24.6: + resolution: {integrity: sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 + /@babel/helper-split-export-declaration@7.24.6: + resolution: {integrity: sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.6 + dev: true + /@babel/helper-string-parser@7.24.1: resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} + /@babel/helper-string-parser@7.24.6: + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.24.6: + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-option@7.23.5: resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.24.6: + resolution: {integrity: sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.24.6: + resolution: {integrity: sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.24.6 + '@babel/template': 7.24.6 + '@babel/types': 7.24.6 + dev: true + /@babel/helpers@7.24.1: resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} engines: {node: '>=6.9.0'} @@ -660,6 +892,16 @@ packages: js-tokens: 4.0.0 picocolors: 1.0.0 + /@babel/highlight@7.24.6: + resolution: {integrity: sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.6 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + dev: true + /@babel/parser@7.24.1: resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} engines: {node: '>=6.0.0'} @@ -667,6 +909,67 @@ packages: dependencies: '@babel/types': 7.24.0 + /@babel/parser@7.24.6: + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.6 + dev: true + + /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 + '@babel/plugin-transform-optional-chaining': 7.24.6(@babel/core@7.24.3) + dev: true + + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + dev: true + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -691,6 +994,54 @@ packages: '@babel/core': 7.24.3 '@babel/helper-plugin-utils': 7.24.0 + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.3): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-syntax-import-assertions@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-syntax-import-attributes@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -764,6 +1115,16 @@ packages: '@babel/core': 7.24.3 '@babel/helper-plugin-utils': 7.24.0 + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.3): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} @@ -782,6 +1143,433 @@ packages: '@babel/core': 7.24.3 '@babel/helper-plugin-utils': 7.24.0 + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.3): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-regexp-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-arrow-functions@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-VEP2o4iR2DqQU6KPgizTW2mnMx6BG5b5O9iQdrW9HesLkv8GIA8x2daXBQxw1MrsIkFQGA/iJ204CKoQ8UcnAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-remap-async-to-generator': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-async-to-generator@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-NTBA2SioI3OsHeIn6sQmhvXleSl9T70YY/hostQLveWs0ic+qvbA3fa0kwAwQ0OA/XGaAerNZRQGJyRfhbJK4g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-remap-async-to-generator': 7.24.6(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-block-scoping@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-class-properties@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-class-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-class-static-block@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-class-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-classes@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-compilation-targets': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-function-name': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-replace-supers': 7.24.6(@babel/core@7.24.3) + '@babel/helper-split-export-declaration': 7.24.6 + globals: 11.12.0 + dev: true + + /@babel/plugin-transform-computed-properties@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/template': 7.24.6 + dev: true + + /@babel/plugin-transform-destructuring@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-dotall-regex@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-regexp-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-dynamic-import@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-export-namespace-from@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-for-of@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 + dev: true + + /@babel/plugin-transform-function-name@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-compilation-targets': 7.24.6 + '@babel/helper-function-name': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-json-strings@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-literals@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-member-expression-literals@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-modules-amd@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-modules-commonjs@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-simple-access': 7.24.6 + dev: true + + /@babel/plugin-transform-modules-systemjs@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-hoist-variables': 7.24.6 + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + dev: true + + /@babel/plugin-transform-modules-umd@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-regexp-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-new-target@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-numeric-separator@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-compilation-targets': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-transform-parameters': 7.24.6(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-object-super@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-replace-supers': 7.24.6(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-optional-chaining@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-parameters@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-private-methods@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-class-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-private-property-in-object@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-create-class-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3) + dev: true + + /@babel/plugin-transform-property-literals@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + /@babel/plugin-transform-react-jsx-self@7.24.1(@babel/core@7.24.3): resolution: {integrity: sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==} engines: {node: '>=6.9.0'} @@ -802,6 +1590,242 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-transform-regenerator@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + regenerator-transform: 0.15.2 + dev: true + + /@babel/plugin-transform-reserved-words@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-spread@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 + dev: true + + /@babel/plugin-transform-sticky-regex@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-template-literals@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-unicode-escapes@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-regexp-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-unicode-regex@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-regexp-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-create-regexp-features-plugin': 7.24.6(@babel/core@7.24.3) + '@babel/helper-plugin-utils': 7.24.6 + dev: true + + /@babel/preset-env@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-CrxEAvN7VxfjOG8JNF2Y/eMqMJbZPZ185amwGUBp8D9USK90xQmv7dLdFSa+VbD7fdIqcy/Mfv7WtzG8+/qxKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.24.6 + '@babel/core': 7.24.3 + '@babel/helper-compilation-targets': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/helper-validator-option': 7.24.6 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-import-assertions': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-syntax-import-attributes': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.3) + '@babel/plugin-transform-arrow-functions': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-async-generator-functions': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-async-to-generator': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-block-scoped-functions': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-block-scoping': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-class-properties': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-class-static-block': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-classes': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-computed-properties': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-destructuring': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-dotall-regex': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-duplicate-keys': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-dynamic-import': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-exponentiation-operator': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-export-namespace-from': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-for-of': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-function-name': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-json-strings': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-literals': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-logical-assignment-operators': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-member-expression-literals': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-modules-amd': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-modules-commonjs': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-modules-systemjs': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-modules-umd': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-new-target': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-numeric-separator': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-object-rest-spread': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-object-super': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-optional-catch-binding': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-optional-chaining': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-parameters': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-private-methods': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-private-property-in-object': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-property-literals': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-regenerator': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-reserved-words': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-shorthand-properties': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-spread': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-sticky-regex': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-template-literals': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-typeof-symbol': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-unicode-escapes': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-unicode-property-regex': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-unicode-regex': 7.24.6(@babel/core@7.24.3) + '@babel/plugin-transform-unicode-sets-regex': 7.24.6(@babel/core@7.24.3) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.3) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.3) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.3) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.3) + core-js-compat: 3.37.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.3): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/types': 7.24.6 + esutils: 2.0.3 + dev: true + + /@babel/register@7.24.6(@babel/core@7.24.3): + resolution: {integrity: sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + clone-deep: 4.0.1 + find-cache-dir: 2.1.0 + make-dir: 2.1.0 + pirates: 4.0.6 + source-map-support: 0.5.21 + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + /@babel/runtime@7.0.0: resolution: {integrity: sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==} dependencies: @@ -814,12 +1838,11 @@ packages: dependencies: regenerator-runtime: 0.14.1 - /@babel/runtime@7.24.4: - resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} + /@babel/runtime@7.24.6: + resolution: {integrity: sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 - dev: false /@babel/template@7.24.0: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} @@ -829,6 +1852,15 @@ packages: '@babel/parser': 7.24.1 '@babel/types': 7.24.0 + /@babel/template@7.24.6: + resolution: {integrity: sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.6 + '@babel/parser': 7.24.6 + '@babel/types': 7.24.6 + dev: true + /@babel/traverse@7.24.1: resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} engines: {node: '>=6.9.0'} @@ -854,6 +1886,15 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + /@babel/types@7.24.6: + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + to-fast-properties: 2.0.0 + dev: true + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -880,6 +1921,33 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true + /@cypress/code-coverage@3.12.39(@babel/core@7.24.3)(@babel/preset-env@7.24.6)(babel-loader@9.1.3)(cypress@13.7.2)(webpack@5.91.0): + resolution: {integrity: sha512-ja7I/GRmkSAW9e3O7pideWcNUEHao0WT6sRyXQEURoxkJUASJssJ7Kb/bd3eMYmkUCiD5CRFqWR5BGF4mWVaUw==} + peerDependencies: + '@babel/core': ^7.0.1 + '@babel/preset-env': ^7.0.0 + babel-loader: ^8.3 || ^9 + cypress: '*' + webpack: ^4 || ^5 + dependencies: + '@babel/core': 7.24.3 + '@babel/preset-env': 7.24.6(@babel/core@7.24.3) + '@cypress/webpack-preprocessor': 6.0.1(@babel/core@7.24.3)(@babel/preset-env@7.24.6)(babel-loader@9.1.3)(webpack@5.91.0) + babel-loader: 9.1.3(@babel/core@7.24.3)(webpack@5.91.0) + chalk: 4.1.2 + cypress: 13.7.2 + dayjs: 1.11.10 + debug: 4.3.4(supports-color@8.1.1) + execa: 4.1.0 + globby: 11.1.0 + istanbul-lib-coverage: 3.2.2 + js-yaml: 4.1.0 + nyc: 15.1.0 + webpack: 5.91.0 + transitivePeerDependencies: + - supports-color + dev: true + /@cypress/request@3.0.1: resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==} engines: {node: '>= 6'} @@ -904,6 +1972,25 @@ packages: uuid: 8.3.2 dev: true + /@cypress/webpack-preprocessor@6.0.1(@babel/core@7.24.3)(@babel/preset-env@7.24.6)(babel-loader@9.1.3)(webpack@5.91.0): + resolution: {integrity: sha512-WVNeFVSnFKxE3WZNRIriduTgqJRpevaiJIPlfqYTTzfXRD7X1Pv4woDE+G4caPV9bJqVKmVFiwzrXMRNeJxpxA==} + peerDependencies: + '@babel/core': ^7.0.1 + '@babel/preset-env': ^7.0.0 + babel-loader: ^8.3 || ^9 + webpack: ^4 || ^5 + dependencies: + '@babel/core': 7.24.3 + '@babel/preset-env': 7.24.6(@babel/core@7.24.3) + babel-loader: 9.1.3(@babel/core@7.24.3)(webpack@5.91.0) + bluebird: 3.7.1 + debug: 4.3.4(supports-color@8.1.1) + lodash: 4.17.21 + webpack: 5.91.0 + transitivePeerDependencies: + - supports-color + dev: true + /@cypress/xvfb@1.2.4(supports-color@8.1.1): resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} dependencies: @@ -913,17 +2000,17 @@ packages: - supports-color dev: true - /@emoji-mart/data@1.1.2: - resolution: {integrity: sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg==} + /@emoji-mart/data@1.2.1: + resolution: {integrity: sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==} dev: false - /@emoji-mart/react@1.1.1(emoji-mart@5.5.2)(react@18.2.0): + /@emoji-mart/react@1.1.1(emoji-mart@5.6.0)(react@18.2.0): resolution: {integrity: sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g==} peerDependencies: emoji-mart: ^5.2 react: ^16.8 || ^17 || ^18 dependencies: - emoji-mart: 5.5.2 + emoji-mart: 5.6.0 react: 18.2.0 dev: false @@ -967,8 +2054,8 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.10.6(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==} + /@emotion/react@11.11.4(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} peerDependencies: '@types/react': '*' react: '>=16.8.0' @@ -1002,8 +2089,8 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: false - /@emotion/styled@11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==} + /@emotion/styled@11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 '@types/react': '*' @@ -1015,7 +2102,7 @@ packages: '@babel/runtime': 7.24.1 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.2 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) '@emotion/serialize': 1.1.4 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 @@ -1264,32 +2351,32 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@floating-ui/core@1.6.0: - resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + /@floating-ui/core@1.6.2: + resolution: {integrity: sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==} dependencies: - '@floating-ui/utils': 0.2.1 + '@floating-ui/utils': 0.2.2 dev: false - /@floating-ui/dom@1.6.3: - resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} + /@floating-ui/dom@1.6.5: + resolution: {integrity: sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==} dependencies: - '@floating-ui/core': 1.6.0 - '@floating-ui/utils': 0.2.1 + '@floating-ui/core': 1.6.2 + '@floating-ui/utils': 0.2.2 dev: false - /@floating-ui/react-dom@2.0.8(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==} + /@floating-ui/react-dom@2.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@floating-ui/dom': 1.6.3 + '@floating-ui/dom': 1.6.5 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@floating-ui/utils@0.2.1: - resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + /@floating-ui/utils@0.2.2: + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} dev: false /@humanwhocodes/config-array@0.11.14: @@ -1342,6 +2429,27 @@ packages: js-yaml: 3.14.1 resolve-from: 5.0.0 + /@istanbuljs/nyc-config-babel@3.0.0(@babel/register@7.24.6)(babel-plugin-istanbul@6.1.1): + resolution: {integrity: sha512-mPnSPXfTRWCzYsT64PnuPlce6/hGMCdVVMgU2FenXipbUd+FDwUlqlTihXxpxWzcNVOp8M+L1t/kIcgoC8A7hg==} + engines: {node: '>=8'} + peerDependencies: + '@babel/register': '*' + babel-plugin-istanbul: '>=5' + dependencies: + '@babel/register': 7.24.6(@babel/core@7.24.3) + babel-plugin-istanbul: 6.1.1 + dev: true + + /@istanbuljs/nyc-config-typescript@1.0.2(nyc@15.1.0): + resolution: {integrity: sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==} + engines: {node: '>=8'} + peerDependencies: + nyc: '>=15' + dependencies: + '@istanbuljs/schema': 0.1.3 + nyc: 15.1.0 + dev: true + /@istanbuljs/schema@0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} @@ -1562,6 +2670,13 @@ packages: resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} + /@jridgewell/source-map@0.3.6: + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} @@ -1582,6 +2697,10 @@ packages: resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} dev: false + /@lokesh.dhakar/quantize@1.3.0: + resolution: {integrity: sha512-4KBSyaMj65d8A+2vnzLxtHFu4OmBU4IKO0yLxZ171Itdf9jGV4w+WbG7VsKts2jUdRkFSzsZqpZOz6hTB3qGAw==} + dev: false + /@mui/base@5.0.0-beta.40(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} engines: {node: '>=12.0.0'} @@ -1594,12 +2713,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.24.1 - '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) + '@floating-ui/react-dom': 2.1.0(react-dom@18.2.0)(react@18.2.0) '@mui/types': 7.2.14(@types/react@18.2.66) '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) '@popperjs/core': 2.11.8 '@types/react': 18.2.66 - clsx: 2.1.0 + clsx: 2.1.1 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1616,24 +2735,24 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 - '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) + '@babel/runtime': 7.24.6 + '@floating-ui/react-dom': 2.1.0(react-dom@18.2.0)(react@18.2.0) '@mui/types': 7.2.14(@types/react@18.2.66) - '@mui/utils': 6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0) + '@mui/utils': 6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0) '@popperjs/core': 2.11.8 '@types/react': 18.2.66 - clsx: 2.1.0 + clsx: 2.1.1 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/core-downloads-tracker@6.0.0-alpha.2: - resolution: {integrity: sha512-6JSNsfMePoLZ0tKZzQ2i+W8mcZCbP9snFNf/pQGOsMK2igkPGqOfqgdsda2OJrD5tP9VGjEDrrmYGHuX3ir29g==} + /@mui/core-downloads-tracker@6.0.0-dev.240424162023-9968b4889d: + resolution: {integrity: sha512-doh3M3U7HUGSBIWGe1yvesSbfDguMRjP0N09ogWSBM2hovXAlgULhMgcRTepAZLLwfRxFII0bCohq6B9NqoKuw==} dev: false - /@mui/icons-material@5.11.11(@mui/material@6.0.0-alpha.2)(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-Eell3ADmQVE8HOpt/LZ3zIma8JSvPh3XgnhwZLT0k5HRqZcd6F/QDHc7xsWtgz09t+UEFvOYJXjtrwKmLdwwpw==} + /@mui/icons-material@5.15.18(@mui/material@6.0.0-alpha.2)(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-jGhyw02TSLM0NgW+MDQRLLRUD/K4eN9rlK2pTBTL1OtzyZmQ8nB060zK1wA0b7cVrIiG+zyrRmNAvGWXwm2N9Q==} engines: {node: '>=12.0.0'} peerDependencies: '@mui/material': ^5.0.0 @@ -1644,12 +2763,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.24.1 - '@mui/material': 6.0.0-alpha.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 6.0.0-alpha.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) '@types/react': 18.2.66 react: 18.2.0 dev: false - /@mui/material@6.0.0-alpha.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0): + /@mui/material@6.0.0-alpha.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-p1GpE1a7dQTns0yp0anSNX/Bh1xafTdUCt0roTyqEuL/3hCBKTURE/9/CDttwwQ+Q8oDm5KcsdtXJXJh1ts6Kw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1666,17 +2785,17 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@babel/runtime': 7.24.6 + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) '@mui/base': 5.0.0-beta.42(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) - '@mui/core-downloads-tracker': 6.0.0-alpha.2 - '@mui/system': 6.0.0-alpha.1(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/core-downloads-tracker': 6.0.0-dev.240424162023-9968b4889d + '@mui/system': 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react@18.2.0) '@mui/types': 7.2.14(@types/react@18.2.66) - '@mui/utils': 6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0) + '@mui/utils': 6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0) '@types/react': 18.2.66 '@types/react-transition-group': 4.4.10 - clsx: 2.1.0 + clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 @@ -1695,15 +2814,15 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.6 '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) '@types/react': 18.2.66 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/private-theming@6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-S+vlRxja0ncLT1KK+Qkqy6ZNpIsw5ZxoTd70KR8foLtPQXs0XGWQkq9IotbcZnYyKUUhM/5Cqo3w8Q/zNNVzBQ==} + /@mui/private-theming@6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-0iN+hK/OZTaiVfjFYDgWEc/frRB7Z1hfBsSJBniM4KPZnrdeHIArP+3TdYzRT0avh30O2KNkBNk0GG95BnUVEg==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1712,14 +2831,14 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 - '@mui/utils': 6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0) + '@babel/runtime': 7.24.6 + '@mui/utils': 6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0) '@types/react': 18.2.66 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styled-engine@5.15.14(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0): + /@mui/styled-engine@5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.2.0): resolution: {integrity: sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1732,17 +2851,17 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.6 '@emotion/cache': 11.11.0 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styled-engine@6.0.0-alpha.1(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0): - resolution: {integrity: sha512-lJmMF1D3SD9unSh5gjXYU3ChiCrNGrpT36cPOmGv7wiH2qLMov5Wo23nK7UfuaQVA4c4/JAS43SLT2O2z6hx4Q==} + /@mui/styled-engine@6.0.0-alpha.8(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.2.0): + resolution: {integrity: sha512-7zJYgbjZRQpGN1SGmLDOgRpJZB26JjPSeqml5m+jA4wAsIONm2im+GHfki4nE3ay0uj1S555OMeNpaQ+sG9LkA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -1754,16 +2873,16 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.6 '@emotion/cache': 11.11.0 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.15.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0): + /@mui/system@5.15.15(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react@18.2.0): resolution: {integrity: sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1779,22 +2898,22 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@babel/runtime': 7.24.6 + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) '@mui/private-theming': 5.15.14(@types/react@18.2.66)(react@18.2.0) - '@mui/styled-engine': 5.15.14(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0) + '@mui/styled-engine': 5.15.14(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.2.0) '@mui/types': 7.2.14(@types/react@18.2.66) '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) '@types/react': 18.2.66 - clsx: 2.1.0 + clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@6.0.0-alpha.1(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-NqOFHCT/lvi4v696b0pEEz2Jc3MgjjGRsbFNN+IW5EuIInHr/JEznnPw0GpEU8tgU544MdfMTlFpDgR1LmvmLA==} + /@mui/system@6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-Y3yCFUHN1xMK62hJJBqzZb1YQvHNaHc7JUX01eU6QTPojtIbGMF2jCOP/EQw77/byahNbxeLoAIQx10F0IR3Rw==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1809,15 +2928,15 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) - '@mui/private-theming': 6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0) - '@mui/styled-engine': 6.0.0-alpha.1(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0) + '@babel/runtime': 7.24.6 + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) + '@mui/private-theming': 6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0) + '@mui/styled-engine': 6.0.0-alpha.8(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.2.0) '@mui/types': 7.2.14(@types/react@18.2.66) - '@mui/utils': 6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0) + '@mui/utils': 6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0) '@types/react': 18.2.66 - clsx: 2.1.0 + clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 @@ -1852,8 +2971,8 @@ packages: react-is: 18.2.0 dev: false - /@mui/utils@6.0.0-alpha.1(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-BvTVWvW6JDxMjDfEfTTEb6/CLgj87HyS3hYA4hbk0LdFsXeRnFSK6yDj8Dw3gxvXBymQ26kHDyFK3pEoAFlurw==} + /@mui/utils@6.0.0-alpha.8(@types/react@18.2.66)(react@18.2.0): + resolution: {integrity: sha512-X5lg0bh8B6uYt/0HXV+t82HXLTOVFEKcIBmIbJ5El1h9ykXaRTenr8mORxt5UC5w9DHFhkRoI8XiM5qyDuSJVw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1862,7 +2981,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.6 '@types/prop-types': 15.7.12 '@types/react': 18.2.66 prop-types: 15.8.1 @@ -1870,15 +2989,15 @@ packages: react-is: 18.2.0 dev: false - /@mui/x-date-pickers-pro@6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-8lEVEOtCQssKWel4Ey1pRulGPXUQ73TnkHKzHWsjdv03FjiUs3eYB+Ej0Uk5yWPmsqlShWhOzOlOGDpzsYJsUg==} + /@mui/x-date-pickers-pro@6.20.0(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-lXbO8xCKRvIKgu2R8EAGhYwN1BkMS9GxTeinKZg5lCGvxTrd5pErQ4xpOxYVQq7wNLphDiY7I/Xf88VekKTNLQ==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 '@mui/material': ^5.8.6 '@mui/system': ^5.8.0 - date-fns: ^2.25.0 + date-fns: ^2.25.0 || ^3.2.0 date-fns-jalali: ^2.13.0-0 dayjs: ^1.10.7 luxon: ^3.0.2 @@ -1908,15 +3027,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.24.1 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) '@mui/base': 5.0.0-beta.40(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) - '@mui/material': 6.0.0-alpha.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) - '@mui/system': 5.15.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/material': 6.0.0-alpha.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.15.15(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react@18.2.0) '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) - '@mui/x-date-pickers': 6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-date-pickers': 6.20.0(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0) '@mui/x-license-pro': 6.10.2(@types/react@18.2.66)(react@18.2.0) - clsx: 2.1.0 + clsx: 2.1.1 dayjs: 1.11.9 prop-types: 15.8.1 react: 18.2.0 @@ -1926,15 +3045,15 @@ packages: - '@types/react' dev: false - /@mui/x-date-pickers@6.18.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-HJq4uoFQSu5isa/mesWw2BKh8KBRYUQb+KaSlVlWfJNgP3YhPvWZ6yqCNYyxOAiPMxb0n3nBjS9ErO27OHjFMA==} + /@mui/x-date-pickers@6.20.0(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@6.0.0-alpha.2)(@mui/system@5.15.15)(@types/react@18.2.66)(dayjs@1.11.9)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-q/x3rNmPYMXnx75+3s9pQb1YDtws9y5bwxpxeB3EW88oCp33eS7bvJpeuoCA1LzW/PpVfIRhi5RCyAvrEeTL7Q==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 '@mui/material': ^5.8.6 '@mui/system': ^5.8.0 - date-fns: ^2.25.0 + date-fns: ^2.25.0 || ^3.2.0 date-fns-jalali: ^2.13.0-0 dayjs: ^1.10.7 luxon: ^3.0.2 @@ -1964,14 +3083,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.24.1 - '@emotion/react': 11.10.6(@types/react@18.2.66)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.66)(react@18.2.0) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.2.66)(react@18.2.0) '@mui/base': 5.0.0-beta.40(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) - '@mui/material': 6.0.0-alpha.2(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) - '@mui/system': 5.15.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.2.66)(react@18.2.0) + '@mui/material': 6.0.0-alpha.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.15.15(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.2.66)(react@18.2.0) '@mui/utils': 5.15.14(@types/react@18.2.66)(react@18.2.0) '@types/react-transition-group': 4.4.10 - clsx: 2.1.0 + clsx: 2.1.1 dayjs: 1.11.9 prop-types: 15.8.1 react: 18.2.0 @@ -2029,7 +3148,7 @@ packages: /@popperjs/core@2.11.8: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - /@reduxjs/toolkit@2.0.0(react-redux@8.0.5)(react@18.2.0): + /@reduxjs/toolkit@2.0.0(react-redux@8.1.3)(react@18.2.0): resolution: {integrity: sha512-Kq/a+aO28adYdPoNEu9p800MYPKoUc0tlkYfv035Ief9J7MPq8JvmT7UdpYhvXsoMtOdt567KwZjc9H3Rf8yjg==} peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 @@ -2040,16 +3159,16 @@ packages: react-redux: optional: true dependencies: - immer: 10.0.4 + immer: 10.1.1 react: 18.2.0 - react-redux: 8.0.5(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + react-redux: 8.1.3(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) redux: 5.0.1 redux-thunk: 3.1.0(redux@5.0.1) - reselect: 5.0.1 + reselect: 5.1.0 dev: false - /@remix-run/router@1.15.3: - resolution: {integrity: sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==} + /@remix-run/router@1.16.1: + resolution: {integrity: sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==} engines: {node: '>=14.0.0'} dev: false @@ -2208,15 +3327,15 @@ packages: dependencies: '@sinonjs/commons': 3.0.1 - /@slate-yjs/core@1.0.2(slate@0.101.4)(yjs@13.6.14): + /@slate-yjs/core@1.0.2(slate@0.101.5)(yjs@13.6.15): resolution: {integrity: sha512-X0hLFJbQu9c1ItWBaNuEn0pqcXYK76KCp8C4Gvy/VaTQVMo1VgAb2WiiJ0Je/AyuIYEPPSTNVOcyrGHwgA7e6Q==} peerDependencies: slate: '>=0.70.0' yjs: ^13.5.29 dependencies: - slate: 0.101.4 - y-protocols: 1.0.6(yjs@13.6.14) - yjs: 13.6.14 + slate: 0.101.5 + y-protocols: 1.0.6(yjs@13.6.15) + yjs: 13.6.15 dev: false /@svgr/babel-plugin-add-jsx-attribute@7.0.0(@babel/core@7.24.3): @@ -2458,8 +3577,8 @@ packages: - typescript dev: true - /@tauri-apps/api@1.5.3: - resolution: {integrity: sha512-zxnDjHHKjOsrIzZm6nO5Xapb/BxqUq1tc7cGkFXsFkGTsSWgCPH1D8mm0XS9weJY2OaR73I3k3S+b7eSzJDfqA==} + /@tauri-apps/api@1.5.6: + resolution: {integrity: sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==} engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} dev: false @@ -2625,6 +3744,20 @@ packages: resolution: {integrity: sha512-p9eZ2X9B80iKiTW4ukVj8B4K6q9/+xFtQ5MGYA5HWToY9nL4EkhV9+6ftT2VHpVMEZb5Tv00Iel516bVdO+yRw==} dev: true + /@types/eslint-scope@3.7.7: + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + dependencies: + '@types/eslint': 8.56.10 + '@types/estree': 1.0.5 + dev: true + + /@types/eslint@8.56.10: + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + dev: true + /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -2789,8 +3922,8 @@ packages: redux: 4.2.1 dev: false - /@types/react-swipeable-views@0.13.4: - resolution: {integrity: sha512-hQV9Oq6oa+9HKdnGd43xkckElwf5dThOiegtQxqE7qX761oHhxnZO07fz6IsKSnUy9J3tzlRQBu3sNyvC8+kYw==} + /@types/react-swipeable-views@0.13.5: + resolution: {integrity: sha512-ni6WjO7gBq2xB2Y/ZiRdQOgjGOxIik5ow2s7xKieDq8DxsXTdV46jJslSBVK2yoIJHf6mG3uqNTwxwgzbXRRzg==} dependencies: '@types/react': 18.2.66 dev: false @@ -3038,11 +4171,125 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.3) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + vite: 5.2.0(@types/node@20.11.30)(sass@1.77.2) transitivePeerDependencies: - supports-color dev: true + /@webassemblyjs/ast@1.12.1: + resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + dev: true + + /@webassemblyjs/floating-point-hex-parser@1.11.6: + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + dev: true + + /@webassemblyjs/helper-api-error@1.11.6: + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + dev: true + + /@webassemblyjs/helper-buffer@1.12.1: + resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + dev: true + + /@webassemblyjs/helper-numbers@1.11.6: + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode@1.11.6: + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + dev: true + + /@webassemblyjs/helper-wasm-section@1.12.1: + resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.12.1 + dev: true + + /@webassemblyjs/ieee754@1.11.6: + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128@1.11.6: + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8@1.11.6: + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + dev: true + + /@webassemblyjs/wasm-edit@1.12.1: + resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-opt': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/wast-printer': 1.12.1 + dev: true + + /@webassemblyjs/wasm-gen@1.12.1: + resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wasm-opt@1.12.1: + resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + dev: true + + /@webassemblyjs/wasm-parser@1.12.1: + resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wast-printer@1.12.1: + resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@xtuc/long': 4.2.2 + dev: true + + /@xtuc/ieee754@1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long@4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead @@ -3055,6 +4302,14 @@ packages: acorn-walk: 8.3.2 dev: true + /acorn-import-assertions@1.9.0(acorn@8.11.3): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: true + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -3114,6 +4369,34 @@ packages: indent-string: 4.0.0 dev: true + /ajv-formats@2.1.1(ajv@8.14.0): + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.14.0 + dev: true + + /ajv-keywords@3.5.2(ajv@6.12.6): + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: 6.12.6 + dev: true + + /ajv-keywords@5.1.0(ajv@8.14.0): + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + dependencies: + ajv: 8.14.0 + fast-deep-equal: 3.1.3 + dev: true + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -3121,6 +4404,14 @@ packages: fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 + + /ajv@8.14.0: + resolution: {integrity: sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 dev: true /ansi-colors@4.1.3: @@ -3171,10 +4462,21 @@ packages: normalize-path: 3.0.0 picomatch: 2.3.1 + /append-transform@2.0.0: + resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} + engines: {node: '>=8'} + dependencies: + default-require-extensions: 3.0.1 + dev: true + /arch@2.2.0: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} dev: true + /archy@1.0.0: + resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + dev: true + /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true @@ -3265,12 +4567,10 @@ packages: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} dependencies: safer-buffer: 2.1.2 - dev: true /assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} - dev: true /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} @@ -3320,14 +4620,12 @@ packages: /aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: true /aws4@1.12.0: resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} - dev: true - /axios@1.6.8: - resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + /axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -3375,6 +4673,19 @@ packages: transitivePeerDependencies: - supports-color + /babel-loader@9.1.3(@babel/core@7.24.3)(webpack@5.91.0): + resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + dependencies: + '@babel/core': 7.24.3 + find-cache-dir: 4.0.0 + schema-utils: 4.2.0 + webpack: 5.91.0 + dev: true + /babel-plugin-import@1.13.8: resolution: {integrity: sha512-36babpjra5m3gca44V6tSTomeBlPA7cHUynrE2WiQIm3rEGD9xy28MKsx5IdO45EbnpJY7Jrgd00C6Dwt/l/2Q==} dependencies: @@ -3411,6 +4722,42 @@ packages: resolve: 1.22.8 dev: false + /babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.3): + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.24.6 + '@babel/core': 7.24.3 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.3) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.3) + core-js-compat: 3.37.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.3): + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.3) + transitivePeerDependencies: + - supports-color + dev: true + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.3): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: @@ -3457,20 +4804,23 @@ packages: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} dependencies: tweetnacl: 0.14.5 - dev: true /binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - /bind-event-listener@2.1.1: - resolution: {integrity: sha512-O+a5c0D2se/u2VlBJmPRn45IB6R4mYMh1ok3dWxrIZ2pmLqzggBhb875mbq73508ylzofc0+hT9W41x4Y2s8lg==} + /bind-event-listener@3.0.0: + resolution: {integrity: sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==} dev: false /blob-util@2.0.2: resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} dev: true + /bluebird@3.7.1: + resolution: {integrity: sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==} + dev: true + /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: true @@ -3544,6 +4894,16 @@ packages: engines: {node: '>=6'} dev: true + /caching-transform@4.0.0: + resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} + engines: {node: '>=8'} + dependencies: + hasha: 5.2.2 + make-dir: 3.1.0 + package-hash: 4.0.0 + write-file-atomic: 3.0.3 + dev: true + /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -3591,7 +4951,6 @@ packages: /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: true /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -3653,6 +5012,11 @@ packages: optionalDependencies: fsevents: 2.3.3 + /chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + dev: true + /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -3693,6 +5057,14 @@ packages: string-width: 4.2.3 dev: true + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -3701,6 +5073,15 @@ packages: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + /clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + /clone@2.1.2: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} @@ -3711,8 +5092,8 @@ packages: engines: {node: '>=6'} dev: false - /clsx@2.1.0: - resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} dev: false @@ -3744,12 +5125,23 @@ packages: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} dev: true + /colorthief@2.4.0: + resolution: {integrity: sha512-0U48RGNRo5fVO+yusBwgp+d3augWSorXabnqXUu9SabEhCpCgZJEUjUTTI41OOBBYuMMxawa3177POT6qLfLeQ==} + dependencies: + '@lokesh.dhakar/quantize': 1.3.0 + get-pixels: 3.3.3 + dev: false + /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + /commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -3764,11 +5156,19 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + /common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + dev: true + /common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} dev: true + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + /compute-scroll-into-view@3.1.0: resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==} dev: false @@ -3786,14 +5186,18 @@ packages: /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: false /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + /core-js-compat@3.37.1: + resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} + dependencies: + browserslist: 4.23.0 + dev: true + /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - dev: true /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3932,6 +5336,12 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /cwise-compiler@1.1.3: + resolution: {integrity: sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==} + dependencies: + uniq: 1.0.1 + dev: false + /cypress@13.7.2: resolution: {integrity: sha512-FF5hFI5wlRIHY8urLZjJjj/YvfCBrRpglbZCLr/cYcL9MdDe0+5usa8kTIrDHthlEc9lwihbkb5dmwqBDNS2yw==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} @@ -3987,7 +5397,10 @@ packages: engines: {node: '>=0.10'} dependencies: assert-plus: 1.0.0 - dev: true + + /data-uri-to-buffer@0.0.3: + resolution: {integrity: sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw==} + dev: false /data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} @@ -4035,6 +5448,10 @@ packages: dependencies: '@babel/runtime': 7.24.1 + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: true + /dayjs@1.11.9: resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==} @@ -4062,6 +5479,11 @@ packages: ms: 2.1.2 supports-color: 8.1.1 + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} @@ -4093,6 +5515,13 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + /default-require-extensions@3.0.1: + resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} + engines: {node: '>=8'} + dependencies: + strip-bom: 4.0.0 + dev: true + /define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -4127,14 +5556,6 @@ packages: engines: {node: '>=6'} dev: false - /derive-valtio@0.1.0(valtio@1.12.1): - resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} - peerDependencies: - valtio: '*' - dependencies: - valtio: 1.12.1(@types/react@18.2.66)(react@18.2.0) - dev: false - /detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -4273,7 +5694,6 @@ packages: dependencies: jsbn: 0.1.1 safer-buffer: 2.1.2 - dev: true /electron-to-chromium@1.4.722: resolution: {integrity: sha512-5nLE0TWFFpZ80Crhtp4pIp8LXCztjYX41yUcV6b+bKR2PqzjskTMOOlBi1VjBHlvHwS+4gar7kNKOrsbsewEZQ==} @@ -4282,12 +5702,12 @@ packages: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} - /emoji-mart@5.5.2: - resolution: {integrity: sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A==} + /emoji-mart@5.6.0: + resolution: {integrity: sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==} dev: false - /emoji-regex@10.2.1: - resolution: {integrity: sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==} + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} dev: false /emoji-regex@8.0.0: @@ -4303,6 +5723,14 @@ packages: once: 1.4.0 dev: true + /enhanced-resolve@5.16.1: + resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + /enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -4383,6 +5811,10 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + /es-module-lexer@1.5.3: + resolution: {integrity: sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==} + dev: true + /es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} @@ -4414,6 +5846,10 @@ packages: is-symbol: 1.0.4 dev: true + /es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + dev: true + /esbuild@0.20.2: resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} engines: {node: '>=12'} @@ -4513,6 +5949,14 @@ packages: string.prototype.matchall: 4.0.11 dev: true + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4526,6 +5970,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + /eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4573,6 +6022,15 @@ packages: - supports-color dev: true + /espree@10.0.1: + resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 4.0.0 + dev: true + /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4601,6 +6059,11 @@ packages: estraverse: 5.3.0 dev: true + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -4626,7 +6089,6 @@ packages: /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - dev: false /execa@4.1.0: resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} @@ -4698,11 +6160,9 @@ packages: /extsprintf@1.3.0: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} - dev: true /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true /fast-diff@1.1.2: resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==} @@ -4775,10 +6235,43 @@ packages: dependencies: to-regex-range: 5.0.1 + /find-cache-dir@2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + dev: true + + /find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + + /find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + dev: true + /find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} dev: false + /find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -4794,6 +6287,14 @@ packages: path-exists: 4.0.0 dev: true + /find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + dev: true + /flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -4823,6 +6324,14 @@ packages: is-callable: 1.2.7 dev: true + /foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 3.0.7 + dev: true + /foreground-child@3.1.1: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} @@ -4833,7 +6342,6 @@ packages: /forever-agent@0.6.1: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: true /form-data@2.3.3: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} @@ -4842,7 +6350,6 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: true /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} @@ -4856,6 +6363,10 @@ packages: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} dev: true + /fromentries@1.3.2: + resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} + dev: true + /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -4927,6 +6438,22 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + /get-pixels@3.3.3: + resolution: {integrity: sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==} + dependencies: + data-uri-to-buffer: 0.0.3 + jpeg-js: 0.4.4 + mime-types: 2.1.35 + ndarray: 1.0.19 + ndarray-pack: 1.2.1 + node-bitmap: 0.0.1 + omggif: 1.0.10 + parse-data-uri: 0.2.0 + pngjs: 3.4.0 + request: 2.88.2 + through: 2.3.8 + dev: false + /get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -4957,7 +6484,6 @@ packages: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} dependencies: assert-plus: 1.0.0 - dev: true /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -4972,6 +6498,10 @@ packages: is-glob: 4.0.3 dev: true + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + /glob@10.3.12: resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} engines: {node: '>=16 || 14 >=14.17'} @@ -5043,8 +6573,8 @@ packages: csstype: 3.1.3 dev: false - /google-protobuf@3.16.0: - resolution: {integrity: sha512-gBY66yYL1wbQMU2r1POkXSXkm035Ni0wFv3vx0K9IEUsJLP9G5rAcFVn0xUXfZneRu6MmDjaw93pt/DE56VOyw==} + /google-protobuf@3.21.2: + resolution: {integrity: sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==} dev: false /gopd@1.0.1: @@ -5071,6 +6601,20 @@ packages: through2: 2.0.5 dev: true + /har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + dev: false + + /har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: false + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true @@ -5102,6 +6646,14 @@ packages: dependencies: has-symbols: 1.0.3 + /hasha@5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + dev: true + /hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -5148,6 +6700,15 @@ packages: - supports-color dev: true + /http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + dev: false + /http-signature@1.3.6: resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} engines: {node: '>=0.10'} @@ -5176,20 +6737,20 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - /i18next-browser-languagedetector@7.0.1: - resolution: {integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==} + /i18next-browser-languagedetector@7.2.1: + resolution: {integrity: sha512-h/pM34bcH6tbz8WgGXcmWauNpQupCGr25XPp9cZwZInR9XHSjIFDYp1SIok7zSPsTOMxdvuLyu86V+g2Kycnfw==} dependencies: '@babel/runtime': 7.24.1 dev: false - /i18next-resources-to-backend@1.1.4: - resolution: {integrity: sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg==} + /i18next-resources-to-backend@1.2.1: + resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} dependencies: '@babel/runtime': 7.24.1 dev: false - /i18next@22.4.10: - resolution: {integrity: sha512-3EqgGK6fAJRjnGgfkNSStl4mYLCjUoJID338yVyLMj5APT67HUtWoqSayZewiiC5elzMUB1VEUwcmSCoeQcNEA==} + /i18next@22.5.1: + resolution: {integrity: sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==} dependencies: '@babel/runtime': 7.24.1 dev: false @@ -5210,12 +6771,12 @@ packages: engines: {node: '>= 4'} dev: true - /immer@10.0.4: - resolution: {integrity: sha512-cuBuGK40P/sk5IzWa9QPUaAdvPHjkk1c+xYsd9oZw+YQQEV+10G0P5uMpGctZZKnyQ+ibRO08bD25nWLmYi2pw==} + /immer@10.1.1: + resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} dev: false - /immutable@4.3.5: - resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + /immutable@4.3.6: + resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -5270,6 +6831,10 @@ packages: loose-envify: 1.4.0 dev: false + /iota-array@1.0.0: + resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} + dev: false + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -5309,6 +6874,10 @@ packages: has-tostringtag: 1.0.2 dev: true + /is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + dev: false + /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -5405,6 +6974,13 @@ packages: engines: {node: '>=8'} dev: true + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + /is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} @@ -5455,7 +7031,6 @@ packages: /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: true /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} @@ -5468,6 +7043,11 @@ packages: call-bind: 1.0.7 dev: true + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + /is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -5486,18 +7066,41 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + /isomorphic.js@0.2.5: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} dev: false /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: true /istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} + /istanbul-lib-hook@3.0.0: + resolution: {integrity: sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==} + engines: {node: '>=8'} + dependencies: + append-transform: 2.0.0 + dev: true + + /istanbul-lib-instrument@4.0.3: + resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.24.3 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-lib-instrument@5.2.1: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} @@ -5522,6 +7125,18 @@ packages: transitivePeerDependencies: - supports-color + /istanbul-lib-processinfo@2.0.3: + resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==} + engines: {node: '>=8'} + dependencies: + archy: 1.0.0 + cross-spawn: 7.0.3 + istanbul-lib-coverage: 3.2.2 + p-map: 3.0.0 + rimraf: 3.0.2 + uuid: 8.3.2 + dev: true + /istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} @@ -5934,6 +7549,15 @@ packages: jest-util: 29.7.0 string-length: 4.0.2 + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 20.11.30 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + /jest-worker@29.7.0: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5963,8 +7587,12 @@ packages: - supports-color - ts-node - /js-base64@3.7.5: - resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} + /jpeg-js@0.4.4: + resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} + dev: false + + /js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} dev: false /js-tokens@4.0.0: @@ -5986,7 +7614,6 @@ packages: /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: true /jsdom@20.0.3: resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} @@ -6029,6 +7656,11 @@ packages: - utf-8-validate dev: true + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -6043,11 +7675,13 @@ packages: /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: true /json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: true /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -6055,7 +7689,6 @@ packages: /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} @@ -6074,6 +7707,16 @@ packages: graceful-fs: 4.2.11 dev: true + /jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: false + /jsprim@2.0.2: resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} engines: {'0': node >=0.6.0} @@ -6094,8 +7737,8 @@ packages: object.values: 1.2.0 dev: true - /katex@0.16.7: - resolution: {integrity: sha512-Xk9C6oGKRwJTfqfIbtr0Kes9OSv6IFsuhFGc7tW4urlpMJtuh+7YhzU6YEG9n8gmWKcMAFzkp7nr+r69kV0zrA==} + /katex@0.16.10: + resolution: {integrity: sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==} hasBin: true dependencies: commander: 8.3.0 @@ -6111,6 +7754,11 @@ packages: json-buffer: 3.0.1 dev: true + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -6136,8 +7784,8 @@ packages: type-check: 0.4.0 dev: true - /lib0@0.2.93: - resolution: {integrity: sha512-M5IKsiFJYulS+8Eal8f+zAqf5ckm1vffW0fFDxfgxJ+uiVopvDdd3PxJmz0GsVi3YNO7QCFSq0nAsiDmNhLj9Q==} + /lib0@0.2.94: + resolution: {integrity: sha512-hZ3p54jL4Wpu7IOg26uC7dnEWiMyNlUrb9KoG7+xYs45WkQwpVvKFndVq2+pqLYKe1u8Fp3+zAfZHVvTK34PvQ==} engines: {node: '>=16'} hasBin: true dependencies: @@ -6172,6 +7820,19 @@ packages: wrap-ansi: 7.0.0 dev: true + /loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + dev: true + + /locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -6185,6 +7846,13 @@ packages: p-locate: 5.0.0 dev: true + /locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-locate: 6.0.0 + dev: true + /lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} dev: false @@ -6192,6 +7860,14 @@ packages: /lodash.clonedeep@4.5.0: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.flattendeep@4.4.0: + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + dev: true + /lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} @@ -6268,6 +7944,21 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.2 + dev: true + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.1 + dev: true + /make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -6389,8 +8080,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /nanoid@4.0.0: - resolution: {integrity: sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==} + /nanoid@4.0.2: + resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} engines: {node: ^14 || ^16 || >=18} hasBin: true dev: false @@ -6398,6 +8089,24 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + /ndarray-pack@1.2.1: + resolution: {integrity: sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g==} + dependencies: + cwise-compiler: 1.1.3 + ndarray: 1.0.19 + dev: false + + /ndarray@1.0.19: + resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==} + dependencies: + iota-array: 1.0.0 + is-buffer: 1.1.6 + dev: false + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + /no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: @@ -6405,9 +8114,21 @@ packages: tslib: 2.6.2 dev: true + /node-bitmap@0.0.1: + resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==} + engines: {node: '>=v0.6.5'} + dev: false + /node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + /node-preload@0.2.1: + resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} + engines: {node: '>=8'} + dependencies: + process-on-spawn: 1.0.0 + dev: true + /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} @@ -6440,6 +8161,46 @@ packages: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} dev: true + /nyc@15.1.0: + resolution: {integrity: sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==} + engines: {node: '>=8.9'} + hasBin: true + dependencies: + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + caching-transform: 4.0.0 + convert-source-map: 1.9.0 + decamelize: 1.2.0 + find-cache-dir: 3.3.2 + find-up: 4.1.0 + foreground-child: 2.0.0 + get-package-type: 0.1.0 + glob: 7.2.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-hook: 3.0.0 + istanbul-lib-instrument: 4.0.3 + istanbul-lib-processinfo: 2.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + make-dir: 3.1.0 + node-preload: 0.2.1 + p-map: 3.0.0 + process-on-spawn: 1.0.0 + resolve-from: 5.0.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + spawn-wrap: 2.0.0 + test-exclude: 6.0.0 + yargs: 15.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: false + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -6512,6 +8273,10 @@ packages: es-object-atoms: 1.0.0 dev: true + /omggif@1.0.10: + resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -6560,6 +8325,20 @@ packages: dependencies: yocto-queue: 0.1.0 + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + + /p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -6573,6 +8352,20 @@ packages: p-limit: 3.1.0 dev: true + /p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-limit: 4.0.0 + dev: true + + /p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + dependencies: + aggregate-error: 3.1.0 + dev: true + /p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} @@ -6584,6 +8377,16 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + /package-hash@4.0.0: + resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} + engines: {node: '>=8'} + dependencies: + graceful-fs: 4.2.11 + hasha: 5.2.2 + lodash.flattendeep: 4.4.0 + release-zalgo: 1.0.0 + dev: true + /pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} dev: true @@ -6604,6 +8407,12 @@ packages: dependencies: callsites: 3.1.0 + /parse-data-uri@0.2.0: + resolution: {integrity: sha512-uOtts8NqDcaCt1rIsO3VFDRsAfgE4c6osG4d9z3l4dCBlxYFzni6Di/oNU270SDrjkfZuUvLZx1rxMyqh46Y9w==} + dependencies: + data-uri-to-buffer: 0.0.3 + dev: false + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -6633,10 +8442,20 @@ packages: tslib: 2.6.2 dev: true + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + /path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -6687,16 +8506,40 @@ packages: engines: {node: '>=0.10.0'} dev: true + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + /pkg-dir@3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + dependencies: + find-up: 3.0.0 + dev: true + /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} dependencies: find-up: 4.1.0 + /pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + dependencies: + find-up: 6.3.0 + dev: true + + /pngjs@3.4.0: + resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} + engines: {node: '>=4.0.0'} + dev: false + /possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -6869,6 +8712,13 @@ packages: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true + /process-on-spawn@1.0.0: + resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} + engines: {node: '>=8'} + dependencies: + fromentries: 1.3.2 + dev: true + /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -6893,10 +8743,6 @@ packages: hasBin: true dev: false - /proxy-compare@2.5.1: - resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} - dev: false - /proxy-from-env@1.0.0: resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} dev: true @@ -6907,7 +8753,6 @@ packages: /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: true /pump@2.0.1: resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} @@ -6934,7 +8779,6 @@ packages: /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - dev: true /pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} @@ -6946,6 +8790,11 @@ packages: side-channel: 1.0.6 dev: true + /qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + dev: false + /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} dev: true @@ -7010,6 +8859,12 @@ packages: performance-now: 2.1.0 dev: false + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.1.2 + dev: true + /react-beautiful-dnd@13.1.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==} peerDependencies: @@ -7029,8 +8884,8 @@ packages: - react-native dev: false - /react-big-calendar@1.8.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-cra8WPfoTSQthFfqxi0k9xm/Shv5jWSw19LkNzpSJcnQhP6XGes/eJjd8P8g/iwaJjXIWPpg3+HB5wO5wabRyA==} + /react-big-calendar@1.12.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cPVcwH5V1YiC6QKaV4afvpuZ2DtP8+TocnZY98nGodqq8bfjVDiP3Ch+TewBZzj9mg7JbewHdufDZXZBqQl1lw==} peerDependencies: react: ^16.14.0 || ^17 || ^18 react-dom: ^16.14.0 || ^17 || ^18 @@ -7070,6 +8925,19 @@ packages: tinycolor2: 1.6.0 dev: false + /react-custom-scrollbars-2@4.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-/z0nWAeXfMDr4+OXReTpYd1Atq9kkn4oI3qxq3iMXGQx1EEfwETSqB8HTAvg1X7dEqcCachbny1DRNGlqX5bDQ==} + peerDependencies: + react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + dom-css: 2.1.0 + prop-types: 15.8.1 + raf: 3.4.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-custom-scrollbars@4.2.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-VtJTUvZ7kPh/auZWIbBRceGPkE30XBYe+HktFxuMWBR2eVQQ+Ur6yFJMoaYcNpyGq22uYJ9Wx4UAEcC0K+LNPQ==} peerDependencies: @@ -7083,8 +8951,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /react-datepicker@4.23.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-w+msqlOZ14v6H1UknTKtZw/dw9naFMgAOspf59eY130gWpvy5dvKj/bgsFICDdvxB7PtKWxDcbGlAqCloY1d2A==} + /react-datepicker@4.25.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-zB7CSi44SJ0sqo8hUQ3BF1saE/knn7u25qEMTO1CQGofY1VAKahO8k9drZtp0cfW1DMfoYLR3uSY1/uMvbEzbg==} peerDependencies: react: ^16.9.0 || ^17 || ^18 react-dom: ^16.9.0 || ^17 || ^18 @@ -7095,7 +8963,7 @@ packages: prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-onclickoutside: 6.13.0(react-dom@18.2.0)(react@18.2.0) + react-onclickoutside: 6.13.1(react-dom@18.2.0)(react@18.2.0) react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.2.0)(react@18.2.0) dev: false @@ -7145,8 +9013,8 @@ packages: - csstype dev: false - /react-i18next@14.1.0(i18next@22.4.10)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==} + /react-i18next@14.1.2(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -7160,7 +9028,7 @@ packages: dependencies: '@babel/runtime': 7.24.1 html-parse-stringify: 3.0.1 - i18next: 22.4.10 + i18next: 22.5.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -7181,7 +9049,7 @@ packages: prop-types: ^15.8.1 react: '>=15.3.2 <=18' dependencies: - katex: 0.16.7 + katex: 0.16.10 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -7196,7 +9064,7 @@ packages: react: '>0.13.0' react-dom: '>0.13.0' dependencies: - '@babel/runtime': 7.24.4 + '@babel/runtime': 7.24.1 get-node-dimensions: 1.2.1 prop-types: 15.8.1 react: 18.2.0 @@ -7204,8 +9072,8 @@ packages: resize-observer-polyfill: 1.5.1 dev: false - /react-onclickoutside@6.13.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==} + /react-onclickoutside@6.13.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-LdrrxK/Yh9zbBQdFbMTXPp3dTSN9B+9YJQucdDu3JNKRrbdU+H+/TVONJoWtOwy4II8Sqf1y/DTI6w/vGPYW0w==} peerDependencies: react: ^15.5.x || ^16.x || ^17.x || ^18.x react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x @@ -7267,15 +9135,15 @@ packages: react-is: 17.0.2 dev: false - /react-redux@8.0.5(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): - resolution: {integrity: sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==} + /react-redux@8.1.3(@types/react-dom@18.2.22)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): + resolution: {integrity: sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==} peerDependencies: '@types/react': ^16.8 || ^17.0 || ^18.0 '@types/react-dom': ^16.8 || ^17.0 || ^18.0 react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 react-native: '>=0.59' - redux: ^4 + redux: ^4 || ^5.0.0-beta.0 peerDependenciesMeta: '@types/react': optional: true @@ -7298,7 +9166,7 @@ packages: react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 redux: 4.2.1 - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.2.0) dev: false /react-refresh@0.14.0: @@ -7306,26 +9174,26 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom@6.22.3(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==} + /react-router-dom@6.23.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.15.3 + '@remix-run/router': 1.16.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.22.3(react@18.2.0) + react-router: 6.23.1(react@18.2.0) dev: false - /react-router@6.22.3(react@18.2.0): - resolution: {integrity: sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==} + /react-router@6.23.1(react@18.2.0): + resolution: {integrity: sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.15.3 + '@remix-run/router': 1.16.1 react: 18.2.0 dev: false @@ -7379,11 +9247,11 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /react-virtualized-auto-sizer@1.0.20(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-OdIyHwj4S4wyhbKHOKM1wLSj/UDXm839Z3Cvfg2a9j+He6yDa6i5p0qQvEiCnyQlGO/HyfSnigQwuxvYalaAXA==} + /react-virtualized-auto-sizer@1.0.24(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3kCn7N9NEb3FlvJrSHWGQ4iVl+ydQObq2fHMn12i5wbtm74zHOPhz/i64OL3c1S1vi9i2GXtZqNqUJTQ+BnNfg==} peerDependencies: - react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc - react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -7417,8 +9285,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /react18-input-otp@1.1.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-E21NiPh/KH67Bq/uEAm78E8H+croiGAyX5WcXfX49qh0im1iKrk/3RCKCTESG6WUoJYyh/fj5JY0UrHm+Mm0eQ==} + /react18-input-otp@1.1.4(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-35xvmTeuPWIxd0Z0Opx4z3OoMaTmKN4ubirQCx1YMZiNoe+2h1hsOSUco4aKPlGXWZCtXrfOFieAh46vqiK9mA==} peerDependencies: react: 16.2.0 - 18 react-dom: 16.2.0 - 18 @@ -7484,6 +9352,17 @@ packages: resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} dev: false + /regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + /regenerator-runtime@0.12.1: resolution: {integrity: sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==} dev: false @@ -7491,6 +9370,12 @@ packages: /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.24.6 + dev: true + /regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -7500,22 +9385,84 @@ packages: es-errors: 1.3.0 set-function-name: 2.0.2 + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /release-zalgo@1.0.0: + resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} + engines: {node: '>=4'} + dependencies: + es6-error: 4.1.1 + dev: true + /request-progress@3.0.0: resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} dependencies: throttleit: 1.0.1 dev: true + /request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.1.2 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: false + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: true - /reselect@5.0.1: - resolution: {integrity: sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==} + /reselect@5.1.0: + resolution: {integrity: sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==} dev: false /resize-observer-polyfill@1.5.1: @@ -7656,7 +9603,6 @@ packages: /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true /safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} @@ -7669,15 +9615,14 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true - /sass@1.70.0: - resolution: {integrity: sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==} + /sass@1.77.2: + resolution: {integrity: sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==} engines: {node: '>=14.0.0'} hasBin: true dependencies: chokidar: 3.6.0 - immutable: 4.3.5 + immutable: 4.3.6 source-map-js: 1.2.0 /saxes@6.0.0: @@ -7692,12 +9637,36 @@ packages: dependencies: loose-envify: 1.4.0 + /schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + dev: true + + /schema-utils@4.2.0: + resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} + engines: {node: '>= 12.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.14.0 + ajv-formats: 2.1.1(ajv@8.14.0) + ajv-keywords: 5.1.0(ajv@8.14.0) + dev: true + /scroll-into-view-if-needed@3.1.0: resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} dependencies: compute-scroll-into-view: 3.1.0 dev: false + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -7717,6 +9686,16 @@ packages: upper-case-first: 2.0.2 dev: true + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + /set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -7737,6 +9716,13 @@ packages: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + /shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + /shallow-equal@1.2.1: resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} dev: false @@ -7785,17 +9771,17 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - /slate-history@0.100.0(slate@0.101.4): + /slate-history@0.100.0(slate@0.101.5): resolution: {integrity: sha512-x5rUuWLNtH97hs9PrFovGgt3Qc5zkTm/5mcUB+0NR/TK923eLax4HsL6xACLHMs245nI6aJElyM1y6hN0y5W/Q==} peerDependencies: slate: '>=0.65.3' dependencies: is-plain-object: 5.0.0 - slate: 0.101.4 + slate: 0.101.5 dev: false - /slate-react@0.101.3(react-dom@18.2.0)(react@18.2.0)(slate@0.101.4): - resolution: {integrity: sha512-KMXK9FLeS7HYhhoVcI8SUi4Qp1I9C1lTQ2EgbPH95sVXfH/vq+hbhurEGIGCe0VQ9Opj4rSKJIv/g7De1+nJMA==} + /slate-react@0.101.6(react-dom@18.2.0)(react@18.2.0)(slate@0.101.5): + resolution: {integrity: sha512-aMtp9FY127hKWTkCcTBonfKIwKJC2ESPqFdw2o/RuOk3RMQRwsWay8XTOHx8OBGOHanI2fsKaTAPF5zxOLA1Qg==} peerDependencies: react: '>=18.2.0' react-dom: '>=18.2.0' @@ -7811,14 +9797,14 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) scroll-into-view-if-needed: 3.1.0 - slate: 0.101.4 + slate: 0.101.5 tiny-invariant: 1.3.1 dev: false - /slate@0.101.4: - resolution: {integrity: sha512-8LazZrNDsYFKDg1wpb0HouAfX5Pw/UmOZ/vIrtqD2GSCDZvraOkV2nVJ9Ery8kIlsU1jeybwgcaCy4KkVwfvEg==} + /slate@0.101.5: + resolution: {integrity: sha512-ZZt1ia8ayRqxtpILRMi2a4MfdvwdTu64CorxTVq9vNSd0GQ/t3YDkze6wKjdeUtENmBlq5wNIDInZbx38Hfu5Q==} dependencies: - immer: 10.0.4 + immer: 10.1.1 is-plain-object: 5.0.0 tiny-warning: 1.0.3 dev: false @@ -7841,6 +9827,12 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /smooth-scroll-into-view-if-needed@2.0.2: + resolution: {integrity: sha512-z54WzUSlM+xHHvJu3lMIsh+1d1kA4vaakcAtQvqzeGJ5Ffau7EKjpRrMHh1/OBo5zyU2h30ZYEt77vWmPHqg7Q==} + dependencies: + scroll-into-view-if-needed: 3.1.0 + dev: false + /snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} dependencies: @@ -7879,6 +9871,18 @@ packages: engines: {node: '>= 8'} dev: true + /spawn-wrap@2.0.0: + resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} + engines: {node: '>=8'} + dependencies: + foreground-child: 2.0.0 + is-windows: 1.0.2 + make-dir: 3.1.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + which: 2.0.2 + dev: true + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -7896,7 +9900,6 @@ packages: jsbn: 0.1.1 safer-buffer: 2.1.2 tweetnacl: 0.14.5 - dev: true /stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} @@ -8125,6 +10128,11 @@ packages: - ts-node dev: true + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + /tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} dependencies: @@ -8133,6 +10141,41 @@ packages: streamx: 2.16.1 dev: true + /terser-webpack-plugin@5.3.10(webpack@5.91.0): + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.2 + terser: 5.31.0 + webpack: 5.91.0 + dev: true + + /terser@5.31.0: + resolution: {integrity: sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.11.3 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + /test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -8158,7 +10201,6 @@ packages: /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true /tiny-invariant@1.3.1: resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} @@ -8214,6 +10256,14 @@ packages: engines: {node: '>=6'} dev: true + /tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + dev: false + /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} @@ -8363,11 +10413,9 @@ packages: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.1.2 - dev: true /tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: true /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -8389,6 +10437,11 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + /typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -8433,6 +10486,12 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: true + /typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} @@ -8467,6 +10526,33 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /uniq@1.0.1: + resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==} + dev: false + /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -8513,7 +10599,6 @@ packages: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.1 - dev: true /url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} @@ -8530,8 +10615,8 @@ packages: react: 18.2.0 dev: false - /use-sync-external-store@1.2.0(react@18.2.0): - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + /use-sync-external-store@1.2.2(react@18.2.0): + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: @@ -8546,6 +10631,12 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: false + /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -8568,30 +10659,11 @@ packages: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - /validator@13.11.0: - resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + /validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} engines: {node: '>= 0.10'} dev: false - /valtio@1.12.1(@types/react@18.2.66)(react@18.2.0): - resolution: {integrity: sha512-R0V4H86Xi2Pp7pmxN/EtV4Q6jr6PMN3t1IwxEvKUp6160r8FimvPh941oWyeK1iec/DTsh9Jb3Q+GputMS8SYg==} - engines: {node: '>=12.20.0'} - peerDependencies: - '@types/react': '>=16.8' - react: '>=16.8' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - dependencies: - '@types/react': 18.2.66 - derive-valtio: 0.1.0(valtio@1.12.1) - proxy-compare: 2.5.1 - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) - dev: false - /verror@1.10.0: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} @@ -8599,7 +10671,6 @@ packages: assert-plus: 1.0.0 core-util-is: 1.0.2 extsprintf: 1.3.0 - dev: true /vite-plugin-compression2@1.0.0: resolution: {integrity: sha512-42XNp6FjxE0JIecxj1fdi770pLhYm3MJhBUAod9EszTgDg9C4LDOgBzWcj/0K52KfJrpRXwUsWV6kqTDuoCfLA==} @@ -8621,6 +10692,22 @@ packages: - supports-color dev: true + /vite-plugin-istanbul@6.0.2(vite@5.2.0): + resolution: {integrity: sha512-0/sKwjEEIwbEyl43xX7onX3dIbMJAsigNsKyyVPalG1oRFo5jn3qkJbS2PUfp9wrr3piy1eT6qRoeeum2p4B2A==} + peerDependencies: + vite: '>=4 <=6' + dependencies: + '@istanbuljs/load-nyc-config': 1.1.0 + espree: 10.0.1 + istanbul-lib-instrument: 6.0.2 + picocolors: 1.0.0 + source-map: 0.7.4 + test-exclude: 6.0.0 + vite: 5.2.0(@types/node@20.11.30)(sass@1.77.2) + transitivePeerDependencies: + - supports-color + dev: true + /vite-plugin-svgr@3.2.0(typescript@4.9.5)(vite@5.2.0): resolution: {integrity: sha512-Uvq6niTvhqJU6ga78qLKBFJSDvxWhOnyfQSoKpDPMAGxJPo5S3+9hyjExE5YDj6Lpa4uaLkGc1cBgxXov+LjSw==} peerDependencies: @@ -8629,7 +10716,7 @@ packages: '@rollup/pluginutils': 5.1.0 '@svgr/core': 7.0.0(typescript@4.9.5) '@svgr/plugin-jsx': 7.0.0 - vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + vite: 5.2.0(@types/node@20.11.30)(sass@1.77.2) transitivePeerDependencies: - rollup - supports-color @@ -8647,7 +10734,7 @@ packages: kolorist: 1.8.0 sirv: 2.0.4 ufo: 1.5.3 - vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + vite: 5.2.0(@types/node@20.11.30)(sass@1.77.2) transitivePeerDependencies: - rollup - supports-color @@ -8659,7 +10746,7 @@ packages: vite: '>=5.0.0' dependencies: chalk: 5.3.0 - vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + vite: 5.2.0(@types/node@20.11.30)(sass@1.77.2) dev: true /vite-plugin-wasm@3.3.0(vite@5.2.0): @@ -8667,10 +10754,10 @@ packages: peerDependencies: vite: ^2 || ^3 || ^4 || ^5 dependencies: - vite: 5.2.0(@types/node@20.11.30)(sass@1.70.0) + vite: 5.2.0(@types/node@20.11.30)(sass@1.77.2) dev: false - /vite@5.2.0(@types/node@20.11.30)(sass@1.70.0): + /vite@5.2.0(@types/node@20.11.30)(sass@1.77.2): resolution: {integrity: sha512-xMSLJNEjNk/3DJRgWlPADDwaU9AgYRodDH2t6oENhJnIlmU9Hx1Q6VpjyXua/JdMw1WJRbnAgHJ9xgET9gnIAg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -8702,7 +10789,7 @@ packages: esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.13.2 - sass: 1.70.0 + sass: 1.77.2 optionalDependencies: fsevents: 2.3.3 @@ -8728,11 +10815,64 @@ packages: dependencies: loose-envify: 1.4.0 + /watchpack@2.4.1: + resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + dev: true + /webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} dev: true + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack@5.91.0: + resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.5 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/wasm-edit': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + browserslist: 4.23.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.16.1 + es-module-lexer: 1.5.3 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.10(webpack@5.91.0) + watchpack: 2.4.1 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + /whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} @@ -8763,6 +10903,10 @@ packages: is-symbol: 1.0.4 dev: true + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + /which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -8810,6 +10954,15 @@ packages: /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + /write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: true + /write-file-atomic@4.0.2: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -8844,26 +10997,30 @@ packages: engines: {node: '>=0.4'} dev: true - /y-indexeddb@9.0.12(yjs@13.6.14): + /y-indexeddb@9.0.12(yjs@13.6.15): resolution: {integrity: sha512-9oCFRSPPzBK7/w5vOkJBaVCQZKHXB/v6SIT+WYhnJxlEC61juqG0hBrAf+y3gmSMLFLwICNH9nQ53uscuse6Hg==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} peerDependencies: yjs: ^13.0.0 dependencies: - lib0: 0.2.93 - yjs: 13.6.14 + lib0: 0.2.94 + yjs: 13.6.15 dev: false - /y-protocols@1.0.6(yjs@13.6.14): + /y-protocols@1.0.6(yjs@13.6.15): resolution: {integrity: sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} peerDependencies: yjs: ^13.0.0 dependencies: - lib0: 0.2.93 - yjs: 13.6.14 + lib0: 0.2.94 + yjs: 13.6.15 dev: false + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -8878,10 +11035,35 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -8901,11 +11083,11 @@ packages: fd-slicer: 1.1.0 dev: true - /yjs@13.6.14: - resolution: {integrity: sha512-D+7KcUr0j+vBCUSKXXEWfA+bG4UQBviAwP3gYBhkstkgwy5+8diOPMx0iqLIOxNo/HxaREUimZRxqHGAHCL2BQ==} + /yjs@13.6.15: + resolution: {integrity: sha512-moFv4uNYhp8BFxIk3AkpoAnnjts7gwdpiG8RtyFiKbMtxKCS0zVZ5wPaaGpwC3V2N/K8TK8MwtSI3+WO9CHWjQ==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} dependencies: - lib0: 0.2.93 + lib0: 0.2.94 dev: false /yn@3.1.1: @@ -8916,3 +11098,12 @@ packages: /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false diff --git a/frontend/appflowy_web_app/scripts/generateTailwindColors.cjs b/frontend/appflowy_web_app/scripts/generateTailwindColors.cjs new file mode 100644 index 0000000000..83f5bb25d5 --- /dev/null +++ b/frontend/appflowy_web_app/scripts/generateTailwindColors.cjs @@ -0,0 +1,61 @@ +const fs = require('fs'); +const path = require('path'); + +// Read CSS file +const cssFilePath = path.join(__dirname, '../src/styles/variables/light.variables.css'); +const cssContent = fs.readFileSync(cssFilePath, 'utf-8'); + +// Extract color variables +const shadowVariables = cssContent.match(/--shadow:\s.*;/g); +const colorVariables = cssContent.match(/--[\w-]+:\s*#[0-9a-fA-F]{6}/g); + +if (!colorVariables) { + console.error('No color variables found in CSS file.'); + process.exit(1); +} + +const shadows = shadowVariables.reduce((shadows, variable) => { + const [name, value] = variable.split(':').map(str => str.trim()); + const formattedName = name.replace('--', '').replace(/-/g, '_'); + const key = 'md'; + + shadows[key] = `var(${name})`; + return shadows; +}, {}); +// Generate Tailwind CSS colors configuration +// Replace -- with _ and - with _ in color variable names +const tailwindColors = colorVariables.reduce((colors, variable) => { + const [name, value] = variable.split(':').map(str => str.trim()); + const formattedName = name.replace('--', '').replace(/-/g, '_'); + const category = formattedName.split('_')[0]; + const key = formattedName.replace(`${category}_`, ''); + + if (!colors[category]) { + colors[category] = {}; + } + colors[category][key] = `var(${name})`; + return colors; +}, {}); + +const tailwindColorsFormatted = JSON.stringify(tailwindColors, null, 2) + .replace(/_/g, '-'); +const header = `/**\n` + '* Do not edit directly\n' + `* Generated on ${new Date().toUTCString()}\n` + `* Generated from $pnpm css:variables \n` + `*/\n\n`; + +// Write Tailwind CSS colors configuration to file +const tailwindColorTemplate = ` +${header} +module.exports = ${tailwindColorsFormatted}; +`; + +const tailwindShadowTemplate = ` +${header} +module.exports = ${JSON.stringify(shadows, null, 2).replace(/_/g, '-')}; +`; + +const tailwindConfigFilePath = path.join(__dirname, '../tailwind/colors.cjs'); +fs.writeFileSync(tailwindConfigFilePath, tailwindColorTemplate, 'utf-8'); + +const tailwindShadowFilePath = path.join(__dirname, '../tailwind/box-shadow.cjs'); +fs.writeFileSync(tailwindShadowFilePath, tailwindShadowTemplate, 'utf-8'); + +console.log('Tailwind CSS colors configuration generated successfully.'); diff --git a/frontend/appflowy_web_app/scripts/merge-coverage.cjs b/frontend/appflowy_web_app/scripts/merge-coverage.cjs new file mode 100644 index 0000000000..f059048a0f --- /dev/null +++ b/frontend/appflowy_web_app/scripts/merge-coverage.cjs @@ -0,0 +1,31 @@ +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); +const jestCoverageFile = path.join(__dirname, '../coverage/jest/coverage-final.json'); +const cypressCoverageFile = path.join(__dirname, '../coverage/cypress/coverage-final.json'); +// const cypressComponentCoverageFile = path.join(__dirname, '../coverage/cypress-component/coverage-final.json'); +const nycOutputDir = path.join(__dirname, '../coverage/.nyc_output'); +// Ensure .nyc_output directory exists +if (!fs.existsSync(nycOutputDir)) { + fs.mkdirSync(nycOutputDir, { recursive: true }); +} +// Copy Jest coverage file +fs.copyFileSync(jestCoverageFile, path.join(nycOutputDir, 'jest-coverage.json')); +// Copy Cypress E2E coverage file +fs.copyFileSync(cypressCoverageFile, path.join(nycOutputDir, 'cypress-coverage.json')); +// Copy Cypress Component coverage file +// fs.copyFileSync(cypressComponentCoverageFile, path.join(nycOutputDir, 'cypress-component-coverage.json')); +// Merge coverage files +execSync('nyc merge ./coverage/.nyc_output ./coverage/merged/coverage-final.json', { stdio: 'inherit' }); +// Generate final merged report +execSync('nyc report --reporter=html --reporter=text-summary --report-dir=coverage/merged --temp-dir=coverage/.nyc_output', { stdio: 'inherit' }); +console.log(`Merged coverage report written to coverage/merged`); + +const GITHUB_STEP_SUMMARY = process.env.GITHUB_STEP_SUMMARY; + +if (GITHUB_STEP_SUMMARY) { + const coverageSummary = execSync('nyc report --reporter=html --reporter=text-summary --report-dir=coverage/merged --temp-dir=coverage/.nyc_output').toString(); + + fs.appendFileSync(GITHUB_STEP_SUMMARY, `### Coverage Report\n\`\`\`\n${coverageSummary}\n\`\`\`\n`); +} + diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index 2bb44433ed..23252b551c 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -153,7 +153,7 @@ checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "bincode", @@ -170,12 +170,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "appflowy-ai-client" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "bytes", + "futures", + "serde", + "serde_json", + "serde_repr", + "thiserror", +] + [[package]] name = "appflowy_tauri" version = "0.0.0" dependencies = [ "bytes", "dotenv", + "flowy-chat", "flowy-config", "flowy-core", "flowy-date", @@ -184,6 +199,7 @@ dependencies = [ "flowy-notification", "flowy-user", "lib-dispatch", + "semver", "serde", "serde_json", "tauri", @@ -714,7 +730,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "again", "anyhow", @@ -744,6 +760,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", + "serde_urlencoded", "shared-entity", "thiserror", "tokio", @@ -760,7 +777,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "futures-channel", "futures-util", @@ -843,7 +860,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -867,7 +884,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -897,7 +914,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -916,7 +933,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "bytes", @@ -931,7 +948,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "chrono", @@ -969,7 +986,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-stream", @@ -1008,7 +1025,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "bincode", @@ -1033,7 +1050,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "async-trait", @@ -1050,7 +1067,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -1283,7 +1300,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.10", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1394,7 +1411,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", @@ -1493,6 +1510,7 @@ dependencies = [ "diesel_derives", "libsqlite3-sys", "r2d2", + "serde_json", "time", ] @@ -1831,6 +1849,39 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "flowy-chat" +version = "0.1.0" +dependencies = [ + "bytes", + "dashmap", + "flowy-chat-pub", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-notification", + "flowy-sqlite", + "futures", + "lib-dispatch", + "lib-infra", + "protobuf", + "strum_macros 0.21.1", + "tokio", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "flowy-chat-pub" +version = "0.1.0" +dependencies = [ + "client-api", + "flowy-error", + "futures", + "lib-infra", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -1882,6 +1933,8 @@ dependencies = [ "collab-integrate", "collab-plugins", "diesel", + "flowy-chat", + "flowy-chat-pub", "flowy-config", "flowy-database-pub", "flowy-database2", @@ -2212,6 +2265,7 @@ dependencies = [ "collab-entity", "collab-folder", "collab-plugins", + "flowy-chat-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -2232,6 +2286,7 @@ dependencies = [ "postgrest", "rand 0.8.5", "reqwest", + "semver", "serde", "serde_json", "thiserror", @@ -2851,7 +2906,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "futures-util", @@ -2868,7 +2923,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", @@ -3305,7 +3360,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "reqwest", @@ -4810,7 +4865,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.11.0", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -4831,7 +4886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.55", @@ -5616,27 +5671,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", @@ -5809,13 +5864,15 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ef96b42e43c7b929a928f6c334967c7edffc1319#ef96b42e43c7b929a928f6c334967c7edffc1319" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "app-error", + "appflowy-ai-client", "chrono", "collab-entity", "database-entity", + "futures", "gotrue-entity", "reqwest", "serde", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index 54e09acf6c..9db2fea415 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -20,7 +20,7 @@ bytes = "1.5.0" serde = "1.0" serde_json = "1.0.108" protobuf = { version = "2.28.0" } -diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } +diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2", "serde_json"] } uuid = { version = "1.5.0", features = ["serde", "v4"] } serde_repr = "0.1" parking_lot = "0.12" @@ -52,7 +52,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ef96b42e43c7b929a928f6c334967c7edffc1319" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } [dependencies] serde_json.workspace = true @@ -89,6 +89,9 @@ flowy-document = { path = "../../rust-lib/flowy-document", features = [ flowy-notification = { path = "../../rust-lib/flowy-notification", features = [ "tauri_ts", ] } +flowy-chat = { path = "../../rust-lib/flowy-chat", features = [ + "tauri_ts", +] } uuid = "1.5.0" tauri-plugin-deep-link = "0.1.2" @@ -104,10 +107,10 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } \ No newline at end of file +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/collab.type.ts b/frontend/appflowy_web_app/src/application/collab.type.ts index affc19e921..4f61246aab 100644 --- a/frontend/appflowy_web_app/src/application/collab.type.ts +++ b/frontend/appflowy_web_app/src/application/collab.type.ts @@ -138,15 +138,15 @@ export interface FolderMeta { current_workspace: string; } -export enum CoverType { +export enum DocCoverType { Color = 'CoverType.color', Image = 'CoverType.file', Asset = 'CoverType.asset', } -export type PageCover = { +export type DocCover = { image_type?: ImageType; - cover_selection_type?: CoverType; + cover_selection_type?: DocCoverType; cover_selection?: string; } | null; @@ -166,6 +166,7 @@ export enum YjsEditorKey { // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values database_row = 'data', user_awareness = 'user_awareness', + empty = 'empty', // document blocks = 'blocks', @@ -199,6 +200,10 @@ export enum YjsFolderKey { id = 'id', name = 'name', icon = 'icon', + extra = 'extra', + cover = 'cover', + line_height_layout = 'line_height_layout', + font_layout = 'font_layout', type = 'ty', value = 'value', layout = 'layout', @@ -337,7 +342,7 @@ export interface YView extends Y.Map { get(key: YjsFolderKey.name): string; // eslint-disable-next-line @typescript-eslint/unified-signatures - get(key: YjsFolderKey.icon): string; + get(key: YjsFolderKey.icon | YjsFolderKey.extra): string; // eslint-disable-next-line @typescript-eslint/unified-signatures get(key: YjsFolderKey.layout): string; @@ -607,3 +612,15 @@ export const databaseLayoutMap = { [DatabaseViewLayout.Board]: 'board', [DatabaseViewLayout.Calendar]: 'calendar', }; + +export enum FontLayout { + small = 'small', + normal = 'normal', + large = 'large', +} + +export enum LineHeightLayout { + small = 'small', + normal = 'normal', + large = 'large', +} diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/filter.test.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/filter.test.ts new file mode 100644 index 0000000000..5b2ed3d37e --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/filter.test.ts @@ -0,0 +1,661 @@ +import { + NumberFilterCondition, + TextFilterCondition, + CheckboxFilterCondition, + ChecklistFilterCondition, + SelectOptionFilterCondition, + Row, +} from '@/application/database-yjs'; +import { withTestingData } from '@/application/database-yjs/__tests__/withTestingData'; +import { + withCheckboxFilter, + withChecklistFilter, + withDateTimeFilter, + withMultiSelectOptionFilter, + withNumberFilter, + withRichTextFilter, + withSingleSelectOptionFilter, + withUrlFilter, +} from '@/application/database-yjs/__tests__/withTestingFilters'; +import { withTestingRows } from '@/application/database-yjs/__tests__/withTestingRows'; +import { + textFilterCheck, + numberFilterCheck, + checkboxFilterCheck, + checklistFilterCheck, + selectOptionFilterCheck, + filterBy, +} from '../filter'; +import { expect } from '@jest/globals'; + +describe('Text filter check', () => { + const text = 'Hello, world!'; + it('should return true for TextIs condition', () => { + const condition = TextFilterCondition.TextIs; + const content = 'Hello, world!'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for TextIs condition', () => { + const condition = TextFilterCondition.TextIs; + const content = 'Hello, world'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for TextIsNot condition', () => { + const condition = TextFilterCondition.TextIsNot; + const content = 'Hello, world'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for TextIsNot condition', () => { + const condition = TextFilterCondition.TextIsNot; + const content = 'Hello, world!'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for TextContains condition', () => { + const condition = TextFilterCondition.TextContains; + const content = 'world'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for TextContains condition', () => { + const condition = TextFilterCondition.TextContains; + const content = 'planet'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for TextDoesNotContain condition', () => { + const condition = TextFilterCondition.TextDoesNotContain; + const content = 'planet'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for TextDoesNotContain condition', () => { + const condition = TextFilterCondition.TextDoesNotContain; + const content = 'world'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for TextIsEmpty condition', () => { + const condition = TextFilterCondition.TextIsEmpty; + const text = ''; + + const result = textFilterCheck(text, '', condition); + + expect(result).toBe(true); + }); + + it('should return false for TextIsEmpty condition', () => { + const condition = TextFilterCondition.TextIsEmpty; + const text = 'Hello, world!'; + + const result = textFilterCheck(text, '', condition); + + expect(result).toBe(false); + }); + + it('should return true for TextIsNotEmpty condition', () => { + const condition = TextFilterCondition.TextIsNotEmpty; + const text = 'Hello, world!'; + + const result = textFilterCheck(text, '', condition); + + expect(result).toBe(true); + }); + + it('should return false for TextIsNotEmpty condition', () => { + const condition = TextFilterCondition.TextIsNotEmpty; + const text = ''; + + const result = textFilterCheck(text, '', condition); + + expect(result).toBe(false); + }); + + it('should return false for unknown condition', () => { + const condition = 42; + const content = 'Hello, world!'; + + const result = textFilterCheck(text, content, condition); + + expect(result).toBe(false); + }); +}); + +describe('Number filter check', () => { + const num = '42'; + it('should return true for Equal condition', () => { + const condition = NumberFilterCondition.Equal; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for Equal condition', () => { + const condition = NumberFilterCondition.Equal; + const content = '43'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for NotEqual condition', () => { + const condition = NumberFilterCondition.NotEqual; + const content = '43'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for NotEqual condition', () => { + const condition = NumberFilterCondition.NotEqual; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for GreaterThan condition', () => { + const condition = NumberFilterCondition.GreaterThan; + const content = '41'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for GreaterThan condition', () => { + const condition = NumberFilterCondition.GreaterThan; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for GreaterThanOrEqualTo condition', () => { + const condition = NumberFilterCondition.GreaterThanOrEqualTo; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for GreaterThanOrEqualTo condition', () => { + const condition = NumberFilterCondition.GreaterThanOrEqualTo; + const content = '43'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for LessThan condition', () => { + const condition = NumberFilterCondition.LessThan; + const content = '43'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for LessThan condition', () => { + const condition = NumberFilterCondition.LessThan; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for LessThanOrEqualTo condition', () => { + const condition = NumberFilterCondition.LessThanOrEqualTo; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for LessThanOrEqualTo condition', () => { + const condition = NumberFilterCondition.LessThanOrEqualTo; + const content = '41'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for NumberIsEmpty condition', () => { + const condition = NumberFilterCondition.NumberIsEmpty; + + const result = numberFilterCheck('', '', condition); + + expect(result).toBe(true); + }); + + it('should return false for NumberIsEmpty condition', () => { + const condition = NumberFilterCondition.NumberIsEmpty; + const num = '42'; + + const result = numberFilterCheck(num, '', condition); + + expect(result).toBe(false); + }); + + it('should return true for NumberIsNotEmpty condition', () => { + const condition = NumberFilterCondition.NumberIsNotEmpty; + const num = '42'; + + const result = numberFilterCheck(num, '', condition); + + expect(result).toBe(true); + }); + + it('should return false for NumberIsNotEmpty condition', () => { + const condition = NumberFilterCondition.NumberIsNotEmpty; + const num = ''; + + const result = numberFilterCheck(num, '', condition); + + expect(result).toBe(false); + }); + + it('should return false for unknown condition', () => { + const condition = 42; + const content = '42'; + + const result = numberFilterCheck(num, content, condition); + + expect(result).toBe(false); + }); +}); + +describe('Checkbox filter check', () => { + it('should return true for IsChecked condition', () => { + const condition = CheckboxFilterCondition.IsChecked; + const data = 'Yes'; + + const result = checkboxFilterCheck(data, condition); + + expect(result).toBe(true); + }); + + it('should return false for IsChecked condition', () => { + const condition = CheckboxFilterCondition.IsChecked; + const data = 'No'; + + const result = checkboxFilterCheck(data, condition); + + expect(result).toBe(false); + }); + + it('should return true for IsUnChecked condition', () => { + const condition = CheckboxFilterCondition.IsUnChecked; + const data = 'No'; + + const result = checkboxFilterCheck(data, condition); + + expect(result).toBe(true); + }); + + it('should return false for IsUnChecked condition', () => { + const condition = CheckboxFilterCondition.IsUnChecked; + const data = 'Yes'; + + const result = checkboxFilterCheck(data, condition); + + expect(result).toBe(false); + }); + + it('should return false for unknown condition', () => { + const condition = 42; + const data = 'Yes'; + + const result = checkboxFilterCheck(data, condition); + + expect(result).toBe(false); + }); +}); + +describe('Checklist filter check', () => { + it('should return true for IsComplete condition', () => { + const condition = ChecklistFilterCondition.IsComplete; + const data = JSON.stringify({ + options: [ + { id: '1', name: 'Option 1' }, + { id: '2', name: 'Option 2' }, + ], + selected_option_ids: ['1', '2'], + }); + + const result = checklistFilterCheck(data, '', condition); + + expect(result).toBe(true); + }); + + it('should return false for IsComplete condition', () => { + const condition = ChecklistFilterCondition.IsComplete; + const data = JSON.stringify({ + options: [ + { id: '1', name: 'Option 1' }, + { id: '2', name: 'Option 2' }, + ], + selected_option_ids: ['1'], + }); + + const result = checklistFilterCheck(data, '', condition); + + expect(result).toBe(false); + }); + + it('should return false for unknown condition', () => { + const condition = 42; + const data = JSON.stringify({ + options: [ + { id: '1', name: 'Option 1' }, + { id: '2', name: 'Option 2' }, + ], + selected_option_ids: ['1', '2'], + }); + + const result = checklistFilterCheck(data, '', condition); + + expect(result).toBe(false); + }); +}); + +describe('SelectOption filter check', () => { + it('should return true for OptionIs condition', () => { + const condition = SelectOptionFilterCondition.OptionIs; + const content = '1'; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for OptionIs condition', () => { + const condition = SelectOptionFilterCondition.OptionIs; + const content = '3'; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for OptionIsNot condition', () => { + const condition = SelectOptionFilterCondition.OptionIsNot; + const content = '3'; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for OptionIsNot condition', () => { + const condition = SelectOptionFilterCondition.OptionIsNot; + const content = '1'; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for OptionContains condition', () => { + const condition = SelectOptionFilterCondition.OptionContains; + const content = '1,3'; + const data = '1,2,3'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for OptionContains condition', () => { + const condition = SelectOptionFilterCondition.OptionContains; + const content = '4'; + const data = '1,2,3'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for OptionDoesNotContain condition', () => { + const condition = SelectOptionFilterCondition.OptionDoesNotContain; + const content = '4,5'; + const data = '1,2,3'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(true); + }); + + it('should return false for OptionDoesNotContain condition', () => { + const condition = SelectOptionFilterCondition.OptionDoesNotContain; + const content = '1,3'; + const data = '1,2,3'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(false); + }); + + it('should return true for OptionIsEmpty condition', () => { + const condition = SelectOptionFilterCondition.OptionIsEmpty; + const data = ''; + + const result = selectOptionFilterCheck(data, '', condition); + + expect(result).toBe(true); + }); + + it('should return false for OptionIsEmpty condition', () => { + const condition = SelectOptionFilterCondition.OptionIsEmpty; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, '', condition); + + expect(result).toBe(false); + }); + + it('should return true for OptionIsNotEmpty condition', () => { + const condition = SelectOptionFilterCondition.OptionIsNotEmpty; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, '', condition); + + expect(result).toBe(true); + }); + + it('should return false for OptionIsNotEmpty condition', () => { + const condition = SelectOptionFilterCondition.OptionIsNotEmpty; + const data = ''; + + const result = selectOptionFilterCheck(data, '', condition); + + expect(result).toBe(false); + }); + + it('should return false for unknown condition', () => { + const condition = 42; + const content = '1'; + const data = '1,2'; + + const result = selectOptionFilterCheck(data, content, condition); + + expect(result).toBe(false); + }); +}); + +describe('Database filterBy', () => { + let rows: Row[]; + + beforeEach(() => { + rows = withTestingRows(); + }); + + it('should return all rows for empty filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('1,2,3,4,5,6,7,8,9,10'); + }); + + it('should return rows that match text filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withRichTextFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('1,5'); + }); + + it('should return rows that match number filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withNumberFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('4,5,6,7,8,9,10'); + }); + + it('should return rows that match checkbox filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withCheckboxFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('2,4,6,8,10'); + }); + + it('should return rows that match checklist filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withChecklistFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('1,2,4,5,6,7,8,10'); + }); + + it('should return rows that match multiple filters', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter1 = withRichTextFilter(); + const filter2 = withNumberFilter(); + filters.push([filter1, filter2]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('5'); + }); + + it('should return rows that match url filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withUrlFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('4'); + }); + + it('should return rows that match date filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withDateTimeFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('1,2,3,4,5,6,7,8,9,10'); + }); + + it('should return rows that match select option filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withSingleSelectOptionFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('2,5,8'); + }); + + it('should return rows that match multi select option filter', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter = withMultiSelectOptionFilter(); + filters.push([filter]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('1,2,3,5,6,7,8,9'); + }); + + it('should return rows that match multiple filters', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter1 = withNumberFilter(); + const filter2 = withChecklistFilter(); + filters.push([filter1, filter2]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe('4,5,6,7,8,10'); + }); + + it('should return empty array for all filters', () => { + const { filters, fields, rowMap } = withTestingData(); + const filter1 = withNumberFilter(); + const filter2 = withChecklistFilter(); + const filter3 = withRichTextFilter(); + const filter4 = withCheckboxFilter(); + const filter5 = withSingleSelectOptionFilter(); + const filter6 = withMultiSelectOptionFilter(); + const filter7 = withUrlFilter(); + const filter8 = withDateTimeFilter(); + filters.push([filter1, filter2, filter3, filter4, filter5, filter6, filter7, filter8]); + const result = filterBy(rows, filters, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(result).toBe(''); + }); +}); diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/filters.json b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/filters.json new file mode 100644 index 0000000000..eb0688a5de --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/filters.json @@ -0,0 +1,40 @@ +{ + "filter_text_field": { + "field_id": "text_field", + "condition": 2, + "content": "w" + }, + "filter_number_field": { + "field_id": "number_field", + "condition": 2, + "content": 1000 + }, + "filter_date_field": { + "field_id": "date_field", + "condition": 1, + "content": 1685798400000 + }, + "filter_checkbox_field": { + "field_id": "checkbox_field", + "condition": 1 + }, + "filter_checklist_field": { + "field_id": "checklist_field", + "condition": 1 + }, + "filter_url_field": { + "field_id": "url_field", + "condition": 0, + "content": "https://example.com/4" + }, + "filter_single_select_field": { + "field_id": "single_select_field", + "condition": 0, + "content": "2" + }, + "filter_multi_select_field": { + "field_id": "multi_select_field", + "condition": 2, + "content": "1,3" + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/rows.json b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/rows.json new file mode 100644 index 0000000000..989a335527 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/rows.json @@ -0,0 +1,412 @@ +[ + { + "id": "1", + "cells": { + "text_field": { + "id": "text_field", + "data": "Hello world" + }, + "number_field": { + "id": "number_field", + "data": 123 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "Yes" + }, + "date_field": { + "id": "date_field", + "data": 1685539200000, + "end_timestamp": 1685625600000, + "include_time": true, + "is_range": false, + "reminder_id": "rem1" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/1" + }, + "single_select_field": { + "id": "single_select_field", + "data": "1" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "1,2" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"1\"]}" + } + } + }, + { + "id": "2", + "cells": { + "text_field": { + "id": "text_field", + "data": "Good morning" + }, + "number_field": { + "id": "number_field", + "data": 456 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "No" + }, + "date_field": { + "id": "date_field", + "data": 1685625600000, + "end_timestamp": 1685712000000, + "include_time": false, + "is_range": true, + "reminder_id": "rem2" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/2" + }, + "single_select_field": { + "id": "single_select_field", + "data": "2" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "2,3" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"2\"]}" + } + } + }, + { + "id": "3", + "cells": { + "text_field": { + "id": "text_field", + "data": "Good night" + }, + "number_field": { + "id": "number_field", + "data": 789 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "Yes" + }, + "date_field": { + "id": "date_field", + "data": 1685712000000, + "end_timestamp": 1685798400000, + "include_time": true, + "is_range": false, + "reminder_id": "rem3" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/3" + }, + "single_select_field": { + "id": "single_select_field", + "data": "3" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "1,3" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"1\",\"2\"]}" + } + } + }, + { + "id": "4", + "cells": { + "text_field": { + "id": "text_field", + "data": "Happy day" + }, + "number_field": { + "id": "number_field", + "data": 1011 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "No" + }, + "date_field": { + "id": "date_field", + "data": 1685798400000, + "end_timestamp": 1685884800000, + "include_time": false, + "is_range": true, + "reminder_id": "rem4" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/4" + }, + "single_select_field": { + "id": "single_select_field", + "data": "1" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "2" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[]}" + } + } + }, + { + "id": "5", + "cells": { + "text_field": { + "id": "text_field", + "data": "Sunny weather" + }, + "number_field": { + "id": "number_field", + "data": 1213 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "Yes" + }, + "date_field": { + "id": "date_field", + "data": 1685884800000, + "end_timestamp": 1685971200000, + "include_time": true, + "is_range": false, + "reminder_id": "rem5" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/5" + }, + "single_select_field": { + "id": "single_select_field", + "data": "2" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "1,2,3" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"1\"]}" + } + } + }, + { + "id": "6", + "cells": { + "text_field": { + "id": "text_field", + "data": "Rainy day" + }, + "number_field": { + "id": "number_field", + "data": 1415 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "No" + }, + "date_field": { + "id": "date_field", + "data": 1685971200000, + "end_timestamp": 1686057600000, + "include_time": false, + "is_range": true, + "reminder_id": "rem6" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/6" + }, + "single_select_field": { + "id": "single_select_field", + "data": "3" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "1,3" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"2\"]}" + } + } + }, + { + "id": "7", + "cells": { + "text_field": { + "id": "text_field", + "data": "Winter is coming" + }, + "number_field": { + "id": "number_field", + "data": 1617 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "Yes" + }, + "date_field": { + "id": "date_field", + "data": 1686057600000, + "end_timestamp": 1686144000000, + "include_time": true, + "is_range": false, + "reminder_id": "rem7" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/7" + }, + "single_select_field": { + "id": "single_select_field", + "data": "1" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "1,2" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"1\"]}" + } + } + }, + { + "id": "8", + "cells": { + "text_field": { + "id": "text_field", + "data": "Summer vibes" + }, + "number_field": { + "id": "number_field", + "data": 1819 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "No" + }, + "date_field": { + "id": "date_field", + "data": 1686144000000, + "end_timestamp": 1686230400000, + "include_time": false, + "is_range": true, + "reminder_id": "rem8" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/8" + }, + "single_select_field": { + "id": "single_select_field", + "data": "2" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "2,3" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"2\"]}" + } + } + }, + { + "id": "9", + "cells": { + "text_field": { + "id": "text_field", + "data": "Autumn leaves" + }, + "number_field": { + "id": "number_field", + "data": 2021 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "Yes" + }, + "date_field": { + "id": "date_field", + "data": 1686230400000, + "end_timestamp": 1686316800000, + "include_time": true, + "is_range": false, + "reminder_id": "rem9" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/9" + }, + "single_select_field": { + "id": "single_select_field", + "data": "3" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "1,3" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[\"1\",\"2\"]}" + } + } + }, + { + "id": "10", + "cells": { + "text_field": { + "id": "text_field", + "data": "Spring blossoms" + }, + "number_field": { + "id": "number_field", + "data": 2223 + }, + "checkbox_field": { + "id": "checkbox_field", + "data": "No" + }, + "date_field": { + "id": "date_field", + "data": 1686316800000, + "end_timestamp": 1686403200000, + "include_time": false, + "is_range": true, + "reminder_id": "rem10" + }, + "url_field": { + "id": "url_field", + "data": "https://example.com/10" + }, + "single_select_field": { + "id": "single_select_field", + "data": "1" + }, + "multi_select_field": { + "id": "multi_select_field", + "data": "2" + }, + "checklist_field": { + "id": "checklist_field", + "data": "{\"options\":[{\"id\":\"1\",\"name\":\"Task 1\"},{\"id\":\"2\",\"name\":\"Task 2\"}],\"selected_option_ids\":[]}" + } + } + } +] diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/sorts.json b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/sorts.json new file mode 100644 index 0000000000..e07c1647ce --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/fixtures/sorts.json @@ -0,0 +1,82 @@ +{ + "sort_asc_text_field": { + "id": "sort_asc_text_field", + "field_id": "text_field", + "condition": "asc" + }, + "sort_desc_text_field": { + "field_id": "text_field", + "condition": "desc", + "id": "sort_desc_text_field" + }, + "sort_asc_number_field": { + "field_id": "number_field", + "condition": "asc", + "id": "sort_asc_number_field" + }, + "sort_desc_number_field": { + "field_id": "number_field", + "condition": "desc", + "id": "sort_desc_number_field" + }, + "sort_asc_date_field": { + "field_id": "date_field", + "condition": "asc", + "id": "sort_asc_date_field" + }, + "sort_desc_date_field": { + "field_id": "date_field", + "condition": "desc", + "id": "sort_desc_date_field" + }, + "sort_asc_checkbox_field": { + "field_id": "checkbox_field", + "condition": "asc", + "id": "sort_asc_checkbox_field" + }, + "sort_desc_checkbox_field": { + "field_id": "checkbox_field", + "condition": "desc", + "id": "sort_desc_checkbox_field" + }, + "sort_asc_checklist_field": { + "field_id": "checklist_field", + "condition": "asc", + "id": "sort_asc_checklist_field" + }, + "sort_desc_checklist_field": { + "field_id": "checklist_field", + "condition": "desc", + "id": "sort_desc_checklist_field" + }, + "sort_asc_single_select_field": { + "field_id": "single_select_field", + "condition": "asc", + "id": "sort_asc_single_select_field" + }, + "sort_desc_single_select_field": { + "field_id": "single_select_field", + "condition": "desc", + "id": "sort_desc_single_select_field" + }, + "sort_asc_multi_select_field": { + "field_id": "multi_select_field", + "condition": "asc", + "id": "sort_asc_multi_select_field" + }, + "sort_desc_multi_select_field": { + "field_id": "multi_select_field", + "condition": "desc", + "id": "sort_desc_multi_select_field" + }, + "sort_asc_url_field": { + "field_id": "url_field", + "condition": "asc", + "id": "sort_asc_url_field" + }, + "sort_desc_url_field": { + "field_id": "url_field", + "condition": "desc", + "id": "sort_desc_url_field" + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/group.test.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/group.test.ts new file mode 100644 index 0000000000..518918138b --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/group.test.ts @@ -0,0 +1,98 @@ +import { Row } from '@/application/database-yjs'; +import { withTestingData } from '@/application/database-yjs/__tests__/withTestingData'; +import { withTestingRows } from '@/application/database-yjs/__tests__/withTestingRows'; +import { expect } from '@jest/globals'; +import { groupByField } from '../group'; + +describe('Database group', () => { + let rows: Row[]; + + beforeEach(() => { + rows = withTestingRows(); + }); + + it('should return undefined if field is not select option', () => { + const { fields, rowMap } = withTestingData(); + expect(groupByField(rows, rowMap, fields.get('text_field'))).toBeUndefined(); + expect(groupByField(rows, rowMap, fields.get('number_field'))).toBeUndefined(); + expect(groupByField(rows, rowMap, fields.get('checkbox_field'))).toBeUndefined(); + expect(groupByField(rows, rowMap, fields.get('checklist_field'))).toBeUndefined(); + }); + + it('should group by select option field', () => { + const { fields, rowMap } = withTestingData(); + const field = fields.get('single_select_field'); + const result = groupByField(rows, rowMap, field); + const expectRes = new Map([ + [ + '1', + [ + { id: '1', height: 37 }, + { id: '4', height: 37 }, + { id: '7', height: 37 }, + { id: '10', height: 37 }, + ], + ], + [ + '2', + [ + { id: '2', height: 37 }, + { id: '5', height: 37 }, + { id: '8', height: 37 }, + ], + ], + [ + '3', + [ + { id: '3', height: 37 }, + { id: '6', height: 37 }, + { id: '9', height: 37 }, + ], + ], + ]); + expect(result).toEqual(expectRes); + }); + + it('should group by multi select option field', () => { + const { fields, rowMap } = withTestingData(); + const field = fields.get('multi_select_field'); + const result = groupByField(rows, rowMap, field); + const expectRes = new Map([ + [ + '1', + [ + { id: '1', height: 37 }, + { id: '3', height: 37 }, + { id: '5', height: 37 }, + { id: '6', height: 37 }, + { id: '7', height: 37 }, + { id: '9', height: 37 }, + ], + ], + [ + '2', + [ + { id: '1', height: 37 }, + { id: '2', height: 37 }, + { id: '4', height: 37 }, + { id: '5', height: 37 }, + { id: '7', height: 37 }, + { id: '8', height: 37 }, + { id: '10', height: 37 }, + ], + ], + [ + '3', + [ + { id: '2', height: 37 }, + { id: '3', height: 37 }, + { id: '5', height: 37 }, + { id: '6', height: 37 }, + { id: '8', height: 37 }, + { id: '9', height: 37 }, + ], + ], + ]); + expect(result).toEqual(expectRes); + }); +}); diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/sort.test.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/sort.test.ts new file mode 100644 index 0000000000..39ffa2abe5 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/sort.test.ts @@ -0,0 +1,314 @@ +import { Row } from '@/application/database-yjs'; +import { withTestingData } from '@/application/database-yjs/__tests__/withTestingData'; +import { withTestingRows } from '@/application/database-yjs/__tests__/withTestingRows'; +import { + withCheckboxSort, + withChecklistSort, + withDateTimeSort, + withMultiSelectOptionSort, + withNumberSort, + withRichTextSort, + withSingleSelectOptionSort, + withUrlSort, +} from '@/application/database-yjs/__tests__/withTestingSorts'; +import { + withCheckboxTestingField, + withDateTimeTestingField, + withNumberTestingField, + withRichTextTestingField, + withSelectOptionTestingField, + withURLTestingField, + withChecklistTestingField, +} from './withTestingField'; +import { sortBy, parseCellDataForSort } from '../sort'; +import * as Y from 'yjs'; +import { expect } from '@jest/globals'; + +describe('parseCellDataForSort', () => { + it('should parse data correctly based on field type', () => { + const doc = new Y.Doc(); + const field = withNumberTestingField(); + doc.getMap().set('field', field); + const data = 42; + + const result = parseCellDataForSort(field, data); + + expect(result).toEqual(data); + }); + + it('should return default value for empty rich text', () => { + const doc = new Y.Doc(); + const field = withRichTextTestingField(); + doc.getMap().set('field', field); + const data = ''; + + const result = parseCellDataForSort(field, data); + + expect(result).toEqual('\uFFFF'); + }); + + it('should return default value for empty URL', () => { + const doc = new Y.Doc(); + const field = withURLTestingField(); + doc.getMap().set('field', field); + const data = ''; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe('\uFFFF'); + }); + + it('should return data for non-empty rich text', () => { + const doc = new Y.Doc(); + const field = withRichTextTestingField(); + doc.getMap().set('field', field); + const data = 'Hello, world!'; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe(data); + }); + + it('should parse checkbox data correctly', () => { + const doc = new Y.Doc(); + const field = withCheckboxTestingField(); + doc.getMap().set('field', field); + const data = 'Yes'; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe(true); + + const noData = 'No'; + const noResult = parseCellDataForSort(field, noData); + expect(noResult).toBe(false); + }); + + it('should parse DateTime data correctly', () => { + const doc = new Y.Doc(); + const field = withDateTimeTestingField(); + doc.getMap().set('field', field); + const data = '1633046400000'; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe(Number(data)); + }); + + it('should parse SingleSelect data correctly', () => { + const doc = new Y.Doc(); + const field = withSelectOptionTestingField(); + doc.getMap().set('field', field); + const data = '1'; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe('Option 1'); + }); + + it('should parse MultiSelect data correctly', () => { + const doc = new Y.Doc(); + const field = withSelectOptionTestingField(); + doc.getMap().set('field', field); + const data = '1,2'; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe('Option 1, Option 2'); + }); + + it('should parse Checklist data correctly', () => { + const doc = new Y.Doc(); + const field = withChecklistTestingField(); + doc.getMap().set('field', field); + const data = '[]'; + + const result = parseCellDataForSort(field, data); + + expect(result).toBe(0); + }); +}); + +describe('Database sortBy', () => { + let rows: Row[]; + + beforeEach(() => { + rows = withTestingRows(); + }); + + it('should sort by number field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withNumberSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('1,2,3,4,5,6,7,8,9,10'); + }); + + it('should sort by number field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withNumberSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('10,9,8,7,6,5,4,3,2,1'); + }); + + it('should sort by rich text field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withRichTextSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('9,2,3,4,1,6,10,8,5,7'); + }); + + it('should sort by rich text field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withRichTextSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('7,5,8,10,6,1,4,3,2,9'); + }); + + it('should sort by url field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withUrlSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('1,10,2,3,4,5,6,7,8,9'); + }); + + it('should sort by url field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withUrlSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('9,8,7,6,5,4,3,2,10,1'); + }); + + it('should sort by checkbox field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withCheckboxSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('2,4,6,8,10,1,3,5,7,9'); + }); + + it('should sort by checkbox field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withCheckboxSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('1,3,5,7,9,2,4,6,8,10'); + }); + + it('should sort by DateTime field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withDateTimeSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('1,2,3,4,5,6,7,8,9,10'); + }); + + it('should sort by DateTime field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withDateTimeSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('10,9,8,7,6,5,4,3,2,1'); + }); + + it('should sort by SingleSelect field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withSingleSelectOptionSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('1,4,7,10,2,5,8,3,6,9'); + }); + + it('should sort by SingleSelect field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withSingleSelectOptionSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('3,6,9,2,5,8,1,4,7,10'); + }); + + it('should sort by MultiSelect field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withMultiSelectOptionSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('1,7,5,3,6,9,4,10,2,8'); + }); + + it('should sort by MultiSelect field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withMultiSelectOptionSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('2,8,4,10,3,6,9,5,1,7'); + }); + + it('should sort by Checklist field in ascending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withChecklistSort(); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('4,10,1,2,5,6,7,8,3,9'); + }); + + it('should sort by Checklist field in descending order', () => { + const { sorts, fields, rowMap } = withTestingData(); + const sort = withChecklistSort(false); + sorts.push([sort]); + + const sortedRows = sortBy(rows, sorts, fields, rowMap) + .map((row) => row.id) + .join(','); + expect(sortedRows).toBe('3,9,1,2,5,6,7,8,4,10'); + }); +}); diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingData.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingData.ts new file mode 100644 index 0000000000..40633223be --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingData.ts @@ -0,0 +1,31 @@ +import { YDatabaseFields, YDatabaseFilters, YDatabaseSorts } from '@/application/collab.type'; +import { withTestingFields } from '@/application/database-yjs/__tests__/withTestingField'; +import { withTestingRowDataMap } from '@/application/database-yjs/__tests__/withTestingRows'; +import * as Y from 'yjs'; + +export function withTestingData() { + const doc = new Y.Doc(); + const sharedRoot = doc.getMap(); + const fields = withTestingFields() as YDatabaseFields; + + sharedRoot.set('fields', fields); + + const rowMap = withTestingRowDataMap(); + + sharedRoot.set('rows', rowMap); + + const sorts = new Y.Array() as YDatabaseSorts; + + sharedRoot.set('sorts', sorts); + + const filters = new Y.Array() as YDatabaseFilters; + + sharedRoot.set('filters', filters); + + return { + fields, + rowMap, + sorts, + filters, + }; +} diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingField.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingField.ts new file mode 100644 index 0000000000..417a3b99a7 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingField.ts @@ -0,0 +1,153 @@ +import { + YDatabaseField, + YDatabaseFieldTypeOption, + YjsDatabaseKey, + YMapFieldTypeOption, +} from '@/application/collab.type'; +import { FieldType, SelectOptionColor } from '@/application/database-yjs'; +import * as Y from 'yjs'; + +export function withTestingFields() { + const fields = new Y.Map(); + const textField = withRichTextTestingField(); + + fields.set('text_field', textField); + const numberField = withNumberTestingField(); + + fields.set('number_field', numberField); + + const checkboxField = withCheckboxTestingField(); + + fields.set('checkbox_field', checkboxField); + + const dateTimeField = withDateTimeTestingField(); + + fields.set('date_field', dateTimeField); + + const singleSelectField = withSelectOptionTestingField(); + + fields.set('single_select_field', singleSelectField); + const multipleSelectField = withSelectOptionTestingField(true); + + fields.set('multi_select_field', multipleSelectField); + + const urlField = withURLTestingField(); + + fields.set('url_field', urlField); + + const checklistField = withChecklistTestingField(); + + fields.set('checklist_field', checklistField); + + return fields; +} + +export function withRichTextTestingField() { + const field = new Y.Map() as YDatabaseField; + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'Rich Text Field'); + field.set(YjsDatabaseKey.id, 'text_field'); + field.set(YjsDatabaseKey.type, String(FieldType.RichText)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + + return field; +} + +export function withNumberTestingField() { + const field = new Y.Map() as YDatabaseField; + + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'Number Field'); + field.set(YjsDatabaseKey.id, 'number_field'); + field.set(YjsDatabaseKey.type, String(FieldType.Number)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + + return field; +} + +export function withCheckboxTestingField() { + const field = new Y.Map() as YDatabaseField; + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'Checkbox Field'); + field.set(YjsDatabaseKey.id, 'checkbox_field'); + field.set(YjsDatabaseKey.type, String(FieldType.Checkbox)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + + return field; +} + +export function withDateTimeTestingField() { + const field = new Y.Map() as YDatabaseField; + const typeOption = new Y.Map() as YDatabaseFieldTypeOption; + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'DateTime Field'); + field.set(YjsDatabaseKey.id, 'date_field'); + field.set(YjsDatabaseKey.type, String(FieldType.DateTime)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + field.set(YjsDatabaseKey.type_option, typeOption); + + const dateTypeOption = new Y.Map() as YMapFieldTypeOption; + + typeOption.set(String(FieldType.DateTime), dateTypeOption); + + dateTypeOption.set(YjsDatabaseKey.time_format, '0'); + dateTypeOption.set(YjsDatabaseKey.date_format, '0'); + return field; +} + +export function withURLTestingField() { + const field = new Y.Map() as YDatabaseField; + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'URL Field'); + field.set(YjsDatabaseKey.id, 'url_field'); + field.set(YjsDatabaseKey.type, String(FieldType.URL)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + + return field; +} + +export function withSelectOptionTestingField(isMultiple = false) { + const field = new Y.Map() as YDatabaseField; + const typeOption = new Y.Map() as YDatabaseFieldTypeOption; + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'Single Select Field'); + field.set(YjsDatabaseKey.id, isMultiple ? 'multi_select_field' : 'single_select_field'); + field.set(YjsDatabaseKey.type, String(FieldType.SingleSelect)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + field.set(YjsDatabaseKey.type_option, typeOption); + + const selectTypeOption = new Y.Map() as YMapFieldTypeOption; + + typeOption.set(String(FieldType.SingleSelect), selectTypeOption); + + selectTypeOption.set( + YjsDatabaseKey.content, + JSON.stringify({ + disable_color: false, + options: [ + { id: '1', name: 'Option 1', color: SelectOptionColor.Purple }, + { id: '2', name: 'Option 2', color: SelectOptionColor.Pink }, + { id: '3', name: 'Option 3', color: SelectOptionColor.LightPink }, + ], + }) + ); + return field; +} + +export function withChecklistTestingField() { + const field = new Y.Map() as YDatabaseField; + const now = Date.now().toString(); + + field.set(YjsDatabaseKey.name, 'Checklist Field'); + field.set(YjsDatabaseKey.id, 'checklist_field'); + field.set(YjsDatabaseKey.type, String(FieldType.Checklist)); + field.set(YjsDatabaseKey.last_modified, now.valueOf()); + + return field; +} diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingFilters.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingFilters.ts new file mode 100644 index 0000000000..540c298abf --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingFilters.ts @@ -0,0 +1,83 @@ +import { YDatabaseFilter, YjsDatabaseKey } from '@/application/collab.type'; +import * as Y from 'yjs'; +import * as filtersJson from './fixtures/filters.json'; + +export function withRichTextFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_text_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_text_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_text_field.condition); + filter.set(YjsDatabaseKey.content, filtersJson.filter_text_field.content); + return filter; +} + +export function withUrlFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_url_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_url_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_url_field.condition); + filter.set(YjsDatabaseKey.content, filtersJson.filter_url_field.content); + return filter; +} + +export function withNumberFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_number_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_number_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_number_field.condition); + filter.set(YjsDatabaseKey.content, filtersJson.filter_number_field.content); + return filter; +} + +export function withCheckboxFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_checkbox_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_checkbox_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_checkbox_field.condition); + filter.set(YjsDatabaseKey.content, ''); + return filter; +} + +export function withChecklistFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_checklist_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_checklist_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_checklist_field.condition); + filter.set(YjsDatabaseKey.content, ''); + return filter; +} + +export function withSingleSelectOptionFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_single_select_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_single_select_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_single_select_field.condition); + filter.set(YjsDatabaseKey.content, filtersJson.filter_single_select_field.content); + return filter; +} + +export function withMultiSelectOptionFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_multi_select_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_multi_select_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_multi_select_field.condition); + filter.set(YjsDatabaseKey.content, filtersJson.filter_multi_select_field.content); + return filter; +} + +export function withDateTimeFilter() { + const filter = new Y.Map() as YDatabaseFilter; + + filter.set(YjsDatabaseKey.id, 'filter_date_field'); + filter.set(YjsDatabaseKey.field_id, filtersJson.filter_date_field.field_id); + filter.set(YjsDatabaseKey.condition, filtersJson.filter_date_field.condition); + filter.set(YjsDatabaseKey.content, filtersJson.filter_date_field.content); + return filter; +} diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingRows.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingRows.ts new file mode 100644 index 0000000000..fc4c8c4f4c --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingRows.ts @@ -0,0 +1,94 @@ +import { + YDatabaseCell, + YDatabaseCells, + YDatabaseRow, + YDoc, + YjsDatabaseKey, + YjsEditorKey, +} from '@/application/collab.type'; +import { FieldType, Row } from '@/application/database-yjs'; +import * as Y from 'yjs'; +import * as rowsJson from './fixtures/rows.json'; + +export function withTestingRows(): Row[] { + return rowsJson.map((row) => { + return { + id: row.id, + height: 37, + }; + }); +} + +export function withTestingRowDataMap(): Y.Map { + const folder = new Y.Map(); + const rows = withTestingRows(); + + rows.forEach((row, index) => { + const rowDoc = new Y.Doc(); + const rowData = withTestingRowData(row.id, index); + + rowDoc.getMap(YjsEditorKey.data_section).set(YjsEditorKey.database_row, rowData); + folder.set(row.id, rowDoc); + }); + + return folder as Y.Map; +} + +export function withTestingRowData(id: string, index: number) { + const rowData = new Y.Map() as YDatabaseRow; + + rowData.set(YjsDatabaseKey.id, id); + rowData.set(YjsDatabaseKey.height, 37); + + const cells = new Y.Map() as YDatabaseCells; + + const textFieldCell = withTestingCell(rowsJson[index].cells.text_field.data); + + textFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.RichText)); + cells.set('text_field', textFieldCell); + + const numberFieldCell = withTestingCell(rowsJson[index].cells.number_field.data); + + numberFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.Number)); + cells.set('number_field', numberFieldCell); + + const checkboxFieldCell = withTestingCell(rowsJson[index].cells.checkbox_field.data); + + checkboxFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.Checkbox)); + cells.set('checkbox_field', checkboxFieldCell); + + const dateTimeFieldCell = withTestingCell(rowsJson[index].cells.date_field.data); + + dateTimeFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.DateTime)); + cells.set('date_field', dateTimeFieldCell); + + const urlFieldCell = withTestingCell(rowsJson[index].cells.url_field.data); + + urlFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.URL)); + cells.set('url_field', urlFieldCell); + + const singleSelectFieldCell = withTestingCell(rowsJson[index].cells.single_select_field.data); + + singleSelectFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.SingleSelect)); + cells.set('single_select_field', singleSelectFieldCell); + + const multiSelectFieldCell = withTestingCell(rowsJson[index].cells.multi_select_field.data); + + multiSelectFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.MultiSelect)); + cells.set('multi_select_field', multiSelectFieldCell); + + const checlistFieldCell = withTestingCell(rowsJson[index].cells.checklist_field.data); + + checlistFieldCell.set(YjsDatabaseKey.field_type, Number(FieldType.Checklist)); + cells.set('checklist_field', checlistFieldCell); + + rowData.set(YjsDatabaseKey.cells, cells); + return rowData; +} + +export function withTestingCell(cellData: string | number) { + const cell = new Y.Map() as YDatabaseCell; + + cell.set(YjsDatabaseKey.data, cellData); + return cell; +} diff --git a/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingSorts.ts b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingSorts.ts new file mode 100644 index 0000000000..f5c1fd5a16 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/database-yjs/__tests__/withTestingSorts.ts @@ -0,0 +1,91 @@ +import { YDatabaseSort, YjsDatabaseKey } from '@/application/collab.type'; +import * as Y from 'yjs'; +import * as sortsJson from './fixtures/sorts.json'; + +export function withRichTextSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_text_field : sortsJson.sort_desc_text_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withUrlSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_url_field : sortsJson.sort_desc_url_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withNumberSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_number_field : sortsJson.sort_desc_number_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withCheckboxSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_checkbox_field : sortsJson.sort_desc_checkbox_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withDateTimeSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_date_field : sortsJson.sort_desc_date_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withSingleSelectOptionSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_single_select_field : sortsJson.sort_desc_single_select_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withMultiSelectOptionSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_multi_select_field : sortsJson.sort_desc_multi_select_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} + +export function withChecklistSort(isAscending: boolean = true) { + const sort = new Y.Map() as YDatabaseSort; + const sortJSON = isAscending ? sortsJson.sort_asc_checklist_field : sortsJson.sort_desc_checklist_field; + + sort.set(YjsDatabaseKey.id, sortJSON.id); + sort.set(YjsDatabaseKey.field_id, sortJSON.field_id); + sort.set(YjsDatabaseKey.condition, sortJSON.condition === 'asc' ? '0' : '1'); + + return sort; +} diff --git a/frontend/appflowy_web_app/src/application/database-yjs/const.ts b/frontend/appflowy_web_app/src/application/database-yjs/const.ts index b8ebe46a3a..c67b9edec8 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/const.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/const.ts @@ -3,7 +3,7 @@ import { RowMetaKey } from '@/application/database-yjs/database.type'; import * as Y from 'yjs'; import { v5 as uuidv5, parse as uuidParse } from 'uuid'; -export const DEFAULT_ROW_HEIGHT = 37; +export const DEFAULT_ROW_HEIGHT = 36; export const MIN_COLUMN_WIDTH = 100; export const getCell = (rowId: string, fieldId: string, rowMetas: Y.Map) => { diff --git a/frontend/appflowy_web_app/src/application/database-yjs/context.ts b/frontend/appflowy_web_app/src/application/database-yjs/context.ts index 96a0f067c4..4e0824762c 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/context.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/context.ts @@ -5,9 +5,10 @@ import * as Y from 'yjs'; export interface DatabaseContextState { readOnly: boolean; - doc: YDoc; + databaseDoc: YDoc; viewId: string; rowDocMap: Y.Map; + isDatabaseRowPage?: boolean; navigateToRow?: (rowId: string) => void; } @@ -15,18 +16,30 @@ export const DatabaseContext = createContext(null); export const useDatabase = () => { const database = useContext(DatabaseContext) - ?.doc?.getMap(YjsEditorKey.data_section) + ?.databaseDoc?.getMap(YjsEditorKey.data_section) .get(YjsEditorKey.database) as YDatabase; return database; }; +export function useDatabaseViewId() { + return useContext(DatabaseContext)?.viewId; +} + export const useNavigateToRow = () => { return useContext(DatabaseContext)?.navigateToRow; }; +export const useRowDocMap = () => { + return useContext(DatabaseContext)?.rowDocMap; +}; + +export const useIsDatabaseRowPage = () => { + return useContext(DatabaseContext)?.isDatabaseRowPage; +}; + export const useRow = (rowId: string) => { - const rows = useContext(DatabaseContext)?.rowDocMap; + const rows = useRowDocMap(); return rows?.get(rowId)?.getMap(YjsEditorKey.data_section); }; @@ -51,7 +64,7 @@ export const useDatabaseView = () => { const database = useDatabase(); const viewId = useViewId(); - return viewId ? database.get(YjsDatabaseKey.views)?.get(viewId) : undefined; + return viewId ? database?.get(YjsDatabaseKey.views)?.get(viewId) : undefined; }; export function useDatabaseFields() { diff --git a/frontend/appflowy_web_app/src/application/database-yjs/filter.ts b/frontend/appflowy_web_app/src/application/database-yjs/filter.ts index 5f0919c4d9..235897b6c5 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/filter.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/filter.ts @@ -141,6 +141,18 @@ export function textFilterCheck(data: string, content: string, condition: TextFi } export function numberFilterCheck(data: string, content: string, condition: number) { + if (isNaN(Number(data)) || isNaN(Number(content)) || data === '' || content === '') { + if (condition === NumberFilterCondition.NumberIsEmpty && data === '') { + return true; + } + + if (condition === NumberFilterCondition.NumberIsNotEmpty && data !== '') { + return true; + } + + return false; + } + const decimal = new Decimal(data).toNumber(); const filterDecimal = new Decimal(content).toNumber(); @@ -188,6 +200,14 @@ export function checklistFilterCheck(data: string, content: string, condition: n } export function selectOptionFilterCheck(data: string, content: string, condition: number) { + if (SelectOptionFilterCondition.OptionIsEmpty === condition) { + return data === ''; + } + + if (SelectOptionFilterCondition.OptionIsNotEmpty === condition) { + return data !== ''; + } + const selectedOptionIds = data.split(','); const filterOptionIds = content.split(','); diff --git a/frontend/appflowy_web_app/src/application/database-yjs/selector.ts b/frontend/appflowy_web_app/src/application/database-yjs/selector.ts index d42399d882..c7d1272c9d 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/selector.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/selector.ts @@ -1,12 +1,19 @@ -import { FieldId, SortId, YDatabaseField, YjsDatabaseKey, YjsEditorKey, YjsFolderKey } from '@/application/collab.type'; +import { + FieldId, + SortId, + YDatabaseField, + YDoc, + YjsDatabaseKey, + YjsEditorKey, + YjsFolderKey, +} from '@/application/collab.type'; import { getCell, metaIdFromRowId, MIN_COLUMN_WIDTH } from '@/application/database-yjs/const'; import { - DatabaseContext, useDatabase, useDatabaseFields, useDatabaseView, - useRow, - useRowData, + useIsDatabaseRowPage, + useRowDocMap, useRows, useViewId, } from '@/application/database-yjs/context'; @@ -14,12 +21,12 @@ import { filterBy, parseFilter } from '@/application/database-yjs/filter'; import { groupByField } from '@/application/database-yjs/group'; import { sortBy } from '@/application/database-yjs/sort'; import { useViewsIdSelector } from '@/application/folder-yjs'; -import { useId } from '@/components/_shared/context-provider/IdProvider'; import { parseYDatabaseCellToCell } from '@/components/database/components/cell/cell.parse'; import { DateTimeCell } from '@/components/database/components/cell/cell.type'; import dayjs from 'dayjs'; -import debounce from 'lodash-es/debounce'; -import React, { useContext, useEffect, useMemo, useState } from 'react'; +import { throttle } from 'lodash-es'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import Y from 'yjs'; import { CalendarLayoutSetting, FieldType, FieldVisibility, Filter, RowMetaKey, SortCondition } from './database.type'; export interface Column { @@ -36,10 +43,10 @@ export interface Row { const defaultVisible = [FieldVisibility.AlwaysShown, FieldVisibility.HideWhenEmpty]; -export function useDatabaseViewsSelector() { +export function useDatabaseViewsSelector(iidIndex: string) { const database = useDatabase(); - const { objectId: currentViewId } = useId(); const { viewsId: visibleViewsId, views: folderViews } = useViewsIdSelector(); + const views = database?.get(YjsDatabaseKey.views); const [viewIds, setViewIds] = useState([]); const childViews = useMemo(() => { @@ -50,16 +57,33 @@ export function useDatabaseViewsSelector() { if (!views) return; const observerEvent = () => { - setViewIds( - Array.from(views.keys()).filter((id) => { - const view = folderViews?.get(id); + const viewsObj = views.toJSON(); - return ( - visibleViewsId.includes(id) && - (view?.get(YjsFolderKey.bid) === currentViewId || view?.get(YjsFolderKey.id) === currentViewId) - ); - }) - ); + const viewsSorted = Object.entries(viewsObj).sort((a, b) => { + const [, viewA] = a; + const [, viewB] = b; + + return Number(viewB.created_at) - Number(viewA.created_at); + }); + + const viewsId = []; + + for (const viewItem of viewsSorted) { + const [key] = viewItem; + const view = folderViews?.get(key); + + console.log('view', view?.get(YjsFolderKey.bid), iidIndex); + if ( + visibleViewsId.includes(key) && + view && + (view.get(YjsFolderKey.bid) === iidIndex || view.get(YjsFolderKey.id) === iidIndex) + ) { + viewsId.push(key); + } + } + + console.log('viewsId', viewsId); + setViewIds(viewsId); }; observerEvent(); @@ -68,7 +92,7 @@ export function useDatabaseViewsSelector() { return () => { views.unobserve(observerEvent); }; - }, [visibleViewsId, views, folderViews, currentViewId]); + }, [visibleViewsId, views, folderViews, iidIndex]); return { childViews, @@ -368,8 +392,9 @@ export function useGroup(groupId: string) { export function useRowsByGroup(groupId: string) { const { columns, fieldId } = useGroup(groupId); - const rows = useContext(DatabaseContext)?.rowDocMap; + const rows = useRowDocMap(); const rowOrders = useRowOrdersSelector(); + const fields = useDatabaseFields(); const [notFound, setNotFound] = useState(false); const [groupResult, setGroupResult] = useState>(new Map()); @@ -378,6 +403,8 @@ export function useRowsByGroup(groupId: string) { if (!fieldId || !rowOrders || !rows) return; const onConditionsChange = () => { + if (rows.size !== rowOrders?.length) return; + const newResult = new Map(); const field = fields.get(fieldId); @@ -400,11 +427,9 @@ export function useRowsByGroup(groupId: string) { onConditionsChange(); - const debounceConditionsChange = debounce(onConditionsChange, 200); - - fields.observeDeep(debounceConditionsChange); + fields.observeDeep(onConditionsChange); return () => { - fields.unobserveDeep(debounceConditionsChange); + fields.unobserveDeep(onConditionsChange); }; }, [fieldId, fields, rowOrders, rows]); @@ -419,62 +444,139 @@ export function useRowsByGroup(groupId: string) { } export function useRowOrdersSelector() { - const rows = useContext(DatabaseContext)?.rowDocMap; + const isDatabaseRowPage = useIsDatabaseRowPage(); + const { rows, clock } = useRowDocMapSelector(); const [rowOrders, setRowOrders] = useState(); const view = useDatabaseView(); const sorts = view?.get(YjsDatabaseKey.sorts); const fields = useDatabaseFields(); const filters = view?.get(YjsDatabaseKey.filters); + const onConditionsChange = useCallback(() => { + const originalRowOrders = view?.get(YjsDatabaseKey.row_orders).toJSON(); + + if (!originalRowOrders || !rows) return; + + if (originalRowOrders.length !== rows.size && !isDatabaseRowPage) return; + if (sorts?.length === 0 && filters?.length === 0) { + setRowOrders(originalRowOrders); + return; + } + + let rowOrders: Row[] | undefined; + + if (sorts?.length) { + rowOrders = sortBy(originalRowOrders, sorts, fields, rows); + } + + if (filters?.length) { + rowOrders = filterBy(rowOrders ?? originalRowOrders, filters, fields, rows); + } + + if (rowOrders) { + setRowOrders(rowOrders); + } else { + setRowOrders(originalRowOrders); + } + }, [fields, filters, rows, sorts, view, isDatabaseRowPage]); useEffect(() => { - const onConditionsChange = () => { - const originalRowOrders = view?.get(YjsDatabaseKey.row_orders).toJSON(); - - if (!originalRowOrders || !rows) return; - - if (sorts?.length === 0 && filters?.length === 0) { - setRowOrders(originalRowOrders); - return; - } - - let rowOrders: Row[] | undefined; - - if (sorts?.length) { - rowOrders = sortBy(originalRowOrders, sorts, fields, rows); - } - - if (filters?.length) { - rowOrders = filterBy(rowOrders ?? originalRowOrders, filters, fields, rows); - } - - if (rowOrders) { - setRowOrders(rowOrders); - } else { - setRowOrders(originalRowOrders); - } - }; - - const debounceConditionsChange = debounce(onConditionsChange, 200); - onConditionsChange(); - sorts?.observeDeep(debounceConditionsChange); - filters?.observeDeep(debounceConditionsChange); - fields?.observeDeep(debounceConditionsChange); - rows?.observeDeep(debounceConditionsChange); + }, [onConditionsChange, clock]); + + useEffect(() => { + const throttleChange = throttle(onConditionsChange, 200); + + sorts?.observeDeep(throttleChange); + filters?.observeDeep(throttleChange); + fields?.observeDeep(throttleChange); return () => { - sorts?.unobserveDeep(debounceConditionsChange); - filters?.unobserveDeep(debounceConditionsChange); - fields?.unobserveDeep(debounceConditionsChange); - rows?.observeDeep(debounceConditionsChange); + sorts?.unobserveDeep(throttleChange); + filters?.unobserveDeep(throttleChange); + fields?.unobserveDeep(throttleChange); }; - }, [fields, rows, sorts, filters, view]); + }, [onConditionsChange, fields, filters, sorts]); return rowOrders; } +export function useRowDocMapSelector() { + const rowMap = useRowDocMap(); + const [clock, setClock] = useState(0); + + useEffect(() => { + if (!rowMap) return; + const observerEvent = () => setClock((prev) => prev + 1); + + const rowIds = Array.from(rowMap?.keys() || []); + + rowMap.observe(observerEvent); + + const observers = rowIds.map((rowId) => { + return observeDeepRow(rowId, rowMap, observerEvent); + }); + + return () => { + rowMap.unobserve(observerEvent); + observers.forEach((observer) => observer()); + }; + }, [rowMap]); + + return { + rows: rowMap, + clock, + }; +} + +export function observeDeepRow( + rowId: string, + rowMap: Y.Map, + observerEvent: () => void, + key: YjsEditorKey.meta | YjsEditorKey.database_row = YjsEditorKey.database_row +) { + const rowSharedRoot = rowMap?.get(rowId)?.getMap(YjsEditorKey.data_section); + const row = rowSharedRoot?.get(key); + + rowSharedRoot?.observe(observerEvent); + row?.observeDeep(observerEvent); + return () => { + rowSharedRoot?.unobserve(observerEvent); + row?.unobserveDeep(observerEvent); + }; +} + +export function useRowDataSelector(rowId: string) { + const rowMap = useRowDocMap(); + const rowSharedRoot = rowMap?.get(rowId)?.getMap(YjsEditorKey.data_section); + const row = rowSharedRoot?.get(YjsEditorKey.database_row); + + const [clock, setClock] = useState(0); + + useEffect(() => { + if (!rowMap) return; + const onChange = () => { + setClock((prev) => prev + 1); + }; + + const observer = observeDeepRow(rowId, rowMap, onChange); + + rowMap.observe(onChange); + + return () => { + rowMap.unobserve(onChange); + observer(); + }; + }, [rowId, rowMap]); + + return { + row, + clock, + }; +} + export function useCellSelector({ rowId, fieldId }: { rowId: string; fieldId: string }) { - const row = useRowData(rowId); + const { row } = useRowDataSelector(rowId); + const cell = row?.get(YjsDatabaseKey.cells)?.get(fieldId); const [cellValue, setCellValue] = useState(() => (cell ? parseYDatabaseCellToCell(cell) : undefined)); @@ -504,7 +606,7 @@ export function useCalendarEventsSelector() { const filedId = setting.fieldId; const { field } = useFieldSelector(filedId); const rowOrders = useRowOrdersSelector(); - const rows = useContext(DatabaseContext)?.rowDocMap; + const rows = useRowDocMap(); const [events, setEvents] = useState([]); const [emptyEvents, setEmptyEvents] = useState([]); @@ -610,35 +712,67 @@ export interface RowMeta { isEmptyDocument: boolean; } +const metaIdMapFromRowIdMap = new Map>(); + +function getMetaIdMap(rowId: string) { + const hasMetaIdMap = metaIdMapFromRowIdMap.has(rowId); + + if (!hasMetaIdMap) { + const parser = metaIdFromRowId(rowId); + const map = new Map(); + + map.set(RowMetaKey.IconId, parser(RowMetaKey.IconId)); + map.set(RowMetaKey.CoverId, parser(RowMetaKey.CoverId)); + map.set(RowMetaKey.DocumentId, parser(RowMetaKey.DocumentId)); + map.set(RowMetaKey.IsDocumentEmpty, parser(RowMetaKey.IsDocumentEmpty)); + metaIdMapFromRowIdMap.set(rowId, map); + return map; + } + + return metaIdMapFromRowIdMap.get(rowId) as Map; +} + export const useRowMetaSelector = (rowId: string) => { const [meta, setMeta] = useState(); - const yMeta = useRow(rowId)?.get(YjsEditorKey.meta); + const rowMap = useRowDocMap(); + + const updateMeta = useCallback(() => { + const metaKeyMap = getMetaIdMap(rowId); + + const iconKey = metaKeyMap.get(RowMetaKey.IconId) ?? ''; + const coverKey = metaKeyMap.get(RowMetaKey.CoverId) ?? ''; + const documentId = metaKeyMap.get(RowMetaKey.DocumentId) ?? ''; + const isEmptyDocumentKey = metaKeyMap.get(RowMetaKey.IsDocumentEmpty) ?? ''; + const rowSharedRoot = rowMap?.get(rowId)?.getMap(YjsEditorKey.data_section); + const yMeta = rowSharedRoot?.get(YjsEditorKey.meta); + + if (!yMeta) return; + const metaJson = yMeta.toJSON(); + + const icon = metaJson[iconKey]; + const cover = metaJson[coverKey]; + const isEmptyDocument = metaJson[isEmptyDocumentKey]; + + setMeta({ + icon, + cover, + documentId, + isEmptyDocument, + }); + }, [rowId, rowMap]); useEffect(() => { - if (!yMeta) return; - const onChange = () => { - const metaJson = yMeta.toJSON(); - const getData = metaIdFromRowId(rowId); - const icon = metaJson[getData(RowMetaKey.IconId)]; - const cover = metaJson[getData(RowMetaKey.CoverId)]; - const documentId = getData(RowMetaKey.DocumentId); - const isEmptyDocument = metaJson[getData(RowMetaKey.IsDocumentEmpty)]; + if (!rowMap) return; + updateMeta(); + const observer = observeDeepRow(rowId, rowMap, updateMeta, YjsEditorKey.meta); - return setMeta({ - icon, - cover, - documentId, - isEmptyDocument, - }); - }; + rowMap.observe(updateMeta); - onChange(); - - yMeta.observe(onChange); return () => { - yMeta.unobserve(onChange); + rowMap.unobserve(updateMeta); + observer(); }; - }, [rowId, yMeta]); + }, [rowId, rowMap, updateMeta]); return meta; }; diff --git a/frontend/appflowy_web_app/src/application/database-yjs/sort.ts b/frontend/appflowy_web_app/src/application/database-yjs/sort.ts index f229ce8f74..43ba0408a5 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/sort.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/sort.ts @@ -10,7 +10,7 @@ import { import { FieldType, SortCondition } from '@/application/database-yjs/database.type'; import { parseChecklistData, parseSelectOptionCellData } from '@/application/database-yjs/fields'; import { Row } from '@/application/database-yjs/selector'; -import orderBy from 'lodash-es/orderBy'; +import { orderBy } from 'lodash-es'; import * as Y from 'yjs'; export function sortBy(rows: Row[], sorts: YDatabaseSorts, fields: YDatabaseFields, rowMetas: Y.Map) { diff --git a/frontend/appflowy_web_app/src/application/folder-yjs/context.ts b/frontend/appflowy_web_app/src/application/folder-yjs/context.ts index 57c4d171df..02a2cfcba4 100644 --- a/frontend/appflowy_web_app/src/application/folder-yjs/context.ts +++ b/frontend/appflowy_web_app/src/application/folder-yjs/context.ts @@ -1,8 +1,49 @@ -import { YFolder } from '@/application/collab.type'; -import { createContext, useContext } from 'react'; +import { ViewLayout, YFolder, YjsFolderKey } from '@/application/collab.type'; +import { createContext, useCallback, useContext } from 'react'; +import { useParams } from 'react-router-dom'; -export const FolderContext = createContext(null); +export interface Crumb { + viewId: string; + rowId?: string; + name: string; + icon: string; +} + +export const FolderContext = createContext<{ + folder: YFolder | null; + onNavigateToView?: (viewId: string) => void; + crumbs?: Crumb[]; + setCrumbs?: React.Dispatch>; +} | null>(null); export const useFolderContext = () => { - return useContext(FolderContext); + return useContext(FolderContext)?.folder; +}; + +export const useViewLayout = () => { + const folder = useFolderContext(); + const { objectId } = useParams(); + const views = folder?.get(YjsFolderKey.views); + const view = objectId ? views?.get(objectId) : null; + + return Number(view?.get(YjsFolderKey.layout)) as ViewLayout; +}; + +export const useNavigateToView = () => { + return useContext(FolderContext)?.onNavigateToView; +}; + +export const useCrumbs = () => { + return useContext(FolderContext)?.crumbs; +}; + +export const usePushCrumb = () => { + const { setCrumbs } = useContext(FolderContext) || {}; + + return useCallback( + (crumb: Crumb) => { + setCrumbs?.((prevCrumbs) => [...prevCrumbs, crumb]); + }, + [setCrumbs] + ); }; diff --git a/frontend/appflowy_web_app/src/application/folder-yjs/folder.type.ts b/frontend/appflowy_web_app/src/application/folder-yjs/folder.type.ts new file mode 100644 index 0000000000..ce9bebcefb --- /dev/null +++ b/frontend/appflowy_web_app/src/application/folder-yjs/folder.type.ts @@ -0,0 +1,9 @@ +export enum CoverType { + NormalColor = 'color', + GradientColor = 'gradient', + BuildInImage = 'built_in', + CustomImage = 'custom', + LocalImage = 'local', + UpsplashImage = 'unsplash', + None = 'none', +} diff --git a/frontend/appflowy_web_app/src/application/folder-yjs/selector.ts b/frontend/appflowy_web_app/src/application/folder-yjs/selector.ts index e5eb68203e..8e43efbf6a 100644 --- a/frontend/appflowy_web_app/src/application/folder-yjs/selector.ts +++ b/frontend/appflowy_web_app/src/application/folder-yjs/selector.ts @@ -10,7 +10,9 @@ export function useViewsIdSelector() { const meta = folder?.get(YjsFolderKey.meta); useEffect(() => { - if (!views) return; + if (!views) { + return; + } const trashUid = trash ? Array.from(trash.keys())[0] : null; const userTrash = trashUid ? trash?.get(trashUid) : null; @@ -54,10 +56,10 @@ export function useViewSelector(viewId: string) { setView(view || null); const observerEvent = () => setClock((prev) => prev + 1); - view.observe(observerEvent); + view?.observe(observerEvent); return () => { - view.unobserve(observerEvent); + view?.unobserve(observerEvent); }; }, [folder, viewId]); diff --git a/frontend/appflowy_web_app/src/application/services/js-services/database.service.ts b/frontend/appflowy_web_app/src/application/services/js-services/database.service.ts index e80915c393..b1dcfe8d0f 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/database.service.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/database.service.ts @@ -1,9 +1,9 @@ -import { CollabOrigin, CollabType, YDatabase, YDoc, YjsDatabaseKey, YjsEditorKey } from '@/application/collab.type'; +import { CollabType, YDatabase, YDoc, YjsDatabaseKey, YjsEditorKey } from '@/application/collab.type'; import { batchCollabs, getCollabStorage, getCollabStorageWithAPICall, - getUserWorkspace, + getCurrentWorkspace, } from '@/application/services/js-services/storage'; import { DatabaseService } from '@/application/services/services.type'; import * as Y from 'yjs'; @@ -11,21 +11,63 @@ import * as Y from 'yjs'; export class JSDatabaseService implements DatabaseService { private loadedDatabaseId: Set = new Set(); + private cacheDatabaseRowDocMap: Map = new Map(); + constructor() { // } - async getDatabase( - workspaceId: string, + currentWorkspace() { + return getCurrentWorkspace(); + } + + async getWorkspaceDatabases(): Promise<{ views: string[]; database_id: string }[]> { + const workspace = await this.currentWorkspace(); + + if (!workspace) { + throw new Error('Workspace database not found'); + } + + const workspaceDatabase = await getCollabStorageWithAPICall( + workspace.id, + workspace.workspaceDatabaseId, + CollabType.WorkspaceDatabase + ); + + return workspaceDatabase.getMap(YjsEditorKey.data_section).get(YjsEditorKey.workspace_database).toJSON() as { + views: string[]; + database_id: string; + }[]; + } + + async openDatabase( databaseId: string, rowIds?: string[] ): Promise<{ databaseDoc: YDoc; rows: Y.Map; }> { - const rootRowsDoc = new Y.Doc(); - const rowsFolder = rootRowsDoc.getMap(); + const workspace = await this.currentWorkspace(); + + if (!workspace) { + throw new Error('Workspace database not found'); + } + + const workspaceId = workspace.id; const isLoaded = this.loadedDatabaseId.has(databaseId); + + const rootRowsDoc = + this.cacheDatabaseRowDocMap.get(databaseId) ?? + new Y.Doc({ + guid: databaseId, + }); + + if (!this.cacheDatabaseRowDocMap.has(databaseId)) { + this.cacheDatabaseRowDocMap.set(databaseId, rootRowsDoc); + } + + const rowsFolder: Y.Map = rootRowsDoc.getMap(); + let databaseDoc: YDoc | undefined = undefined; if (isLoaded) { @@ -51,13 +93,15 @@ export class JSDatabaseService implements DatabaseService { for (const id of ids) { const { doc } = await getCollabStorage(id, CollabType.DatabaseRow); - rowsFolder.set(id, doc); + if (!rowsFolder.has(id)) { + rowsFolder.set(id, doc); + } } } else { - const rows = await this.loadDatabaseRows(workspaceId, ids); - - rows.forEach((row, id) => { - rowsFolder.set(id, row); + void this.loadDatabaseRows(workspaceId, ids, (id, row) => { + if (!rowsFolder.has(id)) { + rowsFolder.set(id, row); + } }); } @@ -74,86 +118,24 @@ export class JSDatabaseService implements DatabaseService { console.log('Update rows', rowIds); void this.loadDatabaseRows( workspaceId, - rowIds.map((item) => item.id) - ).then((newRows) => { - newRows.forEach((row, id) => { - rowsFolder.set(id, row); - }); - }); + rowIds.map((item) => item.id), + (rowId: string, rowDoc) => { + if (!rowsFolder.has(rowId)) { + rowsFolder.set(rowId, rowDoc); + } + } + ); } }); } return { databaseDoc, - rows: rowsFolder as Y.Map, + rows: rowsFolder, }; } - async openDatabase( - workspaceId: string, - viewId: string, - rowIds?: string[] - ): Promise<{ - databaseDoc: YDoc; - rows: Y.Map; - }> { - const userWorkspace = await getUserWorkspace(); - - if (!userWorkspace) { - throw new Error('User workspace not found'); - } - - const workspaceDatabaseId = userWorkspace.workspaces.find( - (workspace) => workspace.id === workspaceId - )?.workspaceDatabaseId; - - if (!workspaceDatabaseId) { - throw new Error('Workspace database not found'); - } - - const workspaceDatabase = await getCollabStorageWithAPICall( - workspaceId, - workspaceDatabaseId, - CollabType.WorkspaceDatabase - ); - - const databases = workspaceDatabase - .getMap(YjsEditorKey.data_section) - .get(YjsEditorKey.workspace_database) - .toJSON() as { - views: string[]; - database_id: string; - }[]; - - const databaseMeta = databases.find((item) => { - return item.views.some((databaseViewId: string) => databaseViewId === viewId); - }); - - if (!databaseMeta) { - throw new Error('Database not found'); - } - - const { databaseDoc, rows } = await this.getDatabase(workspaceId, databaseMeta.database_id, rowIds); - - const handleUpdate = (update: Uint8Array, origin: CollabOrigin) => { - if (origin === CollabOrigin.LocalSync) { - // Send the update to the server - console.log('update', update); - } - }; - - databaseDoc.on('update', handleUpdate); - - return { - databaseDoc, - rows, - }; - } - - async loadDatabaseRows(workspaceId: string, rowIds: string[]) { - const rows = new Map(); - + async loadDatabaseRows(workspaceId: string, rowIds: string[], rowCallback: (rowId: string, rowDoc: YDoc) => void) { try { await batchCollabs( workspaceId, @@ -161,12 +143,14 @@ export class JSDatabaseService implements DatabaseService { object_id: id, collab_type: CollabType.DatabaseRow, })), - (id, rowDoc) => rows.set(id, rowDoc) + rowCallback ); } catch (e) { console.error(e); } + } - return rows; + async closeDatabase(databaseId: string) { + this.cacheDatabaseRowDocMap.delete(databaseId); } } diff --git a/frontend/appflowy_web_app/src/application/services/js-services/db/index.ts b/frontend/appflowy_web_app/src/application/services/js-services/db/index.ts index bf5f0c7aa1..f17ac50531 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/db/index.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/db/index.ts @@ -10,6 +10,7 @@ import * as Y from 'yjs'; export async function openCollabDB(docName: string): Promise { const name = `${databasePrefix}_${docName}`; const doc = new Y.Doc(); + const provider = new IndexeddbPersistence(name, doc); let resolve: (value: unknown) => void; @@ -26,14 +27,6 @@ export async function openCollabDB(docName: string): Promise { return doc as YDoc; } -export async function deleteCollabDB(docName: string) { - const name = `${databasePrefix}_${docName}`; - const doc = new Y.Doc(); - const provider = new IndexeddbPersistence(name, doc); - - await provider.destroy(); -} - export function getDBName(id: string, type: string) { const { uuid } = getAuthInfo() || {}; diff --git a/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts b/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts index e93809449d..cc3d3dd411 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/document.service.ts @@ -1,5 +1,5 @@ import { CollabOrigin, CollabType, YDoc } from '@/application/collab.type'; -import { getCollabStorageWithAPICall } from '@/application/services/js-services/storage'; +import { getCollabStorageWithAPICall, getCurrentWorkspace } from '@/application/services/js-services/storage'; import { DocumentService } from '@/application/services/services.type'; export class JSDocumentService implements DocumentService { @@ -7,8 +7,14 @@ export class JSDocumentService implements DocumentService { // } - async openDocument(workspaceId: string, docId: string): Promise { - const doc = await getCollabStorageWithAPICall(workspaceId, docId, CollabType.Document); + async openDocument(docId: string): Promise { + const workspace = await getCurrentWorkspace(); + + if (!workspace) { + throw new Error('Workspace database not found'); + } + + const doc = await getCollabStorageWithAPICall(workspace.id, docId, CollabType.Document); const handleUpdate = (update: Uint8Array, origin: CollabOrigin) => { if (origin === CollabOrigin.LocalSync) { diff --git a/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts b/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts index bdc1392024..b41f1861ab 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts @@ -1,4 +1,4 @@ -import { CollabType, YDoc, YjsEditorKey } from '@/application/collab.type'; +import { CollabType, YDoc, YjsEditorKey, YSharedRoot } from '@/application/collab.type'; import { getDBName, openCollabDB } from '@/application/services/js-services/db'; import { APIService } from '@/application/services/js-services/wasm'; import { applyYDoc } from '@/application/ydoc/apply'; @@ -30,11 +30,28 @@ function collabTypeToDBType(type: CollabType) { } } +const collabSharedRootKeyMap = { + [CollabType.Folder]: YjsEditorKey.folder, + [CollabType.Document]: YjsEditorKey.document, + [CollabType.Database]: YjsEditorKey.database, + [CollabType.WorkspaceDatabase]: YjsEditorKey.workspace_database, + [CollabType.DatabaseRow]: YjsEditorKey.database_row, + [CollabType.UserAwareness]: YjsEditorKey.user_awareness, + [CollabType.Empty]: YjsEditorKey.empty, +}; + export async function getCollabStorage(id: string, type: CollabType) { const name = getDBName(id, collabTypeToDBType(type)); const doc = await openCollabDB(name); - const localExist = doc.share.has(YjsEditorKey.data_section); + let localExist = false; + const existData = doc.share.has(YjsEditorKey.data_section); + + if (existData) { + const data = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; + + localExist = data.has(collabSharedRootKeyMap[type] as string); + } return { doc, @@ -74,28 +91,27 @@ export async function batchCollabs( for (const item of params) { const { object_id, collab_type } = item; - const { doc } = await getCollabStorage(object_id, collab_type); + const { doc, localExist } = await getCollabStorage(object_id, collab_type); - if (rowCallback) { + if (rowCallback && localExist) { rowCallback(object_id, doc); } } - // Async fetch collab data and apply to Y.Doc - void (async () => { - const res = await batchFetchCollab(workspaceId, params); + const res = await batchFetchCollab(workspaceId, params); - for (const id of Object.keys(res)) { - const type = params.find((param) => param.object_id === id)?.collab_type; - const data = res[id]; + for (const id of Object.keys(res)) { + const type = params.find((param) => param.object_id === id)?.collab_type; + const data = res[id]; - if (type === undefined || !data) { - continue; - } - - const { doc } = await getCollabStorage(id, type); - - applyYDoc(doc, data); + if (type === undefined || !data) { + continue; } - })(); + + const { doc } = await getCollabStorage(id, type); + + applyYDoc(doc, new Uint8Array(data)); + + rowCallback?.(id, doc); + } } diff --git a/frontend/appflowy_web_app/src/application/services/js-services/storage/user.ts b/frontend/appflowy_web_app/src/application/services/js-services/storage/user.ts index db9626ae8e..6fbab3f390 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/storage/user.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/storage/user.ts @@ -1,4 +1,4 @@ -import { UserProfile, UserWorkspace } from '@/application/user.type'; +import { UserProfile, UserWorkspace, Workspace } from '@/application/user.type'; const userKey = 'user'; const workspaceKey = 'workspace'; @@ -34,3 +34,10 @@ export async function setUserWorkspace(workspace: UserWorkspace) { localStorage.setItem(workspaceKey, str); } + +export async function getCurrentWorkspace(): Promise { + const userProfile = await getSignInUser(); + const userWorkspace = await getUserWorkspace(); + + return userWorkspace?.workspaces.find((workspace) => workspace.id === userProfile?.workspaceId); +} diff --git a/frontend/appflowy_web_app/src/application/services/js-services/wasm/client_api.ts b/frontend/appflowy_web_app/src/application/services/js-services/wasm/client_api.ts index f3fecb1215..6b50ca27e5 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/wasm/client_api.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/wasm/client_api.ts @@ -93,10 +93,10 @@ export async function batchGetCollab( })) )) as unknown as Map; - const result: Record = {}; + const result: Record = {}; res.forEach((value, key) => { - result[key] = new Uint8Array(value.doc_state); + result[key] = value.doc_state; }); return result; } diff --git a/frontend/appflowy_web_app/src/application/services/services.type.ts b/frontend/appflowy_web_app/src/application/services/services.type.ts index 1d6a7d45b0..1e837f1576 100644 --- a/frontend/appflowy_web_app/src/application/services/services.type.ts +++ b/frontend/appflowy_web_app/src/application/services/services.type.ts @@ -31,26 +31,19 @@ export interface AuthService { } export interface DocumentService { - openDocument: (workspaceId: string, docId: string) => Promise; + openDocument: (docId: string) => Promise; } export interface DatabaseService { + getWorkspaceDatabases: () => Promise<{ views: string[]; database_id: string }[]>; openDatabase: ( - workspaceId: string, - viewId: string, - rowIds?: string[] - ) => Promise<{ - databaseDoc: YDoc; - rows: Y.Map; - }>; - getDatabase: ( - workspaceId: string, databaseId: string, rowIds?: string[] ) => Promise<{ databaseDoc: YDoc; rows: Y.Map; }>; + closeDatabase: (databaseId: string) => Promise; } export interface UserService { diff --git a/frontend/appflowy_web_app/src/application/services/tauri-services/database.service.ts b/frontend/appflowy_web_app/src/application/services/tauri-services/database.service.ts index 8644914ca7..d7909679fb 100644 --- a/frontend/appflowy_web_app/src/application/services/tauri-services/database.service.ts +++ b/frontend/appflowy_web_app/src/application/services/tauri-services/database.service.ts @@ -7,20 +7,15 @@ export class TauriDatabaseService implements DatabaseService { // } - async openDatabase( - _workspaceId: string, - _viewId: string - ): Promise<{ - databaseDoc: YDoc; - rows: Y.Map; - }> { + async getWorkspaceDatabases(): Promise<{ views: string[]; database_id: string }[]> { return Promise.reject('Not implemented'); } - async getDatabase( - _workspaceId: string, - _databaseId: string - ): Promise<{ + async closeDatabase(_databaseId: string) { + return Promise.reject('Not implemented'); + } + + async openDatabase(_viewId: string): Promise<{ databaseDoc: YDoc; rows: Y.Map; }> { diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/plugins/withYjs.ts b/frontend/appflowy_web_app/src/application/slate-yjs/plugins/withYjs.ts index dd3ec137d7..837063fd1d 100644 --- a/frontend/appflowy_web_app/src/application/slate-yjs/plugins/withYjs.ts +++ b/frontend/appflowy_web_app/src/application/slate-yjs/plugins/withYjs.ts @@ -1,6 +1,5 @@ import { CollabOrigin, YjsEditorKey, YSharedRoot } from '@/application/collab.type'; -import { applySlateOp } from '@/application/slate-yjs/utils/applySlateOpts'; -import { translateYjsEvent } from 'src/application/slate-yjs/utils/translateYjsEvent'; +import { applyToYjs } from '@/application/slate-yjs/utils/applyToYjs'; import { Editor, Operation, Descendant } from 'slate'; import Y, { YEvent, Transaction } from 'yjs'; import { yDocToSlateContent } from '@/application/slate-yjs/utils/convert'; @@ -57,44 +56,52 @@ export const YjsEditor = { export function withYjs( editor: T, doc: Y.Doc, - { - localOrigin, - includeRoot = true, - }: { + opts?: { localOrigin: CollabOrigin; - includeRoot?: boolean; } ): T & YjsEditor { + const { localOrigin = CollabOrigin.Local } = opts ?? {}; const e = editor as T & YjsEditor; const { apply, onChange } = e; e.sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; const initializeDocumentContent = () => { - const content = yDocToSlateContent(doc, includeRoot); + const content = yDocToSlateContent(doc); if (!content) { return; } e.children = content.children; + + console.log('initializeDocumentContent', doc.getMap(YjsEditorKey.data_section).toJSON(), e.children); Editor.normalize(editor, { force: true }); }; - e.applyRemoteEvents = (events: Array>, _: Transaction) => { - YjsEditor.flushLocalChanges(e); + const applyIntercept = (op: Operation) => { + if (YjsEditor.connected(e)) { + YjsEditor.storeLocalChange(e, op); + } - // TODO: handle remote events - // This is a temporary implementation to apply remote events to slate + apply(op); + }; + + const applyRemoteIntercept = (op: Operation) => { + apply(op); + }; + + e.applyRemoteEvents = (_events: Array>, _: Transaction) => { + // Flush local changes to ensure all local changes are applied before processing remote events + YjsEditor.flushLocalChanges(e); + // Replace the apply function to avoid storing remote changes as local changes + e.apply = applyRemoteIntercept; + + // Initialize or update the document content to ensure it is in the correct state before applying remote events initializeDocumentContent(); - Editor.withoutNormalizing(editor, () => { - events.forEach((event) => { - translateYjsEvent(e.sharedRoot, editor, event).forEach((op) => { - // apply remote events to slate, don't call e.apply here because e.apply has been overridden. - apply(op); - }); - }); - }); + + // Restore the apply function to store local changes after applying remote changes + e.apply = applyIntercept; }; const handleYEvents = (events: Array>, transaction: Transaction) => { @@ -135,18 +142,12 @@ export function withYjs( // parse changes and apply to ydoc doc.transact(() => { changes.forEach((change) => { - applySlateOp(doc, { children: change.slateContent }, change.op); + applyToYjs(doc, { children: change.slateContent }, change.op); }); }, localOrigin); }; - e.apply = (op) => { - if (YjsEditor.connected(e)) { - YjsEditor.storeLocalChange(e, op); - } - - apply(op); - }; + e.apply = applyIntercept; e.onChange = () => { if (YjsEditor.connected(e)) { diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/applyRemoteEvents.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/applyRemoteEvents.ts new file mode 100644 index 0000000000..7348ce0029 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/applyRemoteEvents.ts @@ -0,0 +1,67 @@ +import { + CollabOrigin, + YBlocks, + YChildrenMap, + YjsEditorKey, + YMeta, + YSharedRoot, + YTextMap, +} from '@/application/collab.type'; +import { yDocToSlateContent } from '@/application/slate-yjs/utils/convert'; +import { generateId, withTestingYDoc, withTestingYjsEditor } from './withTestingYjsEditor'; +import { createEditor } from 'slate'; +import { expect } from '@jest/globals'; +import * as Y from 'yjs'; + +export async function runApplyRemoteEventsTest() { + const pageId = generateId(); + const remoteDoc = withTestingYDoc(pageId); + const remote = withTestingYjsEditor(createEditor(), remoteDoc); + + const localDoc = new Y.Doc(); + + Y.applyUpdateV2(localDoc, Y.encodeStateAsUpdateV2(remoteDoc)); + const editor = withTestingYjsEditor(createEditor(), localDoc); + + editor.connect(); + expect(editor.children).toEqual(remote.children); + + // update remote doc + insertBlock(remoteDoc, generateId(), pageId, 0); + remote.children = yDocToSlateContent(remoteDoc)?.children ?? []; + + // apply remote changes to local doc + Y.transact( + localDoc, + () => { + Y.applyUpdateV2(localDoc, Y.encodeStateAsUpdateV2(remoteDoc)); + }, + CollabOrigin.Remote + ); + + expect(editor.children).toEqual(remote.children); +} + +function insertBlock(doc: Y.Doc, blockId: string, parentId: string, index: number) { + const sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; + const document = sharedRoot.get(YjsEditorKey.document); + const blocks = document.get(YjsEditorKey.blocks) as YBlocks; + const meta = document.get(YjsEditorKey.meta) as YMeta; + const childrenMap = meta.get(YjsEditorKey.children_map) as YChildrenMap; + const textMap = meta.get(YjsEditorKey.text_map) as YTextMap; + + const block = new Y.Map(); + + block.set(YjsEditorKey.block_id, blockId); + block.set(YjsEditorKey.block_children, blockId); + block.set(YjsEditorKey.block_type, 'paragraph'); + block.set(YjsEditorKey.block_data, '{}'); + block.set(YjsEditorKey.block_external_id, blockId); + blocks.set(blockId, block); + childrenMap.set(blockId, new Y.Array()); + childrenMap.get(parentId).insert(index, [blockId]); + const text = new Y.Text(); + + text.insert(0, 'Hello, World!'); + textMap.set(blockId, text); +} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/convert.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/convert.ts new file mode 100644 index 0000000000..ef0c26b054 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/convert.ts @@ -0,0 +1,41 @@ +import { withTestingYDoc, withTestingYjsEditor } from './withTestingYjsEditor'; +import { yDocToSlateContent } from '../convert'; +import { createEditor, Editor } from 'slate'; +import { expect } from '@jest/globals'; +import * as Y from 'yjs'; + +function normalizedSlateDoc(doc: Y.Doc) { + const editor = createEditor(); + + const yjsEditor = withTestingYjsEditor(editor, doc); + + editor.children = yDocToSlateContent(doc)?.children ?? []; + return yjsEditor.children; +} + +export async function runCollaborationTest() { + const doc = withTestingYDoc('1'); + const editor = createEditor(); + const yjsEditor = withTestingYjsEditor(editor, doc); + + // Keep the 'local' editor state before applying run. + const baseState = Y.encodeStateAsUpdateV2(doc); + + Editor.normalize(editor, { force: true }); + + expect(normalizedSlateDoc(doc)).toEqual(yjsEditor.children); + + // Setup remote editor with input base state + const remoteDoc = new Y.Doc(); + + Y.applyUpdateV2(remoteDoc, baseState); + const remote = withTestingYjsEditor(createEditor(), remoteDoc); + + // Apply changes from 'run' + Y.applyUpdateV2(remoteDoc, Y.encodeStateAsUpdateV2(yjsEditor.sharedRoot.doc!)); + + // Verify remote and editor state are equal + expect(normalizedSlateDoc(remoteDoc)).toEqual(remote.children); + expect(yjsEditor.children).toEqual(remote.children); + expect(normalizedSlateDoc(doc)).toEqual(yjsEditor.children); +} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/index.test.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/index.test.ts new file mode 100644 index 0000000000..bcbd87176f --- /dev/null +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/index.test.ts @@ -0,0 +1,12 @@ +import { runCollaborationTest } from './convert'; +import { runApplyRemoteEventsTest } from './applyRemoteEvents'; + +describe('slate-yjs adapter', () => { + it('should pass the collaboration test', async () => { + await runCollaborationTest(); + }); + + it('should pass the apply remote events test', async () => { + await runApplyRemoteEventsTest(); + }); +}); diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/withTestingYjsEditor.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/withTestingYjsEditor.ts new file mode 100644 index 0000000000..9d6922ad62 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/__tests__/withTestingYjsEditor.ts @@ -0,0 +1,45 @@ +import { CollabOrigin, YjsEditorKey, YSharedRoot } from '@/application/collab.type'; +import { withYjs } from '@/application/slate-yjs'; +import { Editor } from 'slate'; +import * as Y from 'yjs'; +import { v4 as uuidv4 } from 'uuid'; + +export function generateId() { + return uuidv4(); +} + +export function withTestingYjsEditor(editor: Editor, doc: Y.Doc) { + const yjdEditor = withYjs(editor, doc, { + localOrigin: CollabOrigin.LocalSync, + }); + + return yjdEditor; +} + +export function withTestingYDoc(docId: string) { + const doc = new Y.Doc(); + const sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; + const document = new Y.Map(); + const blocks = new Y.Map(); + const meta = new Y.Map(); + const children_map = new Y.Map(); + const text_map = new Y.Map(); + const rootBlock = new Y.Map(); + const blockOrders = new Y.Array(); + const pageId = docId; + + sharedRoot.set(YjsEditorKey.document, document); + document.set(YjsEditorKey.page_id, pageId); + document.set(YjsEditorKey.blocks, blocks); + document.set(YjsEditorKey.meta, meta); + meta.set(YjsEditorKey.children_map, children_map); + meta.set(YjsEditorKey.text_map, text_map); + children_map.set(pageId, blockOrders); + blocks.set(pageId, rootBlock); + rootBlock.set(YjsEditorKey.block_id, pageId); + rootBlock.set(YjsEditorKey.block_children, pageId); + rootBlock.set(YjsEditorKey.block_type, 'page'); + rootBlock.set(YjsEditorKey.block_data, '{}'); + rootBlock.set(YjsEditorKey.block_external_id, ''); + return doc; +} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/applySlateOpts.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/applySlateOpts.ts deleted file mode 100644 index 5a2fd6670c..0000000000 --- a/frontend/appflowy_web_app/src/application/slate-yjs/utils/applySlateOpts.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Operation, Node } from 'slate'; -import * as Y from 'yjs'; - -export function applySlateOp(ydoc: Y.Doc, slateRoot: Node, op: Operation) { - console.log('applySlateOp', op); -} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/applyToYjs.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/applyToYjs.ts new file mode 100644 index 0000000000..98daed4817 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/applyToYjs.ts @@ -0,0 +1,8 @@ +import { Operation, Node } from 'slate'; +import * as Y from 'yjs'; + +// transform slate op to yjs op and apply it to ydoc +export function applyToYjs(_ydoc: Y.Doc, _slateRoot: Node, op: Operation) { + if (op.type === 'set_selection') return; + console.log('applySlateOp', op); +} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/convert.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/convert.ts index ae8b6698e6..0cc5f372e9 100644 --- a/frontend/appflowy_web_app/src/application/slate-yjs/utils/convert.ts +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/convert.ts @@ -10,23 +10,14 @@ import { BlockData, BlockType, } from '@/application/collab.type'; +import { BlockJson } from '@/application/slate-yjs/utils/types'; import { getFontFamily } from '@/utils/font'; import { uniq } from 'lodash-es'; import { Element, Text } from 'slate'; -interface BlockJson { - id: string; - ty: string; - data?: string; - children?: string; - external_id?: string; -} - -export function yDocToSlateContent(doc: YDoc, includeRoot?: boolean): Element | undefined { - console.log(doc); +export function yDocToSlateContent(doc: YDoc): Element | undefined { const sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot; - console.log(sharedRoot.toJSON()); const document = sharedRoot.get(YjsEditorKey.document); const pageId = document.get(YjsEditorKey.page_id) as string; const blocks = document.get(YjsEditorKey.blocks) as YBlocks; @@ -107,13 +98,6 @@ export function yDocToSlateContent(doc: YDoc, includeRoot?: boolean): Element | if (!result) return; - if (!includeRoot) { - return result; - } - - const { children, ...rootNode } = result; - - // load font family if (fontFamilys.length > 0) { window.WebFont?.load({ google: { @@ -122,21 +106,7 @@ export function yDocToSlateContent(doc: YDoc, includeRoot?: boolean): Element | }); } - return { - children: [ - { - ...rootNode, - children: [ - { - textId: pageId, - type: YjsEditorKey.text, - children: [{ text: '' }], - }, - ], - }, - ...children, - ], - }; + return result; } export function blockToSlateNode(block: BlockJson): Element { @@ -151,6 +121,7 @@ export function blockToSlateNode(block: BlockJson): Element { return { blockId: block.id, + relationId: block.children, data: blockData, type: block.ty, children: [], diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/arrayEvent.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/arrayEvent.ts deleted file mode 100644 index 0565e8de92..0000000000 --- a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/arrayEvent.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { YSharedRoot } from '@/application/collab.type'; -import * as Y from 'yjs'; -import { Editor, Operation } from 'slate'; - -export function translateYArrayEvent( - _sharedRoot: YSharedRoot, - _editor: Editor, - _event: Y.YEvent> -): Operation[] { - return []; -} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/index.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/index.ts deleted file mode 100644 index c3f3bfd903..0000000000 --- a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { YSharedRoot } from '@/application/collab.type'; -import { translateYArrayEvent } from '@/application/slate-yjs/utils/translateYjsEvent/arrayEvent'; -import { translateYMapEvent } from '@/application/slate-yjs/utils/translateYjsEvent/mapEvent'; -import { Editor, Operation } from 'slate'; -import * as Y from 'yjs'; -import { translateYTextEvent } from 'src/application/slate-yjs/utils/translateYjsEvent/textEvent'; - -/** - * Translate a yjs event into slate operations. The editor state has to match the - * yText state before the event occurred. - * - * @param sharedType - * @param op - */ -export function translateYjsEvent(sharedRoot: YSharedRoot, editor: Editor, event: Y.YEvent): Operation[] { - if (event instanceof Y.YMapEvent) { - return translateYMapEvent(sharedRoot, editor, event); - } - - if (event instanceof Y.YTextEvent) { - return translateYTextEvent(sharedRoot, editor, event); - } - - if (event instanceof Y.YArrayEvent) { - return translateYArrayEvent(sharedRoot, editor, event); - } - - throw new Error('Unexpected Y event type'); -} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/mapEvent.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/mapEvent.ts deleted file mode 100644 index cab9831833..0000000000 --- a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/mapEvent.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { YSharedRoot } from '@/application/collab.type'; -import * as Y from 'yjs'; -import { Editor, Operation } from 'slate'; - -export function translateYMapEvent( - _sharedRoot: YSharedRoot, - _editor: Editor, - _event: Y.YEvent> -): Operation[] { - return []; -} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/textEvent.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/textEvent.ts deleted file mode 100644 index 2fc6deca73..0000000000 --- a/frontend/appflowy_web_app/src/application/slate-yjs/utils/translateYjsEvent/textEvent.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { YSharedRoot } from '@/application/collab.type'; -import * as Y from 'yjs'; -import { Editor, Operation } from 'slate'; - -export function translateYTextEvent(_sharedRoot: YSharedRoot, _editor: Editor, _event: Y.YEvent): Operation[] { - return []; -} diff --git a/frontend/appflowy_web_app/src/application/slate-yjs/utils/types.ts b/frontend/appflowy_web_app/src/application/slate-yjs/utils/types.ts new file mode 100644 index 0000000000..0dbe81a970 --- /dev/null +++ b/frontend/appflowy_web_app/src/application/slate-yjs/utils/types.ts @@ -0,0 +1,29 @@ +import { Node as SlateNode } from 'slate'; + +export interface BlockJson { + id: string; + ty: string; + data?: string; + children?: string; + external_id?: string; +} + +export interface Operation { + type: OperationType; +} + +export enum OperationType { + InsertNode = 'insert_node', + InsertChildren = 'insert_children', +} + +export interface InsertNodeOperation extends Operation { + type: OperationType.InsertNode; + node: SlateNode; +} + +export interface InsertChildrenOperation extends Operation { + type: OperationType.InsertChildren; + blockId: string; + children: string[]; +} diff --git a/frontend/appflowy_web_app/src/assets/cover/m_cover_image_1.png b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_1.png new file mode 100644 index 0000000000..fb72022287 Binary files /dev/null and b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_1.png differ diff --git a/frontend/appflowy_web_app/src/assets/cover/m_cover_image_2.png b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_2.png new file mode 100644 index 0000000000..9ecf02d253 Binary files /dev/null and b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_2.png differ diff --git a/frontend/appflowy_web_app/src/assets/cover/m_cover_image_3.png b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_3.png new file mode 100644 index 0000000000..97072b04f4 Binary files /dev/null and b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_3.png differ diff --git a/frontend/appflowy_web_app/src/assets/cover/m_cover_image_4.png b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_4.png new file mode 100644 index 0000000000..00d26a0500 Binary files /dev/null and b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_4.png differ diff --git a/frontend/appflowy_web_app/src/assets/cover/m_cover_image_5.png b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_5.png new file mode 100644 index 0000000000..3ecc9546c1 Binary files /dev/null and b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_5.png differ diff --git a/frontend/appflowy_web_app/src/assets/cover/m_cover_image_6.png b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_6.png new file mode 100644 index 0000000000..0abd2700e8 Binary files /dev/null and b/frontend/appflowy_web_app/src/assets/cover/m_cover_image_6.png differ diff --git a/frontend/appflowy_web_app/src/components/_shared/context-provider/FolderProvider.tsx b/frontend/appflowy_web_app/src/components/_shared/context-provider/FolderProvider.tsx index be466fdc49..37bb03533b 100644 --- a/frontend/appflowy_web_app/src/components/_shared/context-provider/FolderProvider.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/context-provider/FolderProvider.tsx @@ -1,9 +1,23 @@ import { YFolder } from '@/application/collab.type'; -import { FolderContext } from '@/application/folder-yjs'; +import { Crumb, FolderContext } from '@/application/folder-yjs'; -export const FolderProvider: React.FC<{ folder: YFolder | null; children?: React.ReactNode }> = ({ - folder, - children, -}) => { - return {children}; +export const FolderProvider: React.FC<{ + folder: YFolder | null; + children?: React.ReactNode; + onNavigateToView?: (viewId: string) => void; + crumbs?: Crumb[]; + setCrumbs?: React.Dispatch>; +}> = ({ folder, children, onNavigateToView, crumbs, setCrumbs }) => { + return ( + + {children} + + ); }; diff --git a/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx b/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx index 15682f1c82..666554ff73 100644 --- a/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx @@ -3,7 +3,6 @@ import { useContext, createContext } from 'react'; export const IdContext = createContext(null); interface IdProviderProps { - workspaceId: string; objectId: string; } diff --git a/frontend/appflowy_web_app/src/components/_shared/not-found/RecordNotFound.tsx b/frontend/appflowy_web_app/src/components/_shared/not-found/RecordNotFound.tsx index 9216a92c69..76d0f7575c 100644 --- a/frontend/appflowy_web_app/src/components/_shared/not-found/RecordNotFound.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/not-found/RecordNotFound.tsx @@ -1,8 +1,9 @@ +import { getCurrentWorkspace } from '@/application/services/js-services/storage'; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from '@mui/material'; import React from 'react'; import { useNavigate } from 'react-router-dom'; -export function RecordNotFound({ open, workspaceId }: { workspaceId: string; open: boolean }) { +export function RecordNotFound({ open, title }: { open: boolean; title?: string }) { const navigate = useNavigate(); return ( @@ -10,13 +11,16 @@ export function RecordNotFound({ open, workspaceId }: { workspaceId: string; ope Oops.. something went wrong - Sorry, the page you are looking for does not exist. + {title ? title : 'The record you are looking for does not exist.'} - +
+ {primaryFieldId && } {fields.map((field) => { return ; })} diff --git a/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaperTitle.tsx b/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaperTitle.tsx new file mode 100644 index 0000000000..6ede73fd99 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaperTitle.tsx @@ -0,0 +1,15 @@ +import { useCellSelector } from '@/application/database-yjs'; +import { TextCell } from '@/components/database/components/cell/cell.type'; +import { TextProperty } from '@/components/database/components/property/text'; +import React from 'react'; + +function EventPaperTitle({ fieldId, rowId }: { fieldId: string; rowId: string }) { + const cell = useCellSelector({ + fieldId, + rowId, + }); + + return ; +} + +export default EventPaperTitle; diff --git a/frontend/appflowy_web_app/src/components/database/components/calendar/toolbar/NoDate.tsx b/frontend/appflowy_web_app/src/components/database/components/calendar/toolbar/NoDate.tsx index 7965bc33b7..b6238185eb 100644 --- a/frontend/appflowy_web_app/src/components/database/components/calendar/toolbar/NoDate.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/calendar/toolbar/NoDate.tsx @@ -33,7 +33,7 @@ function NoDate({ emptyEvents }: { emptyEvents: CalendarEvent[] }) { - +
+ +
)}
); diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationCell.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationCell.tsx index 5bd8eb7b87..47ac405966 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationCell.tsx @@ -1,13 +1,17 @@ +import { FieldType } from '@/application/database-yjs'; import { CellProps, RelationCell as RelationCellType } from '@/components/database/components/cell/cell.type'; import RelationItems from '@/components/database/components/cell/relation/RelationItems'; import React from 'react'; export function RelationCell({ cell, fieldId, style, placeholder }: CellProps) { + if (cell?.fieldType !== FieldType.Relation) return null; + if (!cell?.data) return placeholder ? (
{placeholder}
) : null; + return ; } diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx index 6d68eee4af..fd63c28196 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx @@ -1,24 +1,32 @@ -import { YDatabaseField, YDatabaseFields, YDoc, YjsDatabaseKey, YjsEditorKey } from '@/application/collab.type'; -import { parseRelationTypeOption, useFieldSelector } from '@/application/database-yjs'; -import { useId } from '@/components/_shared/context-provider/IdProvider'; -import { AFConfigContext } from '@/components/app/AppConfig'; +import { YDatabaseField, YDatabaseFields, YjsDatabaseKey, YjsEditorKey } from '@/application/collab.type'; +import { + DatabaseContextState, + parseRelationTypeOption, + useDatabase, + useFieldSelector, + useNavigateToRow, +} from '@/application/database-yjs'; import { RelationCell, RelationCellData } from '@/components/database/components/cell/cell.type'; import { RelationPrimaryValue } from '@/components/database/components/cell/relation/RelationPrimaryValue'; -import React, { useContext, useEffect, useMemo, useState } from 'react'; -import * as Y from 'yjs'; +import { useGetDatabaseDispatch } from '@/components/database/Database.hooks'; +import React, { useEffect, useMemo, useState } from 'react'; function RelationItems({ style, cell, fieldId }: { cell: RelationCell; fieldId: string; style?: React.CSSProperties }) { const { field } = useFieldSelector(fieldId); - const workspaceId = useId()?.workspaceId; - const rowIds = useMemo(() => (cell.data.toJSON() as RelationCellData) ?? [], [cell.data]); + const currentDatabaseId = useDatabase()?.get(YjsDatabaseKey.id); + const { onOpenDatabase, onCloseDatabase } = useGetDatabaseDispatch(); + const rowIds = useMemo(() => { + return (cell.data?.toJSON() as RelationCellData) ?? []; + }, [cell.data]); const databaseId = rowIds.length > 0 && field ? parseRelationTypeOption(field).database_id : undefined; - const databaseService = useContext(AFConfigContext)?.service?.databaseService; const [databasePrimaryFieldId, setDatabasePrimaryFieldId] = useState(undefined); - const [rows, setRows] = useState | null>(); + const [rows, setRows] = useState(); + + const navigateToRow = useNavigateToRow(); useEffect(() => { - if (!workspaceId || !databaseId) return; - void databaseService?.getDatabase(workspaceId, databaseId, rowIds).then(({ databaseDoc: doc, rows }) => { + if (!databaseId || !rowIds.length) return; + void onOpenDatabase({ databaseId, rowIds }).then(({ databaseDoc: doc, rows }) => { const fields = doc .getMap(YjsEditorKey.data_section) .get(YjsEditorKey.database) @@ -32,7 +40,15 @@ function RelationItems({ style, cell, fieldId }: { cell: RelationCell; fieldId: setRows(rows); }); - }, [workspaceId, databaseId, databaseService, rowIds]); + }, [onOpenDatabase, databaseId, rowIds, onCloseDatabase]); + + useEffect(() => { + return () => { + if (currentDatabaseId !== databaseId && databaseId) { + onCloseDatabase(databaseId); + } + }; + }, [databaseId, currentDatabaseId, onCloseDatabase]); return (
@@ -40,7 +56,14 @@ function RelationItems({ style, cell, fieldId }: { cell: RelationCell; fieldId: const rowDoc = rows?.get(rowId); return ( -
+
{ + e.stopPropagation(); + navigateToRow?.(rowId); + }} + className={'w-full cursor-pointer underline'} + > {rowDoc && databasePrimaryFieldId && ( )} diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationPrimaryValue.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationPrimaryValue.tsx index 174a3693f0..0c33397eb8 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationPrimaryValue.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationPrimaryValue.tsx @@ -4,9 +4,24 @@ import React, { useEffect, useState } from 'react'; export function RelationPrimaryValue({ rowDoc, fieldId }: { rowDoc: YDoc; fieldId: FieldId }) { const [text, setText] = useState(null); + const [row, setRow] = useState(null); useEffect(() => { - const row = rowDoc.getMap(YjsEditorKey.data_section).get(YjsEditorKey.database_row) as YDatabaseRow; + const data = rowDoc.getMap(YjsEditorKey.data_section); + + const onRowChange = () => { + setRow(data?.get(YjsEditorKey.database_row) as YDatabaseRow); + }; + + onRowChange(); + data?.observe(onRowChange); + return () => { + data?.unobserve(onRowChange); + }; + }, [rowDoc]); + + useEffect(() => { + if (!row) return; const cells = row.get(YjsDatabaseKey.cells); const primaryCell = cells.get(fieldId); @@ -21,7 +36,7 @@ export function RelationPrimaryValue({ rowDoc, fieldId }: { rowDoc: YDoc; fieldI return () => { primaryCell.unobserve(observeHandler); }; - }, [rowDoc, fieldId]); + }, [row, fieldId]); return
{text}
; } diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx index 4d882b8c28..b4d048b14f 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx @@ -2,10 +2,15 @@ import { useReadOnly } from '@/application/database-yjs'; import { CellProps, TextCell as TextCellType } from '@/components/database/components/cell/cell.type'; import React from 'react'; -export function TextCell({ cell, style }: CellProps) { +export function TextCell({ cell, style, placeholder }: CellProps) { const readOnly = useReadOnly(); - if (!cell?.data) return null; + if (!cell?.data) + return placeholder ? ( +
+ {placeholder} +
+ ) : null; return (
{cell?.data} diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/url/UrlCell.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/url/UrlCell.tsx index 63e3c4cb10..0ee2c1d5bf 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/url/UrlCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/url/UrlCell.tsx @@ -30,9 +30,10 @@ export function UrlCell({ cell, style, placeholder }: CellProps) { return (
{ + onClick={(e) => { if (!isUrl || !cell) return; if (readOnly) { + e.stopPropagation(); void openUrl(cell.data, '_blank'); } }} diff --git a/frontend/appflowy_web_app/src/components/database/components/conditions/DatabaseActions.tsx b/frontend/appflowy_web_app/src/components/database/components/conditions/DatabaseActions.tsx index e095a0eacc..a7559374c2 100644 --- a/frontend/appflowy_web_app/src/components/database/components/conditions/DatabaseActions.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/conditions/DatabaseActions.tsx @@ -1,5 +1,4 @@ -import { DatabaseViewLayout, YjsDatabaseKey } from '@/application/collab.type'; -import { useDatabaseView, useFiltersSelector, useSortsSelector } from '@/application/database-yjs'; +import { useFiltersSelector, useSortsSelector } from '@/application/database-yjs'; import { useConditionsContext } from '@/components/database/components/conditions/context'; import { TextButton } from '@/components/database/components/tabs/TextButton'; import React from 'react'; @@ -7,16 +6,11 @@ import { useTranslation } from 'react-i18next'; export function DatabaseActions() { const { t } = useTranslation(); - const view = useDatabaseView(); - const layout = Number(view?.get(YjsDatabaseKey.layout)) as DatabaseViewLayout; + const sorts = useSortsSelector(); const filter = useFiltersSelector(); const conditionsContext = useConditionsContext(); - if (layout === DatabaseViewLayout.Calendar) { - return null; - } - return (
(null); - const [notFound, setNotFound] = useState(false); const documentService = useContext(AFConfigContext)?.service?.documentService; const handleOpenDocument = useCallback(async () => { - if (!documentService || !workspaceId || !documentId) return; + if (!documentService || !documentId) return; try { setDoc(null); - const doc = await documentService.openDocument(workspaceId, documentId); + const doc = await documentService.openDocument(documentId); + console.log('doc', doc); setDoc(doc); } catch (e) { - Log.error(e); - setNotFound(true); + console.error(e); + // haven't created by client, ignore error and show empty } - }, [documentService, workspaceId, documentId]); + }, [documentService, documentId]); useEffect(() => { - setNotFound(false); - void handleOpenDocument(); + setLoading(true); + void handleOpenDocument().then(() => setLoading(false)); }, [handleOpenDocument]); - if (notFound || !documentId) { - return ; - } - - if (!doc) { + if (loading) { return ( -
+
); } - return ; + if (!doc) return null; + + return ; } export default DatabaseRowSubDocument; diff --git a/frontend/appflowy_web_app/src/components/database/components/database-row/OpenAction.tsx b/frontend/appflowy_web_app/src/components/database/components/database-row/OpenAction.tsx new file mode 100644 index 0000000000..94b6977bca --- /dev/null +++ b/frontend/appflowy_web_app/src/components/database/components/database-row/OpenAction.tsx @@ -0,0 +1,27 @@ +import { ReactComponent as ExpandMoreIcon } from '$icons/16x/full_view.svg'; +import { useTranslation } from 'react-i18next'; +import { useNavigateToRow } from '@/application/database-yjs'; +import { Tooltip } from '@mui/material'; +import React from 'react'; + +function OpenAction({ rowId }: { rowId: string }) { + const navigateToRow = useNavigateToRow(); + + const { t } = useTranslation(); + + return ( + + + + ); +} + +export default OpenAction; diff --git a/frontend/appflowy_web_app/src/components/database/components/field/CardField.tsx b/frontend/appflowy_web_app/src/components/database/components/field/CardField.tsx index 585a3d2ce0..2575aa47ca 100644 --- a/frontend/appflowy_web_app/src/components/database/components/field/CardField.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/field/CardField.tsx @@ -14,13 +14,11 @@ function CardField({ rowId, fieldId, index }: { rowId: string; fieldId: string; const isPrimary = field?.get(YjsDatabaseKey.is_primary); const style = useMemo(() => { - const styleProperties = { - fontSize: '12px', - }; + const styleProperties = {}; if (isPrimary) { Object.assign(styleProperties, { - fontSize: '14px', + fontSize: '1.25em', fontWeight: 500, }); } diff --git a/frontend/appflowy_web_app/src/components/database/components/grid/grid-column/GridColumn.tsx b/frontend/appflowy_web_app/src/components/database/components/grid/grid-column/GridColumn.tsx index 88c6fae84e..56845e8425 100644 --- a/frontend/appflowy_web_app/src/components/database/components/grid/grid-column/GridColumn.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/grid/grid-column/GridColumn.tsx @@ -2,6 +2,7 @@ import { YjsDatabaseKey } from '@/application/collab.type'; import { FieldType } from '@/application/database-yjs/database.type'; import { Column, useFieldSelector } from '@/application/database-yjs/selector'; import { FieldTypeIcon } from '@/components/database/components/field'; +import { Tooltip } from '@mui/material'; import React, { useMemo } from 'react'; export function GridColumn({ column, index }: { column: Column; index: number }) { @@ -16,19 +17,21 @@ export function GridColumn({ column, index }: { column: Column; index: number }) }, [field]); return ( -
-
- + +
+
+ +
+
{name}
-
{name}
-
+ ); } diff --git a/frontend/appflowy_web_app/src/components/database/components/grid/grid-header/GridHeader.tsx b/frontend/appflowy_web_app/src/components/database/components/grid/grid-header/GridHeader.tsx index 64d0c39117..30dd0ffe9e 100644 --- a/frontend/appflowy_web_app/src/components/database/components/grid/grid-header/GridHeader.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/grid/grid-header/GridHeader.tsx @@ -1,5 +1,5 @@ -import React, { useCallback, useEffect, useRef } from 'react'; -import { GridChildComponentProps, VariableSizeGrid } from 'react-window'; +import React, { memo, useEffect, useRef } from 'react'; +import { areEqual, GridChildComponentProps, VariableSizeGrid } from 'react-window'; import AutoSizer from 'react-virtualized-auto-sizer'; import { GridColumnType, RenderColumn, GridColumn } from '../grid-column'; @@ -10,24 +10,25 @@ export interface GridHeaderProps { scrollLeft?: number; } +const Cell = memo(({ columnIndex, style, data }: GridChildComponentProps) => { + const column = data[columnIndex]; + + // Placeholder for Action toolbar + if (!column || column.type === GridColumnType.Action) return
; + + if (column.type === GridColumnType.Field) { + return ( +
+ +
+ ); + } + + return
; +}, areEqual); + export const GridHeader = ({ scrollLeft, onScrollLeft, columnWidth, columns }: GridHeaderProps) => { const ref = useRef(null); - const Cell = useCallback(({ columnIndex, style, data }: GridChildComponentProps) => { - const column = data[columnIndex]; - - // Placeholder for Action toolbar - if (!column || column.type === GridColumnType.Action) return
; - - if (column.type === GridColumnType.Field) { - return ( -
- -
- ); - } - - return
; - }, []); useEffect(() => { if (ref.current) { diff --git a/frontend/appflowy_web_app/src/components/database/components/grid/grid-row/GridRowCell.tsx b/frontend/appflowy_web_app/src/components/database/components/grid/grid-row/GridRowCell.tsx index 11f14135e3..51b7781008 100644 --- a/frontend/appflowy_web_app/src/components/database/components/grid/grid-row/GridRowCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/grid/grid-row/GridRowCell.tsx @@ -1,5 +1,6 @@ +import { areEqual } from 'react-window'; import { GridColumnType } from '../grid-column'; -import React from 'react'; +import React, { memo } from 'react'; import GridCell from '../grid-cell/GridCell'; export interface GridRowCellProps { @@ -11,7 +12,7 @@ export interface GridRowCellProps { onResize?: (rowIndex: number, columnIndex: number, size: { width: number; height: number }) => void; } -export function GridRowCell({ onResize, rowIndex, columnIndex, rowId, fieldId, type }: GridRowCellProps) { +export const GridRowCell = memo(({ onResize, rowIndex, columnIndex, rowId, fieldId, type }: GridRowCellProps) => { if (type === GridColumnType.Field && fieldId) { return ( @@ -23,6 +24,6 @@ export function GridRowCell({ onResize, rowIndex, columnIndex, rowId, fieldId, t } return null; -} +}, areEqual); export default GridRowCell; diff --git a/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx b/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx index ee39bfb957..41e52c5086 100644 --- a/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx @@ -1,5 +1,5 @@ -import { DEFAULT_ROW_HEIGHT } from '@/application/database-yjs/const'; import { AFScroller } from '@/components/_shared/scroller'; +import { useMeasureHeight } from '@/components/database/components/cell/useMeasure'; import { GridColumnType, RenderColumn } from '../grid-column'; import { GridCalculateRowCell, GridRowCell, RenderRowType, useRenderRows } from '../grid-row'; import React, { useCallback, useEffect, useRef } from 'react'; @@ -18,11 +18,14 @@ export interface GridTableProps { export const GridTable = ({ scrollLeft, columnWidth, columns, onScrollLeft }: GridTableProps) => { const ref = useRef(null); const { rows } = useRenderRows(); - const rowHeights = useRef<{ [key: string]: number }>({}); + const forceUpdate = useCallback((index: number) => { + ref.current?.resetAfterRowIndex(index, true); + }, []); + + const { rowHeight, onResize } = useMeasureHeight({ forceUpdate, rows }); useEffect(() => { if (ref.current) { - console.log(ref.current, scrollLeft); ref.current.scrollTo({ scrollLeft }); } }, [scrollLeft]); @@ -33,40 +36,6 @@ export const GridTable = ({ scrollLeft, columnWidth, columns, onScrollLeft }: Gr } }, [columns]); - const rowHeight = useCallback( - (index: number) => { - const row = rows[index]; - - if (!row || !row.rowId) return DEFAULT_ROW_HEIGHT; - - return rowHeights.current[row.rowId] || DEFAULT_ROW_HEIGHT; - }, - [rows] - ); - - const setRowHeight = useCallback( - (index: number, height: number) => { - const row = rows[index]; - const rowId = row.rowId; - - if (!row || !rowId) return; - const oldHeight = rowHeights.current[rowId]; - - rowHeights.current[rowId] = Math.max(oldHeight || DEFAULT_ROW_HEIGHT, height); - if (oldHeight !== height) { - ref.current?.resetAfterRowIndex(index, true); - } - }, - [rows] - ); - - const onResize = useCallback( - (rowIndex: number, columnIndex: number, size: { width: number; height: number }) => { - setRowHeight(rowIndex, size.height); - }, - [setRowHeight] - ); - const getItemKey = useCallback( ({ columnIndex, rowIndex }: { columnIndex: number; rowIndex: number }) => { const row = rows[rowIndex]; diff --git a/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx b/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx index cbbfcaee49..330e5ba1cf 100644 --- a/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx @@ -1,15 +1,35 @@ -import { useCellSelector, usePrimaryFieldId, useRowMetaSelector } from '@/application/database-yjs'; +import { useCellSelector, useDatabaseViewId, usePrimaryFieldId, useRowMetaSelector } from '@/application/database-yjs'; +import { FolderContext } from '@/application/folder-yjs'; import Title from '@/components/database/components/header/Title'; -import React from 'react'; +import React, { useContext, useEffect } from 'react'; function DatabaseRowHeader({ rowId }: { rowId: string }) { const fieldId = usePrimaryFieldId() || ''; + const setCrumbs = useContext(FolderContext)?.setCrumbs; + const viewId = useDatabaseViewId(); + const meta = useRowMetaSelector(rowId); const cell = useCellSelector({ rowId, fieldId, }); + useEffect(() => { + if (!viewId) return; + setCrumbs?.((prev) => { + const lastCrumb = prev[prev.length - 1]; + const crumb = { + viewId, + rowId, + name: cell?.data as string, + icon: meta?.icon || '', + }; + + if (lastCrumb?.rowId === rowId) return [...prev.slice(0, -1), crumb]; + return [...prev, crumb]; + }); + }, [cell, meta, rowId, setCrumbs, viewId]); + return ; } diff --git a/frontend/appflowy_web_app/src/components/database/components/property/Property.tsx b/frontend/appflowy_web_app/src/components/database/components/property/Property.tsx index f194a65a72..b1e4662b2d 100644 --- a/frontend/appflowy_web_app/src/components/database/components/property/Property.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/property/Property.tsx @@ -1,12 +1,13 @@ import { YjsDatabaseKey } from '@/application/collab.type'; import { FieldType, useCellSelector, useFieldSelector } from '@/application/database-yjs'; -import { Cell as CellType, CellProps, TextCell } from '@/components/database/components/cell/cell.type'; +import { Cell as CellType, CellProps } from '@/components/database/components/cell/cell.type'; import { CheckboxCell } from '@/components/database/components/cell/checkbox'; import { RowCreateModifiedTime } from '@/components/database/components/cell/created-modified'; import { DateTimeCell } from '@/components/database/components/cell/date'; import { NumberCell } from '@/components/database/components/cell/number'; import { RelationCell } from '@/components/database/components/cell/relation'; import { SelectOptionCell } from '@/components/database/components/cell/select-option'; +import { TextCell } from '@/components/database/components/cell/text'; import { UrlCell } from '@/components/database/components/cell/url'; import PropertyWrapper from '@/components/database/components/property/PropertyWrapper'; import { TextProperty } from '@/components/database/components/property/text'; @@ -42,6 +43,8 @@ export function Property({ fieldId, rowId }: { fieldId: string; rowId: string }) return ChecklistProperty; case FieldType.Relation: return RelationCell; + case FieldType.RichText: + return TextCell; default: return TextProperty; } @@ -54,10 +57,6 @@ export function Property({ fieldId, rowId }: { fieldId: string; rowId: string }) [] ); - if (fieldType === FieldType.RichText) { - return <TextProperty cell={cell as TextCell} fieldId={fieldId} rowId={rowId} />; - } - if (fieldType === FieldType.CreatedTime || fieldType === FieldType.LastEditedTime) { const attrName = fieldType === FieldType.CreatedTime ? YjsDatabaseKey.created_at : YjsDatabaseKey.last_modified; diff --git a/frontend/appflowy_web_app/src/components/database/components/property/PropertyWrapper.tsx b/frontend/appflowy_web_app/src/components/database/components/property/PropertyWrapper.tsx index 9e970abaee..c930365b37 100644 --- a/frontend/appflowy_web_app/src/components/database/components/property/PropertyWrapper.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/property/PropertyWrapper.tsx @@ -7,7 +7,7 @@ function PropertyWrapper({ fieldId, children }: { fieldId: string; children: Rea <div className={'property-label flex h-[28px] w-[30%] items-center'}> <FieldDisplay fieldId={fieldId} /> </div> - <div className={'flex flex-1 flex-wrap pr-1'}>{children}</div> + <div className={'flex flex-1 flex-wrap items-center overflow-x-hidden pr-1'}>{children}</div> </div> ); } diff --git a/frontend/appflowy_web_app/src/components/database/components/property/cheklist/ChecklistProperty.tsx b/frontend/appflowy_web_app/src/components/database/components/property/cheklist/ChecklistProperty.tsx index 6e47ada5fe..fabe862659 100644 --- a/frontend/appflowy_web_app/src/components/database/components/property/cheklist/ChecklistProperty.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/property/cheklist/ChecklistProperty.tsx @@ -15,7 +15,7 @@ export function ChecklistProperty(props: CellProps<CellType>) { const selectedOptions = data?.selectedOptionIds; return ( - <div className={'flex w-full flex-col gap-2'}> + <div className={'flex w-full flex-col gap-2 py-2'}> <ChecklistCell {...props} /> {options?.map((option) => { const isSelected = selectedOptions?.includes(option.id); diff --git a/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx b/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx index 8e33c7eaba..881f3d91df 100644 --- a/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx @@ -1,8 +1,9 @@ -import { ViewLayout, YjsFolderKey, YView } from '@/application/collab.type'; +import { DatabaseViewLayout, ViewLayout, YjsDatabaseKey, YjsFolderKey, YView } from '@/application/collab.type'; +import { useDatabaseView } from '@/application/database-yjs'; import { useFolderContext } from '@/application/folder-yjs'; -import { useId } from '@/components/_shared/context-provider/IdProvider'; import { DatabaseActions } from '@/components/database/components/conditions'; -import { forwardRef, FunctionComponent, SVGProps, useCallback, useEffect, useMemo } from 'react'; +import { Tooltip } from '@mui/material'; +import { forwardRef, FunctionComponent, SVGProps, useCallback, useMemo } from 'react'; import { ViewTabs, ViewTab } from './ViewTabs'; import { useTranslation } from 'react-i18next'; @@ -28,20 +29,15 @@ const DatabaseIcons: { export const DatabaseTabs = forwardRef<HTMLDivElement, DatabaseTabBarProps>( ({ viewIds, selectedViewId, setSelectedViewId }, ref) => { - const objectId = useId().objectId; const { t } = useTranslation(); const folder = useFolderContext(); + const view = useDatabaseView(); + const layout = Number(view?.get(YjsDatabaseKey.layout)) as DatabaseViewLayout; + const handleChange = (_: React.SyntheticEvent, newValue: string) => { setSelectedViewId?.(newValue); }; - useEffect(() => { - if (selectedViewId === undefined) { - setSelectedViewId?.(objectId); - } - }, [selectedViewId, setSelectedViewId, objectId]); - const isSelected = useMemo(() => viewIds.some((viewId) => viewId === selectedViewId), [viewIds, selectedViewId]); - const getFolderView = useCallback( (viewId: string) => { if (!folder) return null; @@ -50,12 +46,21 @@ export const DatabaseTabs = forwardRef<HTMLDivElement, DatabaseTabBarProps>( [folder] ); + const className = useMemo(() => { + const classList = [ + 'mx-16 -mb-[0.5px] flex items-center overflow-hidden border-line-divider text-text-title max-md:mx-4', + ]; + + if (layout === DatabaseViewLayout.Calendar) { + classList.push('border-b'); + } + + return classList.join(' '); + }, [layout]); + if (viewIds.length === 0) return null; return ( - <div - ref={ref} - className='mx-16 -mb-[0.5px] flex items-center overflow-hidden border-b border-line-divider text-text-title max-md:mx-4' - > + <div ref={ref} className={className}> <div style={{ width: 'calc(100% - 120px)', @@ -66,7 +71,7 @@ export const DatabaseTabs = forwardRef<HTMLDivElement, DatabaseTabBarProps>( scrollButtons={false} variant='scrollable' allowScrollButtonsMobile - value={isSelected ? selectedViewId : objectId} + value={selectedViewId} onChange={handleChange} > {viewIds.map((viewId) => { @@ -80,17 +85,22 @@ export const DatabaseTabs = forwardRef<HTMLDivElement, DatabaseTabBarProps>( return ( <ViewTab key={viewId} + data-testid={`view-tab-${viewId}`} icon={<Icon className={'h-4 w-4'} />} iconPosition='start' color='inherit' - label={<span className={'max-w-[120px] truncate'}>{name || t('grid.title.placeholder')}</span>} + label={ + <Tooltip title={name} enterDelay={1000} enterNextDelay={1000} placement={'right'}> + <span className={'max-w-[120px] truncate'}>{name || t('grid.title.placeholder')}</span> + </Tooltip> + } value={viewId} /> ); })} </ViewTabs> </div> - <DatabaseActions /> + {layout !== DatabaseViewLayout.Calendar ? <DatabaseActions /> : null} </div> ); } diff --git a/frontend/appflowy_web_app/src/components/database/grid/Grid.tsx b/frontend/appflowy_web_app/src/components/database/grid/Grid.tsx index 954f9cd7c3..521fa1cac0 100644 --- a/frontend/appflowy_web_app/src/components/database/grid/Grid.tsx +++ b/frontend/appflowy_web_app/src/components/database/grid/Grid.tsx @@ -1,7 +1,7 @@ import { RowsContext, useDatabase, useRowOrdersSelector, useViewId } from '@/application/database-yjs'; import { useRenderFields, GridHeader, GridTable } from '@/components/database/components/grid'; import { CircularProgress } from '@mui/material'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; export function Grid() { const database = useDatabase(); @@ -11,6 +11,10 @@ export function Grid() { const { fields, columnWidth } = useRenderFields(); const rowOrders = useRowOrdersSelector(); + useEffect(() => { + setScrollLeft(0); + }, [viewId]); + if (!database || !rowOrders) { return ( <div className={'flex w-full flex-1 flex-col items-center justify-center'}> @@ -25,7 +29,7 @@ export function Grid() { rowOrders, }} > - <div className={'flex w-full flex-1 flex-col'}> + <div className={'database-grid flex w-full flex-1 flex-col'}> <GridHeader scrollLeft={scrollLeft} columnWidth={columnWidth} columns={fields} onScrollLeft={setScrollLeft} /> <div className={'grid-scroll-table w-full flex-1'}> <GridTable diff --git a/frontend/appflowy_web_app/src/components/document/Document.tsx b/frontend/appflowy_web_app/src/components/document/Document.tsx index 219b76e7e5..8809cffee3 100644 --- a/frontend/appflowy_web_app/src/components/document/Document.tsx +++ b/frontend/appflowy_web_app/src/components/document/Document.tsx @@ -1,53 +1,111 @@ import { YDoc } from '@/application/collab.type'; import { useId } from '@/components/_shared/context-provider/IdProvider'; +import { usePageInfo } from '@/components/_shared/page/usePageInfo'; +import ComponentLoading from '@/components/_shared/progress/ComponentLoading'; import { AFConfigContext } from '@/components/app/AppConfig'; import { DocumentHeader } from '@/components/document/document_header'; import { Editor } from '@/components/editor'; +import { EditorLayoutStyle } from '@/components/editor/EditorContext'; import { Log } from '@/utils/log'; -import React, { useCallback, useContext, useEffect, useState } from 'react'; +import CircularProgress from '@mui/material/CircularProgress'; +import React, { Suspense, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import RecordNotFound from 'src/components/_shared/not-found/RecordNotFound'; export const Document = () => { - const { objectId: documentId, workspaceId } = useId() || {}; + const { objectId: documentId } = useId() || {}; const [doc, setDoc] = useState<YDoc | null>(null); const [notFound, setNotFound] = useState<boolean>(false); + const extra = usePageInfo(documentId).extra; + const layoutStyle: EditorLayoutStyle = useMemo(() => { + return { + font: extra?.font || '', + fontLayout: extra?.fontLayout, + lineHeightLayout: extra?.lineHeightLayout, + }; + }, [extra]); const documentService = useContext(AFConfigContext)?.service?.documentService; const handleOpenDocument = useCallback(async () => { - if (!documentService || !workspaceId || !documentId) return; + if (!documentService || !documentId) return; try { setDoc(null); - const doc = await documentService.openDocument(workspaceId, documentId); + const doc = await documentService.openDocument(documentId); setDoc(doc); } catch (e) { Log.error(e); setNotFound(true); } - }, [documentService, workspaceId, documentId]); + }, [documentService, documentId]); useEffect(() => { setNotFound(false); void handleOpenDocument(); }, [handleOpenDocument]); + const style = useMemo(() => { + const fontSizeMap = { + small: '14px', + normal: '16px', + large: '20px', + }; + + return { + fontFamily: layoutStyle.font, + fontSize: fontSizeMap[layoutStyle.fontLayout], + }; + }, [layoutStyle]); + + const layoutClassName = useMemo(() => { + const classList = []; + + if (layoutStyle.fontLayout === 'large') { + classList.push('font-large'); + } else if (layoutStyle.fontLayout === 'small') { + classList.push('font-small'); + } + + if (layoutStyle.lineHeightLayout === 'large') { + classList.push('line-height-large'); + } else if (layoutStyle.lineHeightLayout === 'small') { + classList.push('line-height-small'); + } + + return classList.join(' '); + }, [layoutStyle]); + + useEffect(() => { + if (!layoutStyle.font) return; + void window.WebFont?.load({ + google: { + families: [layoutStyle.font], + }, + }); + }, [layoutStyle.font]); + if (!documentId) return null; return ( <> - {doc && ( - <div className={'relative w-full'}> + {doc ? ( + <div style={style} className={`relative w-full ${layoutClassName}`}> <DocumentHeader doc={doc} viewId={documentId} /> <div className={'flex w-full justify-center'}> - <div className={'max-w-screen w-[964px] min-w-0'}> - <Editor doc={doc} readOnly={true} includeRoot={true} /> - </div> + <Suspense fallback={<ComponentLoading />}> + <div className={'max-w-screen w-[964px] min-w-0'}> + <Editor doc={doc} readOnly={true} layoutStyle={layoutStyle} /> + </div> + </Suspense> </div> </div> + ) : ( + <div className={'flex h-full w-full items-center justify-center'}> + <CircularProgress /> + </div> )} - <RecordNotFound open={notFound} workspaceId={workspaceId} /> + <RecordNotFound open={notFound} /> </> ); }; diff --git a/frontend/appflowy_web_app/src/components/document/document_header/DocumentCover.tsx b/frontend/appflowy_web_app/src/components/document/document_header/DocumentCover.tsx index 08ee25ef87..1d01474622 100644 --- a/frontend/appflowy_web_app/src/components/document/document_header/DocumentCover.tsx +++ b/frontend/appflowy_web_app/src/components/document/document_header/DocumentCover.tsx @@ -1,37 +1,56 @@ -import { CoverType, YDoc } from '@/application/collab.type'; -import { useBlockCover } from '@/components/document/document_header/useBlockCover'; +import { showColorsForImage } from '@/components/document/document_header/utils'; import { renderColor } from '@/utils/color'; import React, { useCallback } from 'react'; -import DefaultImage from './default_cover.jpg'; -function DocumentCover({ doc }: { doc: YDoc }) { - const { cover } = useBlockCover(doc); +function DocumentCover({ + coverValue, + coverType, + onTextColor, +}: { + coverValue?: string; + coverType?: string; + onTextColor: (color: string) => void; +}) { const renderCoverColor = useCallback((color: string) => { return ( <div style={{ - backgroundColor: renderColor(color), + background: renderColor(color), }} className={`h-full w-full`} /> ); }, []); - const renderCoverImage = useCallback((url: string) => { - return <img draggable={false} src={url} alt={''} className={'h-full w-full object-cover'} />; - }, []); + const renderCoverImage = useCallback( + (url: string) => { + return ( + <img + onLoad={(e) => { + void showColorsForImage(e.currentTarget).then((res) => { + onTextColor(res); + }); + }} + draggable={false} + src={url} + alt={''} + className={'h-full w-full object-cover'} + /> + ); + }, + [onTextColor] + ); - const { cover_selection_type: type, cover_selection: value = '' } = cover || {}; + if (!coverType || !coverValue) { + return null; + } - return value ? ( - <div className={`relative mb-[-80px] flex h-[255px] w-full`}> - <> - {type === CoverType.Asset ? renderCoverImage(DefaultImage) : null} - {type === CoverType.Color ? renderCoverColor(value) : null} - {type === CoverType.Image ? renderCoverImage(value) : null} - </> + return ( + <div className={'relative flex h-[255px] w-full max-sm:h-[180px]'}> + {coverType === 'color' && renderCoverColor(coverValue)} + {(coverType === 'custom' || coverType === 'built_in') && renderCoverImage(coverValue)} </div> - ) : null; + ); } export default DocumentCover; diff --git a/frontend/appflowy_web_app/src/components/document/document_header/DocumentHeader.tsx b/frontend/appflowy_web_app/src/components/document/document_header/DocumentHeader.tsx index 0610b8a834..04201f5ce5 100644 --- a/frontend/appflowy_web_app/src/components/document/document_header/DocumentHeader.tsx +++ b/frontend/appflowy_web_app/src/components/document/document_header/DocumentHeader.tsx @@ -1,12 +1,21 @@ -import { YDoc, YjsFolderKey } from '@/application/collab.type'; +import { DocCoverType, YDoc, YjsFolderKey } from '@/application/collab.type'; import { useViewSelector } from '@/application/folder-yjs'; +import { CoverType } from '@/application/folder-yjs/folder.type'; +import { usePageInfo } from '@/components/_shared/page/usePageInfo'; import DocumentCover from '@/components/document/document_header/DocumentCover'; -import React, { memo, useMemo, useRef } from 'react'; +import { useBlockCover } from '@/components/document/document_header/useBlockCover'; +import React, { memo, useMemo, useRef, useState } from 'react'; +import BuiltInImage1 from '@/assets/cover/m_cover_image_1.png'; +import BuiltInImage2 from '@/assets/cover/m_cover_image_2.png'; +import BuiltInImage3 from '@/assets/cover/m_cover_image_3.png'; +import BuiltInImage4 from '@/assets/cover/m_cover_image_4.png'; +import BuiltInImage5 from '@/assets/cover/m_cover_image_5.png'; +import BuiltInImage6 from '@/assets/cover/m_cover_image_6.png'; export function DocumentHeader({ viewId, doc }: { viewId: string; doc: YDoc }) { const ref = useRef<HTMLDivElement>(null); const { view } = useViewSelector(viewId); - + const [textColor, setTextColor] = useState<string>('var(--text-title)'); const icon = view?.get(YjsFolderKey.icon); const iconObject = useMemo(() => { try { @@ -16,22 +25,71 @@ export function DocumentHeader({ viewId, doc }: { viewId: string; doc: YDoc }) { } }, [icon]); - return ( - <div ref={ref} className={'document-header select-none'}> - <div className={'flex flex-col justify-end'}> - <div className={'view-banner flex w-full flex-col overflow-hidden'}> - <DocumentCover doc={doc} /> + const { extra } = usePageInfo(viewId); - <div className={`relative min-h-[65px] w-[964px] min-w-0 max-w-full px-16 pt-10 max-md:px-4`}> - <div - style={{ - position: 'relative', - bottom: '50%', - }} - > - <div className={`view-icon`}>{iconObject?.value}</div> + const pageCover = extra.cover; + const { cover } = useBlockCover(doc); + + const coverType = useMemo(() => { + if ( + (pageCover && [CoverType.NormalColor, CoverType.GradientColor].includes(pageCover.type)) || + cover?.cover_selection_type === DocCoverType.Color + ) { + return 'color'; + } + + if (CoverType.BuildInImage === pageCover?.type || cover?.cover_selection_type === DocCoverType.Asset) { + return 'built_in'; + } + + if ( + (pageCover && [CoverType.CustomImage, CoverType.UpsplashImage].includes(pageCover.type)) || + cover?.cover_selection_type === DocCoverType.Image + ) { + return 'custom'; + } + }, [cover?.cover_selection_type, pageCover]); + + const coverValue = useMemo(() => { + if (coverType === 'built_in') { + return { + 1: BuiltInImage1, + 2: BuiltInImage2, + 3: BuiltInImage3, + 4: BuiltInImage4, + 5: BuiltInImage5, + 6: BuiltInImage6, + }[pageCover?.value as string]; + } + + return pageCover?.value || cover?.cover_selection; + }, [coverType, cover?.cover_selection, pageCover]); + + return ( + <div ref={ref} className={'document-header mb-[10px] select-none'}> + <div className={'view-banner relative flex w-full flex-col overflow-hidden'}> + <DocumentCover onTextColor={setTextColor} coverType={coverType} coverValue={coverValue} /> + + <div className={`relative mx-16 w-[964px] min-w-0 max-w-full overflow-visible max-md:mx-4`}> + <div + style={{ + position: coverValue ? 'absolute' : 'relative', + bottom: '100%', + width: '100%', + }} + className={'flex items-center gap-2 px-14 py-8 text-4xl max-md:px-2 max-sm:text-[7vw]'} + > + <div className={`view-icon`}>{iconObject?.value}</div> + <div className={'flex flex-1 items-center gap-2 overflow-hidden'}> + <div + style={{ + color: textColor, + }} + className={'font-bold leading-[1.5em]'} + > + {view?.get(YjsFolderKey.name)} + </div> </div> - <div className={'py-2'}></div> </div> </div> </div> diff --git a/frontend/appflowy_web_app/src/components/document/document_header/default_cover.jpg b/frontend/appflowy_web_app/src/components/document/document_header/default_cover.jpg deleted file mode 100644 index aeaa6a0f29..0000000000 Binary files a/frontend/appflowy_web_app/src/components/document/document_header/default_cover.jpg and /dev/null differ diff --git a/frontend/appflowy_web_app/src/components/document/document_header/useBlockCover.ts b/frontend/appflowy_web_app/src/components/document/document_header/useBlockCover.ts index 589a1e4169..ba6226a6e8 100644 --- a/frontend/appflowy_web_app/src/components/document/document_header/useBlockCover.ts +++ b/frontend/appflowy_web_app/src/components/document/document_header/useBlockCover.ts @@ -1,4 +1,4 @@ -import { PageCover, YBlocks, YDoc, YDocument, YjsEditorKey } from '@/application/collab.type'; +import { DocCover, YBlocks, YDoc, YDocument, YjsEditorKey } from '@/application/collab.type'; import { useEffect, useMemo, useState } from 'react'; export function useBlockCover(doc: YDoc) { @@ -22,7 +22,7 @@ export function useBlockCover(doc: YDoc) { }; }, [doc]); - const coverObj: PageCover = useMemo(() => { + const coverObj: DocCover = useMemo(() => { try { return JSON.parse(cover || ''); } catch (e) { diff --git a/frontend/appflowy_web_app/src/components/document/document_header/utils.ts b/frontend/appflowy_web_app/src/components/document/document_header/utils.ts new file mode 100644 index 0000000000..fe2c0acbe0 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/document/document_header/utils.ts @@ -0,0 +1,28 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-expect-error +import ColorThief from 'colorthief'; + +const colorThief = new ColorThief(); + +export function calculateTextColor(rgb: [number, number, number]): string { + const [r, g, b] = rgb; + const brightness = (r * 299 + g * 587 + b * 114) / 1000; + + return brightness > 125 ? 'black' : 'white'; +} + +export async function showColorsForImage(image: HTMLImageElement) { + const img = new Image(); + + img.crossOrigin = 'Anonymous'; // Handle CORS + img.src = image.src; + + await new Promise((resolve, reject) => { + img.onload = resolve; + img.onerror = reject; + }); + + const dominantColor = colorThief.getColor(img); + + return calculateTextColor(dominantColor); +} diff --git a/frontend/appflowy_web_app/src/components/editor/CollaborativeEditor.tsx b/frontend/appflowy_web_app/src/components/editor/CollaborativeEditor.tsx index 7e5ebbc28c..8820296780 100644 --- a/frontend/appflowy_web_app/src/components/editor/CollaborativeEditor.tsx +++ b/frontend/appflowy_web_app/src/components/editor/CollaborativeEditor.tsx @@ -1,8 +1,5 @@ -import { CollabOrigin, YjsFolderKey } from '@/application/collab.type'; -import { useViewSelector } from '@/application/folder-yjs'; +import { CollabOrigin } from '@/application/collab.type'; import { withYjs, YjsEditor } from '@/application/slate-yjs/plugins/withYjs'; -import { useId } from '@/components/_shared/context-provider/IdProvider'; -import { CustomEditor } from '@/components/editor/command'; import EditorEditable from '@/components/editor/Editable'; import { useEditorContext } from '@/components/editor/EditorContext'; import { withPlugins } from '@/components/editor/plugins'; @@ -13,10 +10,7 @@ import * as Y from 'yjs'; const defaultInitialValue: Descendant[] = []; -function CollaborativeEditor({ doc, includeRoot = true }: { doc: Y.Doc; includeRoot?: boolean }) { - const viewId = useId()?.objectId || ''; - const { view } = useViewSelector(viewId); - const title = includeRoot ? view?.get(YjsFolderKey.name) : undefined; +function CollaborativeEditor({ doc }: { doc: Y.Doc }) { const context = useEditorContext(); // if readOnly, collabOrigin is Local, otherwise RemoteSync const localOrigin = context.readOnly ? CollabOrigin.Local : CollabOrigin.LocalSync; @@ -27,13 +21,12 @@ function CollaborativeEditor({ doc, includeRoot = true }: { doc: Y.Doc; includeR withReact( withYjs(createEditor(), doc, { localOrigin, - includeRoot, }) ) ) as YjsEditor), - [doc, localOrigin, includeRoot] + [doc, localOrigin] ); - const [connected, setIsConnected] = useState(false); + const [, setIsConnected] = useState(false); useEffect(() => { if (!editor) return; @@ -45,11 +38,6 @@ function CollaborativeEditor({ doc, includeRoot = true }: { doc: Y.Doc; includeR }; }, [editor]); - useEffect(() => { - if (!editor || !connected || title === undefined) return; - CustomEditor.setDocumentTitle(editor, title); - }, [editor, title, connected]); - return ( <Slate editor={editor} initialValue={defaultInitialValue}> <EditorEditable editor={editor} /> diff --git a/frontend/appflowy_web_app/src/components/editor/Editable.tsx b/frontend/appflowy_web_app/src/components/editor/Editable.tsx index e712fc88fd..2ba4e83e3a 100644 --- a/frontend/appflowy_web_app/src/components/editor/Editable.tsx +++ b/frontend/appflowy_web_app/src/components/editor/Editable.tsx @@ -3,7 +3,7 @@ import { Leaf } from '@/components/editor/components/leaf'; import { useEditorContext } from '@/components/editor/EditorContext'; import React, { useCallback } from 'react'; import { NodeEntry } from 'slate'; -import { Editable, ReactEditor } from 'slate-react'; +import { Editable, ReactEditor, RenderElementProps } from 'slate-react'; import { Element } from './components/element'; const EditorEditable = ({ editor }: { editor: ReactEditor }) => { @@ -17,13 +17,15 @@ const EditorEditable = ({ editor }: { editor: ReactEditor }) => { [codeDecorate] ); + const renderElement = useCallback((props: RenderElementProps) => <Element {...props} />, []); + return ( <Editable role={'textbox'} decorate={decorate} className={'px-16 outline-none focus:outline-none max-md:px-4'} renderLeaf={Leaf} - renderElement={Element} + renderElement={renderElement} readOnly={readOnly} spellCheck={false} autoCorrect={'off'} diff --git a/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx b/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx index 766e1e6d29..7c6ec9a55e 100644 --- a/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx +++ b/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx @@ -1,12 +1,16 @@ -import { YDoc } from '@/application/collab.type'; +import { YDoc, YFolder, YjsEditorKey } from '@/application/collab.type'; import { DocumentTest } from '@/../cypress/support/document'; import { applyYDoc } from '@/application/ydoc/apply'; +import { FolderProvider } from '@/components/_shared/context-provider/FolderProvider'; import React from 'react'; import * as Y from 'yjs'; import { Editor } from './Editor'; import withAppWrapper from '@/components/app/withAppWrapper'; describe('<Editor />', () => { + beforeEach(() => { + cy.viewport(1280, 720); + }); it('renders with a paragraph', () => { const documentTest = new DocumentTest(); @@ -16,21 +20,39 @@ describe('<Editor />', () => { }); it('renders with a full document', () => { - cy.fixture('full_doc').then((docJson) => { + cy.mockDatabase(); + Object.defineProperty(window.navigator, 'language', { value: 'en-US' }); + Object.defineProperty(window.navigator, 'languages', { value: ['en-US'] }); + cy.fixture('folder').then((folderJson) => { const doc = new Y.Doc(); - const state = new Uint8Array(docJson.data.doc_state); + const state = new Uint8Array(folderJson.data.doc_state); applyYDoc(doc, state); - renderEditor(doc); + + const folder = doc.getMap(YjsEditorKey.data_section).get(YjsEditorKey.folder) as YFolder; + + cy.fixture('full_doc').then((docJson) => { + const doc = new Y.Doc(); + const state = new Uint8Array(docJson.data.doc_state); + + applyYDoc(doc, state); + renderEditor(doc, folder); + }); }); }); }); -function renderEditor(doc: YDoc) { +function renderEditor(doc: YDoc, folder?: YFolder) { const AppWrapper = withAppWrapper(() => { return ( <div className={'h-screen w-screen overflow-y-auto'}> - <Editor doc={doc} readOnly /> + {folder ? ( + <FolderProvider folder={folder}> + <Editor doc={doc} readOnly /> + </FolderProvider> + ) : ( + <Editor doc={doc} readOnly /> + )} </div> ); }); diff --git a/frontend/appflowy_web_app/src/components/editor/Editor.tsx b/frontend/appflowy_web_app/src/components/editor/Editor.tsx index 601b5d44b2..183aed8918 100644 --- a/frontend/appflowy_web_app/src/components/editor/Editor.tsx +++ b/frontend/appflowy_web_app/src/components/editor/Editor.tsx @@ -1,23 +1,21 @@ import { YDoc } from '@/application/collab.type'; import CollaborativeEditor from '@/components/editor/CollaborativeEditor'; -import { EditorContextProvider } from '@/components/editor/EditorContext'; -import React from 'react'; +import { defaultLayoutStyle, EditorContextProvider, EditorLayoutStyle } from '@/components/editor/EditorContext'; +import React, { memo } from 'react'; import './editor.scss'; -export const Editor = ({ - readOnly, - doc, - includeRoot = true, -}: { +export interface EditorProps { readOnly: boolean; doc: YDoc; - includeRoot?: boolean; -}) => { + layoutStyle?: EditorLayoutStyle; +} + +export const Editor = memo(({ readOnly, doc, layoutStyle = defaultLayoutStyle }: EditorProps) => { return ( - <EditorContextProvider readOnly={readOnly}> - <CollaborativeEditor doc={doc} includeRoot={includeRoot} /> + <EditorContextProvider layoutStyle={layoutStyle} readOnly={readOnly}> + <CollaborativeEditor doc={doc} /> </EditorContextProvider> ); -}; +}); export default Editor; diff --git a/frontend/appflowy_web_app/src/components/editor/EditorContext.tsx b/frontend/appflowy_web_app/src/components/editor/EditorContext.tsx index 7b4162891e..c360c969dd 100644 --- a/frontend/appflowy_web_app/src/components/editor/EditorContext.tsx +++ b/frontend/appflowy_web_app/src/components/editor/EditorContext.tsx @@ -1,11 +1,26 @@ +import { FontLayout, LineHeightLayout } from '@/application/collab.type'; import { createContext, useContext } from 'react'; +export interface EditorLayoutStyle { + fontLayout: FontLayout; + font: string; + lineHeightLayout: LineHeightLayout; +} + +export const defaultLayoutStyle: EditorLayoutStyle = { + fontLayout: FontLayout.normal, + font: '', + lineHeightLayout: LineHeightLayout.normal, +}; + interface EditorContextState { readOnly: boolean; + layoutStyle: EditorLayoutStyle; } export const EditorContext = createContext<EditorContextState>({ readOnly: true, + layoutStyle: defaultLayoutStyle, }); export const EditorContextProvider = ({ children, ...props }: EditorContextState & { children: React.ReactNode }) => { diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/code/Code.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/code/Code.tsx index be86b4bd98..5ef2279da3 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/code/Code.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/code/Code.tsx @@ -22,5 +22,6 @@ export const CodeBlock = memo( </div> </> ); - }) + }), + (prevProps, nextProps) => JSON.stringify(prevProps.node) === JSON.stringify(nextProps.node) ); diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/BoardBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/BoardBlock.tsx deleted file mode 100644 index 88e3790551..0000000000 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/BoardBlock.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -function BoardBlock() { - return <div></div>; -} - -export default BoardBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/CalendarBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/CalendarBlock.tsx deleted file mode 100644 index 19c2b32bf0..0000000000 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/CalendarBlock.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -function CalendarBlock() { - return <div></div>; -} - -export default CalendarBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx index b9bc174969..a563557ab7 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx @@ -1,7 +1,14 @@ -import { IdProvider, useId } from '@/components/_shared/context-provider/IdProvider'; +import { ReactComponent as ExpandMoreIcon } from '$icons/16x/full_view.svg'; +import { useNavigateToView } from '@/application/folder-yjs'; +import { getCurrentWorkspace } from '@/application/services/js-services/storage'; +import { IdProvider } from '@/components/_shared/context-provider/IdProvider'; import { Database } from '@/components/database'; +import { useGetDatabaseId, useLoadDatabase } from '@/components/database/Database.hooks'; +import { DatabaseContextProvider } from '@/components/database/DatabaseContext'; import { DatabaseNode, EditorElementProps } from '@/components/editor/editor.type'; -import React, { forwardRef, memo, useMemo } from 'react'; +import { Tooltip } from '@mui/material'; +import CircularProgress from '@mui/material/CircularProgress'; +import React, { forwardRef, memo, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { BlockType } from '@/application/collab.type'; @@ -9,9 +16,10 @@ export const DatabaseBlock = memo( forwardRef<HTMLDivElement, EditorElementProps<DatabaseNode>>(({ node, children, ...attributes }, ref) => { const { t } = useTranslation(); const viewId = node.data.view_id; - const workspaceId = useId()?.workspaceId; const type = node.type; - + const navigateToView = useNavigateToView(); + const [isHovering, setIsHovering] = useState(false); + const [databaseViewId, setDatabaseViewId] = useState<string | undefined>(viewId); const style = useMemo(() => { const style = {}; @@ -31,30 +39,83 @@ export const DatabaseBlock = memo( return style; }, [type]); + const handleNavigateToRow = useCallback( + async (rowId: string) => { + const workspace = await getCurrentWorkspace(); + + if (!workspace) return; + + const url = `/view/${workspace.id}/${databaseViewId}?r=${rowId}`; + + window.open(url, '_blank'); + }, + [databaseViewId] + ); + const databaseId = useGetDatabaseId(viewId); + + const { doc, rows, notFound } = useLoadDatabase({ + databaseId, + }); + return ( <> - <div {...attributes} className={`relative w-full cursor-pointer py-2`}> + <div + {...attributes} + className={`relative w-full cursor-pointer py-2`} + onMouseEnter={() => setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + > <div ref={ref} className={'absolute left-0 top-0 h-full w-full caret-transparent'}> {children} </div> - <div contentEditable={false} style={style} className={`container-bg flex w-full flex-col px-3`}> - {viewId ? ( - <IdProvider workspaceId={workspaceId} objectId={viewId}> - <Database /> + <div contentEditable={false} style={style} className={`container-bg relative flex w-full flex-col px-3`}> + {viewId && doc && rows ? ( + <IdProvider objectId={viewId}> + <DatabaseContextProvider + navigateToRow={handleNavigateToRow} + viewId={databaseViewId || viewId} + databaseDoc={doc} + rowDocMap={rows} + readOnly={true} + > + <Database iidIndex={viewId} viewId={databaseViewId || viewId} onNavigateToView={setDatabaseViewId} /> + </DatabaseContextProvider> + {isHovering && ( + <div className={'absolute right-4 top-1'}> + <Tooltip placement={'bottom'} title={t('tooltip.openAsPage')}> + <button + color={'primary'} + className={'rounded border border-line-divider bg-bg-body p-1 hover:bg-fill-list-hover'} + onClick={() => { + navigateToView?.(viewId); + }} + > + <ExpandMoreIcon /> + </button> + </Tooltip> + </div> + )} </IdProvider> ) : ( <div className={'mt-[10%] flex h-full w-full flex-col items-center gap-2 px-16 text-text-caption max-md:px-4'} > - <div className={'text-sm font-medium'}>{t('document.plugins.database.noDataSource')}</div> - <div className={'text-xs'}>{t('grid.relation.noDatabaseSelected')}</div> + {notFound ? ( + <> + <div className={'text-sm font-medium'}>{t('document.plugins.database.noDataSource')}</div> + <div className={'text-xs'}>{t('grid.relation.noDatabaseSelected')}</div> + </> + ) : ( + <CircularProgress /> + )} </div> )} </div> </div> </> ); - }) + }), + (prevProps, nextProps) => prevProps.node.data.view_id === nextProps.node.data.view_id ); export default DatabaseBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/GridBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/GridBlock.tsx deleted file mode 100644 index eaf2742ceb..0000000000 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/GridBlock.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -function GridBlock() { - return <div></div>; -} - -export default GridBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/heading/utils.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/heading/utils.ts index bab542fc84..22fe53980a 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/heading/utils.ts +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/heading/utils.ts @@ -1,17 +1,17 @@ export function getHeadingCssProperty(level: number) { switch (level) { case 1: - return 'text-3xl pt-[10px] pb-[8px] font-bold'; + return 'text-3xl pt-[10px] max-md:pt-[1.5vw] pb-[4px] max-md:pb-[1vw] font-bold max-sm:text-[6vw]'; case 2: - return 'text-2xl pt-[8px] pb-[6px] font-bold'; + return 'text-2xl pt-[8px] max-md:pt-[1vw] pb-[2px] max-md:pb-[0.5vw] font-bold max-sm:text-[5vw]'; case 3: - return 'text-xl pt-[4px] font-bold'; + return 'text-xl pt-[4px] font-bold max-sm:text-[4vw]'; case 4: return 'text-lg pt-[4px] font-bold'; case 5: - return 'text-base pt-[4px] font-bold'; + return 'pt-[4px] font-bold'; case 6: - return 'text-sm pt-[4px] font-bold'; + return 'pt-[4px] font-bold'; default: return ''; } diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/MathEquation.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/MathEquation.tsx index 86eb6117ad..6f6ba420e1 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/MathEquation.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/MathEquation.tsx @@ -38,7 +38,8 @@ export const MathEquation = memo( </> ); } - ) + ), + (prevProps, nextProps) => JSON.stringify(prevProps.node) === JSON.stringify(nextProps.node) ); export default MathEquation; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/index.ts index 27b52f50f2..d10b172020 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/index.ts +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/index.ts @@ -1,5 +1,3 @@ import { lazy } from 'react'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-expect-error -export const MathEquation = lazy(() => import('./MathEquation?chunkName=formula')); +export const MathEquation = lazy(() => import('./MathEquation')); diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/outline/Outline.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/outline/Outline.tsx index cddab4cfb7..e26c066a71 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/outline/Outline.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/outline/Outline.tsx @@ -3,6 +3,7 @@ import { EditorElementProps, HeadingNode, OutlineNode } from '@/components/edito import React, { forwardRef, memo, useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useSlate } from 'slate-react'; +import smoothScrollIntoViewIfNeeded from 'smooth-scroll-into-view-if-needed'; export const Outline = memo( forwardRef<HTMLDivElement, EditorElementProps<OutlineNode>>(({ node, children, className, ...attributes }, ref) => { @@ -22,7 +23,10 @@ export const Outline = memo( const element = document.getElementById(id); if (element) { - element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + void smoothScrollIntoViewIfNeeded(element, { + behavior: 'smooth', + block: 'center', + }); } }, []); @@ -32,7 +36,14 @@ export const Outline = memo( const { text, level } = heading.data as { text: string; level: number }; return ( - <div onClick={() => jumpToHeading(heading)} className={`my-1 ml-4 `} key={`${level}-${index}`}> + <div + onClick={(e) => { + e.stopPropagation(); + jumpToHeading(heading); + }} + className={`my-1 ml-4 `} + key={`${level}-${index}`} + > <div className={'cursor-pointer rounded px-2 underline hover:text-content-blue-400'}>{text}</div> <div className={'ml-2'}>{children}</div> diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/table/Table.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/table/Table.tsx index 3b2ffb1a22..ae0522a1da 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/table/Table.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/table/Table.tsx @@ -2,6 +2,7 @@ import { EditorElementProps, TableCellNode, TableNode } from '@/components/edito import React, { forwardRef, memo, useMemo } from 'react'; import { Grid } from '@atlaskit/primitives'; import './table.scss'; +import isEqual from 'lodash-es/isEqual'; const Table = memo( forwardRef<HTMLDivElement, EditorElementProps<TableNode>>(({ node, children, className, ...attributes }, ref) => { @@ -50,7 +51,8 @@ const Table = memo( </Grid> </div> ); - }) + }), + (prevProps, nextProps) => isEqual(prevProps.node, nextProps.node) ); export default Table; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Placeholder.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Placeholder.tsx index 44c1391e13..08a66de9d2 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Placeholder.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Placeholder.tsx @@ -10,6 +10,7 @@ function Placeholder({ node, ...attributes }: { node: Element; className?: strin const { t } = useTranslation(); const { readOnly } = useEditorContext(); const editor = useSlate(); + const selected = useSelected() && !readOnly && !!editor.selection && Range.isCollapsed(editor.selection); const [isComposing, setIsComposing] = useState(false); const block = useMemo(() => { @@ -33,7 +34,7 @@ function Placeholder({ node, ...attributes }: { node: Element; className?: strin const unSelectedPlaceholder = useMemo(() => { switch (block?.type) { case BlockType.Paragraph: { - if (editor.children.length === 1) { + if (editor.children.length === 1 && !readOnly) { return t('editor.slashPlaceHolder'); } @@ -73,7 +74,7 @@ function Placeholder({ node, ...attributes }: { node: Element; className?: strin default: return ''; } - }, [block, t, editor.children.length]); + }, [readOnly, block, t, editor.children.length]); const selectedPlaceholder = useMemo(() => { switch (block?.type) { @@ -122,7 +123,7 @@ function Placeholder({ node, ...attributes }: { node: Element; className?: strin return ( <span - data-placeholder={selected ? selectedPlaceholder : unSelectedPlaceholder} + data-placeholder={selected && !readOnly ? selectedPlaceholder : unSelectedPlaceholder} contentEditable={false} {...attributes} className={className} diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Text.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Text.tsx index 854789969c..a9843570ea 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Text.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/text/Text.tsx @@ -2,7 +2,6 @@ import Placeholder from '@/components/editor/components/blocks/text/Placeholder' import { useSlateStatic } from 'slate-react'; import { useStartIcon } from './StartIcon.hooks'; import { EditorElementProps, TextNode } from '@/components/editor/editor.type'; - import React, { forwardRef, memo, useMemo } from 'react'; export const Text = memo( @@ -11,13 +10,13 @@ export const Text = memo( const { hasStartIcon, renderIcon } = useStartIcon(node); const editor = useSlateStatic(); const isEmpty = editor.isEmpty(node); - const className = useMemo( - () => - `text-element relative my-1 flex w-full whitespace-pre-wrap break-all px-1 ${classNameProp ?? ''} ${ - hasStartIcon ? 'has-start-icon' : '' - }`, - [classNameProp, hasStartIcon] - ); + const className = useMemo(() => { + const classList = ['text-element', 'relative', 'flex', 'w-full', 'whitespace-pre-wrap', 'break-all', 'px-1']; + + if (classNameProp) classList.push(classNameProp); + if (hasStartIcon) classList.push('has-start-icon'); + return classList.join(' '); + }, [classNameProp, hasStartIcon]); return ( <span {...attributes} ref={ref} className={className}> @@ -27,5 +26,6 @@ export const Text = memo( </span> ); } - ) + ), + (prevProps, nextProps) => JSON.stringify(prevProps.node) === JSON.stringify(nextProps.node) ); diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/TodoList.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/TodoList.tsx index ab3a437b78..f0356d4cbf 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/TodoList.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/TodoList.tsx @@ -7,7 +7,7 @@ export const TodoList = memo( const className = useMemo(() => { return `flex w-full flex-col ${checked ? 'checked' : ''} ${attributes.className ?? ''}`; }, [attributes.className, checked]); - + return ( <div {...attributes} ref={ref} className={className}> {children} diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx index e7a2d288f2..51ed844e82 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx @@ -1,6 +1,6 @@ import { ToggleListNode } from '@/components/editor/editor.type'; import React from 'react'; -import { ReactComponent as RightSvg } from '$icons/16x/more.svg'; +import { ReactComponent as ExpandSvg } from '$icons/16x/drop_menu_show.svg'; function ToggleIcon({ block, className }: { block: ToggleListNode; className: string }) { const { collapsed } = block.data; @@ -14,7 +14,7 @@ function ToggleIcon({ block, className }: { block: ToggleListNode; className: st }} className={`${className} cursor-pointer pr-1 text-xl hover:text-fill-default`} > - {collapsed ? <RightSvg /> : <RightSvg className={'rotate-90 transform'} />} + {collapsed ? <ExpandSvg className={'-rotate-90 transform'} /> : <ExpandSvg />} </span> ); } diff --git a/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx b/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx index 46a784dd37..d117a14221 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx @@ -13,6 +13,9 @@ import { Paragraph } from '@/components/editor/components/blocks/paragraph'; import { Quote } from '@/components/editor/components/blocks/quote'; import { TableBlock, TableCellBlock } from '@/components/editor/components/blocks/table'; import { Text } from '@/components/editor/components/blocks/text'; +import { ElementFallbackRender } from '@/components/error/ElementFallbackRender'; +import { Skeleton } from '@mui/material'; +import { ErrorBoundary } from 'react-error-boundary'; import { TodoList } from 'src/components/editor/components/blocks/todo-list'; import { ToggleList } from 'src/components/editor/components/blocks/toggle-list'; import { UnSupportedBlock } from '@/components/editor/components/element/UnSupportedBlock'; @@ -20,108 +23,116 @@ import { Formula } from '@/components/editor/components/leaf/formula'; import { Mention } from '@/components/editor/components/leaf/mention'; import { EditorElementProps, TextNode } from '@/components/editor/editor.type'; import { renderColor } from '@/utils/color'; -import React, { FC, useMemo } from 'react'; +import React, { FC, memo, Suspense, useMemo } from 'react'; import { RenderElementProps } from 'slate-react'; import { DatabaseBlock } from 'src/components/editor/components/blocks/database'; +import isEqual from 'lodash-es/isEqual'; -export const Element = ({ - element: node, - attributes, - children, -}: RenderElementProps & { - element: EditorElementProps['node']; -}) => { - const Component = useMemo(() => { - switch (node.type) { - case BlockType.HeadingBlock: - return Heading; - case BlockType.TodoListBlock: - return TodoList; - case BlockType.ToggleListBlock: - return ToggleList; - case BlockType.Paragraph: - return Paragraph; - case BlockType.DividerBlock: - return DividerNode; - case BlockType.Page: - return Page; - case BlockType.QuoteBlock: - return Quote; - case BlockType.BulletedListBlock: - return BulletedList; - case BlockType.NumberedListBlock: - return NumberedList; - case BlockType.CodeBlock: - return CodeBlock; - case BlockType.CalloutBlock: - return Callout; - case BlockType.EquationBlock: - return MathEquation; - case BlockType.ImageBlock: - return ImageBlock; - case BlockType.OutlineBlock: - return Outline; - case BlockType.TableBlock: - return TableBlock; - case BlockType.TableCell: - return TableCellBlock; - case BlockType.GridBlock: - case BlockType.BoardBlock: - case BlockType.CalendarBlock: - return DatabaseBlock; - default: - return UnSupportedBlock; +export const Element = memo( + ({ + element: node, + attributes, + children, + }: RenderElementProps & { + element: EditorElementProps['node']; + }) => { + const Component = useMemo(() => { + switch (node.type) { + case BlockType.HeadingBlock: + return Heading; + case BlockType.TodoListBlock: + return TodoList; + case BlockType.ToggleListBlock: + return ToggleList; + case BlockType.Paragraph: + return Paragraph; + case BlockType.DividerBlock: + return DividerNode; + case BlockType.Page: + return Page; + case BlockType.QuoteBlock: + return Quote; + case BlockType.BulletedListBlock: + return BulletedList; + case BlockType.NumberedListBlock: + return NumberedList; + case BlockType.CodeBlock: + return CodeBlock; + case BlockType.CalloutBlock: + return Callout; + case BlockType.EquationBlock: + return MathEquation; + case BlockType.ImageBlock: + return ImageBlock; + case BlockType.OutlineBlock: + return Outline; + case BlockType.TableBlock: + return TableBlock; + case BlockType.TableCell: + return TableCellBlock; + case BlockType.GridBlock: + case BlockType.BoardBlock: + case BlockType.CalendarBlock: + return DatabaseBlock; + default: + return UnSupportedBlock; + } + }, [node.type]) as FC<EditorElementProps>; + + const InlineComponent = useMemo(() => { + switch (node.type) { + case InlineBlockType.Formula: + return Formula; + case InlineBlockType.Mention: + return Mention; + default: + return null; + } + }, [node.type]) as FC<EditorElementProps>; + + const className = useMemo(() => { + const data = (node.data as BlockData) || {}; + const align = data.align; + + return `block-element flex rounded ${align ? `block-align-${align}` : ''}`; + }, [node.data]); + + const style = useMemo(() => { + const data = (node.data as BlockData) || {}; + + return { + backgroundColor: data.bg_color ? renderColor(data.bg_color) : undefined, + color: data.font_color ? renderColor(data.font_color) : undefined, + }; + }, [node.data]); + + if (InlineComponent) { + return ( + <InlineComponent {...attributes} node={node}> + {children} + </InlineComponent> + ); } - }, [node.type]) as FC<EditorElementProps>; - const InlineComponent = useMemo(() => { - switch (node.type) { - case InlineBlockType.Formula: - return Formula; - case InlineBlockType.Mention: - return Mention; - default: - return null; + if (node.type === YjsEditorKey.text) { + return ( + <Text {...attributes} node={node as TextNode}> + {children} + </Text> + ); } - }, [node.type]) as FC<EditorElementProps>; - const className = useMemo(() => { - const data = (node.data as BlockData) || {}; - const align = data.align; - - return `block-element flex rounded ${align ? `block-align-${align}` : ''}`; - }, [node.data]); - - const style = useMemo(() => { - const data = (node.data as BlockData) || {}; - - return { - backgroundColor: data.bg_color ? renderColor(data.bg_color) : undefined, - color: data.font_color ? renderColor(data.font_color) : undefined, - }; - }, [node.data]); - - if (InlineComponent) { return ( - <InlineComponent {...attributes} node={node}> - {children} - </InlineComponent> + <Suspense fallback={<Skeleton width={'100%'} height={24} />}> + <ErrorBoundary fallbackRender={ElementFallbackRender}> + <div {...attributes} data-block-type={node.type} className={className}> + <Component style={style} className={`flex w-full flex-col`} node={node}> + {children} + </Component> + </div> + </ErrorBoundary> + </Suspense> ); - } - - if (node.type === YjsEditorKey.text) { - return ( - <Text {...attributes} node={node as TextNode}> - {children} - </Text> - ); - } - - return ( - <div {...attributes} data-block-type={node.type} className={className}> - <Component style={style} className={`flex w-full flex-col`} node={node}> - {children} - </Component> - </div> - ); -}; + }, + (prevProps, nextProps) => isEqual(prevProps.element, nextProps.element) +); diff --git a/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionPage.tsx b/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionPage.tsx index e4df335a3b..40e6d31e23 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionPage.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionPage.tsx @@ -1,20 +1,15 @@ -import { layoutMap, ViewLayout, YjsFolderKey } from '@/application/collab.type'; -import { useId } from '@/components/_shared/context-provider/IdProvider'; +import { useNavigateToView } from '@/application/folder-yjs'; import { usePageInfo } from '@/components/_shared/page/usePageInfo'; import React from 'react'; -import { useNavigate } from 'react-router-dom'; function MentionPage({ pageId }: { pageId: string }) { - const navigate = useNavigate(); - const { workspaceId } = useId(); - const { view, icon, name } = usePageInfo(pageId); + const onNavigateToView = useNavigateToView(); + const { icon, name } = usePageInfo(pageId); return ( <span onClick={() => { - const layout = parseInt(view?.get(YjsFolderKey.layout) ?? '0') as ViewLayout; - - navigate(`/workspace/${workspaceId}/${layoutMap[layout]}/${pageId}`); + onNavigateToView?.(pageId); }} className={`mention-inline px-1 underline`} contentEditable={false} diff --git a/frontend/appflowy_web_app/src/components/editor/editor.scss b/frontend/appflowy_web_app/src/components/editor/editor.scss index abf09c726e..71832ec330 100644 --- a/frontend/appflowy_web_app/src/components/editor/editor.scss +++ b/frontend/appflowy_web_app/src/components/editor/editor.scss @@ -52,6 +52,7 @@ [role=textbox] { .text-element { + @apply my-1; &::selection { @apply bg-transparent; } @@ -209,11 +210,6 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } -.grid-block .grid-scroll-container::-webkit-scrollbar { - width: 0; - height: 0; -} - .image-render { .image-resizer { @apply absolute w-[10px] top-0 z-10 flex h-full cursor-col-resize items-center justify-end; @@ -269,11 +265,39 @@ span[data-slate-placeholder="true"]:not(.inline-block-content) { } .mention-content { - @apply ml-5; + @apply ml-6; } } .text-block-icon { @apply flex items-center justify-center; -} \ No newline at end of file +} + + +.font-small { + .text-element { + line-height: 1.7; + } +} + + +.font-large { + .text-element { + line-height: 1.2; + } +} + +.line-height-large { + .text-element { + margin-top: 6px; + margin-bottom: 6px; + } +} + +.line-height-small { + .text-element { + margin-top: 0px; + margin-bottom: 0px; + } +} diff --git a/frontend/appflowy_web_app/src/components/error/ElementFallbackRender.tsx b/frontend/appflowy_web_app/src/components/error/ElementFallbackRender.tsx new file mode 100644 index 0000000000..ddfdac39f1 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/error/ElementFallbackRender.tsx @@ -0,0 +1,11 @@ +import { Alert } from '@mui/material'; +import { FallbackProps } from 'react-error-boundary'; + +export function ElementFallbackRender({ error }: FallbackProps) { + return ( + <Alert severity={'error'} variant={'standard'} className={'my-2'}> + <p>Something went wrong:</p> + <pre>{error.message}</pre> + </Alert> + ); +} diff --git a/frontend/appflowy_web_app/src/components/folder/ViewItem.tsx b/frontend/appflowy_web_app/src/components/folder/ViewItem.tsx index c95cd305f9..49feb382e2 100644 --- a/frontend/appflowy_web_app/src/components/folder/ViewItem.tsx +++ b/frontend/appflowy_web_app/src/components/folder/ViewItem.tsx @@ -1,19 +1,15 @@ -import { layoutMap, ViewLayout, YjsFolderKey } from '@/application/collab.type'; +import { useNavigateToView } from '@/application/folder-yjs'; import React from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; import Page from '@/components/_shared/page/Page'; function ViewItem({ id }: { id: string }) { - const navigate = useNavigate(); - const { pathname } = useLocation(); + const onNavigateToView = useNavigateToView(); return ( <div className={'cursor-pointer border-b border-line-border py-4 px-2'}> <Page - onClick={(view) => { - const layout = parseInt(view?.get(YjsFolderKey.layout) ?? '0') as ViewLayout; - - navigate(`${pathname}/${layoutMap[layout]}/${id}`); + onClick={() => { + onNavigateToView?.(id); }} id={id} /> diff --git a/frontend/appflowy_web_app/src/components/layout/Header.tsx b/frontend/appflowy_web_app/src/components/layout/Header.tsx index 5c874db35c..df87892b42 100644 --- a/frontend/appflowy_web_app/src/components/layout/Header.tsx +++ b/frontend/appflowy_web_app/src/components/layout/Header.tsx @@ -2,10 +2,9 @@ import { downloadPage, openAppFlowySchema, openUrl } from '@/utils/url'; import { Button } from '@mui/material'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { useParams } from 'react-router-dom'; -import Page from 'src/components/_shared/page/Page'; import { ReactComponent as Logo } from '@/assets/logo.svg'; import Popover, { PopoverOrigin } from '@mui/material/Popover'; +import Breadcrumb from 'src/components/layout/breadcrumb/Breadcrumb'; const popoverOrigin: { anchorOrigin: PopoverOrigin; @@ -22,14 +21,13 @@ const popoverOrigin: { }; function Header() { - const { objectId } = useParams(); const { t } = useTranslation(); const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null); return ( <div className={'appflowy-top-bar flex h-[64px] p-4'}> - <div className={'flex flex-1 items-center justify-between'}> - <div className={'flex-1'}>{objectId && <Page id={objectId} />}</div> + <div className={'flex w-full items-center justify-between overflow-hidden'}> + <Breadcrumb /> <Button className={'border-line-border'} diff --git a/frontend/appflowy_web_app/src/components/layout/Layout.hooks.ts b/frontend/appflowy_web_app/src/components/layout/Layout.hooks.ts new file mode 100644 index 0000000000..0313015d3f --- /dev/null +++ b/frontend/appflowy_web_app/src/components/layout/Layout.hooks.ts @@ -0,0 +1,96 @@ +import { YFolder, YjsEditorKey, YjsFolderKey } from '@/application/collab.type'; +import { Crumb } from '@/application/folder-yjs'; +import { AFConfigContext } from '@/components/app/AppConfig'; +import { useCallback, useContext, useEffect, useState } from 'react'; +import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; + +export function useLayout() { + const { workspaceId, objectId } = useParams(); + const [search] = useSearchParams(); + const folderService = useContext(AFConfigContext)?.service?.folderService; + const [folder, setFolder] = useState<YFolder | null>(null); + const views = folder?.get(YjsFolderKey.views); + const view = objectId ? views?.get(objectId) : null; + const [crumbs, setCrumbs] = useState<Crumb[]>([]); + + const getFolder = useCallback( + async (workspaceId: string) => { + const folder = (await folderService?.openWorkspace(workspaceId)) + ?.getMap(YjsEditorKey.data_section) + .get(YjsEditorKey.folder); + + if (!folder) return; + + console.log(folder.toJSON()); + setFolder(folder); + }, + [folderService] + ); + + useEffect(() => { + if (!workspaceId) return; + + void getFolder(workspaceId); + }, [getFolder, workspaceId]); + + const navigate = useNavigate(); + + const handleNavigateToView = useCallback( + (viewId: string) => { + const view = folder?.get(YjsFolderKey.views)?.get(viewId); + + if (!view) return; + navigate(`/view/${workspaceId}/${viewId}`); + }, + [folder, navigate, workspaceId] + ); + + const onChangeBreadcrumb = useCallback(() => { + if (!view) return; + const queue = [view]; + let parentId = view.get(YjsFolderKey.bid); + + while (parentId) { + const parent = views?.get(parentId); + + if (!parent) break; + + queue.unshift(parent); + parentId = parent?.get(YjsFolderKey.bid); + } + + setCrumbs( + queue + .map((view) => { + let icon = view.get(YjsFolderKey.icon); + + try { + icon = JSON.parse(icon || '')?.value; + } catch (e) { + // do nothing + } + + return { + viewId: view.get(YjsFolderKey.id), + name: view.get(YjsFolderKey.name), + icon: icon || '', + }; + }) + .slice(1) + ); + }, [view, views]); + + useEffect(() => { + onChangeBreadcrumb(); + + view?.observe(onChangeBreadcrumb); + views?.observe(onChangeBreadcrumb); + + return () => { + view?.unobserve(onChangeBreadcrumb); + views?.unobserve(onChangeBreadcrumb); + }; + }, [search, onChangeBreadcrumb, view, views]); + + return { folder, handleNavigateToView, crumbs, setCrumbs }; +} diff --git a/frontend/appflowy_web_app/src/components/layout/Layout.tsx b/frontend/appflowy_web_app/src/components/layout/Layout.tsx index 46e4619cf8..dc3f075f69 100644 --- a/frontend/appflowy_web_app/src/components/layout/Layout.tsx +++ b/frontend/appflowy_web_app/src/components/layout/Layout.tsx @@ -1,37 +1,23 @@ -import { YFolder, YjsEditorKey } from '@/application/collab.type'; import { FolderProvider } from '@/components/_shared/context-provider/FolderProvider'; -import { AFConfigContext } from '@/components/app/AppConfig'; import Header from '@/components/layout/Header'; import { AFScroller } from '@/components/_shared/scroller'; -import React, { useCallback, useContext, useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useLayout } from '@/components/layout/Layout.hooks'; +import React from 'react'; import './layout.scss'; +import { ReactComponent as Logo } from '@/assets/logo.svg'; function Layout({ children }: { children: React.ReactNode }) { - const { workspaceId } = useParams(); - const folderService = useContext(AFConfigContext)?.service?.folderService; - const [folder, setFolder] = useState<YFolder | null>(null); - const getFolder = useCallback( - async (workspaceId: string) => { - const folder = (await folderService?.openWorkspace(workspaceId)) - ?.getMap(YjsEditorKey.data_section) - .get(YjsEditorKey.folder); + const { folder, handleNavigateToView, crumbs, setCrumbs } = useLayout(); - if (!folder) return; + if (!folder) + return ( + <div className={'flex h-screen w-screen items-center justify-center'}> + <Logo className={'h-20 w-20'} /> + </div> + ); - console.log(folder.toJSON()); - setFolder(folder); - }, - [folderService] - ); - - useEffect(() => { - if (!workspaceId) return; - - void getFolder(workspaceId); - }, [getFolder, workspaceId]); return ( - <FolderProvider folder={folder}> + <FolderProvider setCrumbs={setCrumbs} crumbs={crumbs} onNavigateToView={handleNavigateToView} folder={folder}> <Header /> <AFScroller overflowXHidden diff --git a/frontend/appflowy_web_app/src/components/layout/breadcrumb/Breadcrumb.tsx b/frontend/appflowy_web_app/src/components/layout/breadcrumb/Breadcrumb.tsx new file mode 100644 index 0000000000..02e682514e --- /dev/null +++ b/frontend/appflowy_web_app/src/components/layout/breadcrumb/Breadcrumb.tsx @@ -0,0 +1,25 @@ +import { useCrumbs } from '@/application/folder-yjs'; +import Item from '@/components/layout/breadcrumb/Item'; +import React, { useMemo } from 'react'; + +export function Breadcrumb() { + const crumbs = useCrumbs(); + + const renderCrumb = useMemo(() => { + return crumbs?.map((crumb, index) => { + const isLast = index === crumbs.length - 1; + const key = crumb.rowId ? `${crumb.viewId}-${crumb.rowId}` : `${crumb.viewId}`; + + return ( + <React.Fragment key={key}> + <Item crumb={crumb} disableClick={isLast} /> + {!isLast && <span>/</span>} + </React.Fragment> + ); + }); + }, [crumbs]); + + return <div className={'flex flex-1 items-center gap-2 overflow-hidden'}>{renderCrumb}</div>; +} + +export default Breadcrumb; diff --git a/frontend/appflowy_web_app/src/components/layout/breadcrumb/Item.tsx b/frontend/appflowy_web_app/src/components/layout/breadcrumb/Item.tsx new file mode 100644 index 0000000000..9bad9f5eba --- /dev/null +++ b/frontend/appflowy_web_app/src/components/layout/breadcrumb/Item.tsx @@ -0,0 +1,29 @@ +import { Crumb, useNavigateToView } from '@/application/folder-yjs'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +function Item({ crumb, disableClick = false }: { crumb: Crumb; disableClick?: boolean }) { + const { viewId, icon, name } = crumb; + + const { t } = useTranslation(); + const onNavigateToView = useNavigateToView(); + + return ( + <div + className={`flex items-center gap-1 ${!disableClick ? 'cursor-pointer' : 'flex-1 overflow-hidden'}`} + onClick={() => { + if (disableClick) return; + onNavigateToView?.(viewId); + }} + > + {icon} + <span + className={!disableClick ? 'max-w-[250px] truncate hover:text-fill-default hover:underline' : 'flex-1 truncate'} + > + {name || t('menuAppHeader.defaultNewPageName')} + </span> + </div> + ); +} + +export default Item; diff --git a/frontend/appflowy_web_app/src/components/layout/breadcrumb/index.ts b/frontend/appflowy_web_app/src/components/layout/breadcrumb/index.ts new file mode 100644 index 0000000000..116446358b --- /dev/null +++ b/frontend/appflowy_web_app/src/components/layout/breadcrumb/index.ts @@ -0,0 +1 @@ +export * from './Breadcrumb'; diff --git a/frontend/appflowy_web_app/src/components/layout/layout.scss b/frontend/appflowy_web_app/src/components/layout/layout.scss index 2aa965dd15..b51a842e43 100644 --- a/frontend/appflowy_web_app/src/components/layout/layout.scss +++ b/frontend/appflowy_web_app/src/components/layout/layout.scss @@ -1,3 +1,4 @@ +@use "src/styles/mixin.scss"; .sketch-picker { background-color: var(--bg-body) !important; @@ -16,29 +17,30 @@ box-shadow: var(--line-border) 0px 0px 0px 1px inset !important; } -.appflowy-date-picker-calendar { - width: 100%; -} +body { -.grid-sticky-header::-webkit-scrollbar { - width: 0; - height: 0; -} + &[data-os="windows"]:not([data-browser="firefox"]) { + .appflowy-custom-scroller { + @include mixin.hidden-scrollbar + } -.grid-scroll-container::-webkit-scrollbar { - width: 0; - height: 0; -} + .MuiBox-root { + @include mixin.scrollbar-style; + } + } - -.appflowy-scroll-container { - &::-webkit-scrollbar { - width: 0; - height: 0; + .grid-sticky-header { + @include mixin.hidden-scrollbar } } + +.appflowy-date-picker-calendar { + width: 100%; +} + + .appflowy-scrollbar-thumb-horizontal, .appflowy-scrollbar-thumb-vertical { background-color: var(--scrollbar-thumb); border-radius: 4px; @@ -46,16 +48,8 @@ } -.workspaces, .database-conditions, .grid-scroll-table, .grid-board, .MuiPaper-root, .appflowy-database { - ::-webkit-scrollbar { - width: 0; - height: 0; - } -} - - .view-icon { - @apply flex w-fit cursor-pointer rounded-lg py-2 text-6xl; + @apply flex w-fit leading-[1.5em] cursor-pointer rounded-lg py-2 text-[1.5em]; font-family: "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", EmojiSymbols; line-height: 1em; white-space: nowrap; diff --git a/frontend/appflowy_web_app/src/pages/DatabasePage.tsx b/frontend/appflowy_web_app/src/pages/DatabasePage.tsx index f5b4839924..10e9e5c015 100644 --- a/frontend/appflowy_web_app/src/pages/DatabasePage.tsx +++ b/frontend/appflowy_web_app/src/pages/DatabasePage.tsx @@ -1,24 +1,71 @@ import { useId } from '@/components/_shared/context-provider/IdProvider'; import { DatabaseHeader } from '@/components/database/components/header'; -import React from 'react'; +import { useGetDatabaseId, useLoadDatabase } from '@/components/database/Database.hooks'; +import { DatabaseContextProvider } from '@/components/database/DatabaseContext'; +import CircularProgress from '@mui/material/CircularProgress'; +import React, { useCallback, useMemo } from 'react'; import { useSearchParams } from 'react-router-dom'; import DatabaseRow from '@/components/database/DatabaseRow'; import Database from '@/components/database/Database'; +import RecordNotFound from 'src/components/_shared/not-found/RecordNotFound'; function DatabasePage() { - const objectId = useId()?.objectId; - const [search] = useSearchParams(); + const { objectId } = useId() || {}; + const [search, setSearch] = useSearchParams(); const rowId = search.get('r'); - if (rowId) { - return <DatabaseRow rowId={rowId} />; + const viewId = search.get('v') || undefined; + const handleChangeView = useCallback( + (viewId: string) => { + setSearch({ v: viewId }); + }, + [setSearch] + ); + const handleNavigateToRow = useCallback( + (rowId: string) => { + setSearch({ r: rowId }); + }, + [setSearch] + ); + + const databaseId = useGetDatabaseId(objectId); + const rowIds = useMemo(() => (rowId ? [rowId] : undefined), [rowId]); + + const { doc, rows, notFound } = useLoadDatabase({ + databaseId, + rowIds, + }); + + if (notFound || !objectId) { + return <RecordNotFound open={notFound} />; + } + + if (!rows || !doc) { + return ( + <div className={'flex h-full w-full items-center justify-center'}> + <CircularProgress /> + </div> + ); } return ( - <div className={'relative flex h-full w-full flex-col'}> - <DatabaseHeader viewId={objectId} /> - <Database /> - </div> + <DatabaseContextProvider + isDatabaseRowPage={!!rowId} + navigateToRow={handleNavigateToRow} + viewId={viewId || objectId} + databaseDoc={doc} + rowDocMap={rows} + readOnly={true} + > + {rowId ? ( + <DatabaseRow rowId={rowId} /> + ) : ( + <div className={'relative flex h-full w-full flex-col'}> + <DatabaseHeader viewId={objectId} /> + <Database iidIndex={objectId} viewId={viewId || objectId} onNavigateToView={handleChangeView} /> + </div> + )} + </DatabaseContextProvider> ); } diff --git a/frontend/appflowy_web_app/src/pages/LoginPage.tsx b/frontend/appflowy_web_app/src/pages/LoginPage.tsx index 5d2dcceee4..a4ded1d5e3 100644 --- a/frontend/appflowy_web_app/src/pages/LoginPage.tsx +++ b/frontend/appflowy_web_app/src/pages/LoginPage.tsx @@ -13,7 +13,7 @@ function LoginPage() { const workspaceId = currentUser.user?.workspaceId; if (!redirect || redirect === '/') { - return navigate(`/workspace/${workspaceId}`); + return navigate(`/view/${workspaceId}`); } navigate(`${redirect}`); diff --git a/frontend/appflowy_web_app/src/pages/ProductPage.tsx b/frontend/appflowy_web_app/src/pages/ProductPage.tsx index 0cd4d16cac..1df649b077 100644 --- a/frontend/appflowy_web_app/src/pages/ProductPage.tsx +++ b/frontend/appflowy_web_app/src/pages/ProductPage.tsx @@ -1,3 +1,5 @@ +import { ViewLayout } from '@/application/collab.type'; +import { useViewLayout } from '@/application/folder-yjs'; import { IdProvider } from '@/components/_shared/context-provider/IdProvider'; import React, { lazy, useMemo } from 'react'; import { useParams } from 'react-router-dom'; @@ -5,36 +7,26 @@ import DocumentPage from '@/pages/DocumentPage'; const DatabasePage = lazy(() => import('./DatabasePage')); -enum URL_COLLAB_TYPE { - DOCUMENT = 'document', - GRID = 'grid', - BOARD = 'board', - CALENDAR = 'calendar', -} - function ProductPage() { - const { workspaceId, type, objectId } = useParams(); + const { workspaceId, objectId } = useParams(); + const type = useViewLayout(); + const PageComponent = useMemo(() => { switch (type) { - case URL_COLLAB_TYPE.DOCUMENT: + case ViewLayout.Document: return DocumentPage; - case URL_COLLAB_TYPE.GRID: - case URL_COLLAB_TYPE.BOARD: - case URL_COLLAB_TYPE.CALENDAR: + case ViewLayout.Grid: + case ViewLayout.Board: + case ViewLayout.Calendar: return DatabasePage; default: return null; } }, [type]); - console.log(workspaceId, type, objectId); - if (!workspaceId || !type || !objectId) return null; + if (!workspaceId || !objectId) return null; - return ( - <IdProvider workspaceId={workspaceId} objectId={objectId}> - {PageComponent && <PageComponent />} - </IdProvider> - ); + return <IdProvider objectId={objectId}>{PageComponent && <PageComponent />}</IdProvider>; } export default ProductPage; diff --git a/frontend/appflowy_web_app/src/slate-editor.d.ts b/frontend/appflowy_web_app/src/slate-editor.d.ts index 2ebcf7a88d..58b7c8502e 100644 --- a/frontend/appflowy_web_app/src/slate-editor.d.ts +++ b/frontend/appflowy_web_app/src/slate-editor.d.ts @@ -28,6 +28,7 @@ type CustomElement = { data?: unknown; blockId?: string; textId?: string; + relationId?: string; }; type CustomText = { text: string } & EditorInlineAttributes; diff --git a/frontend/appflowy_web_app/src/styles/mixin.scss b/frontend/appflowy_web_app/src/styles/mixin.scss new file mode 100644 index 0000000000..d571ef9cbf --- /dev/null +++ b/frontend/appflowy_web_app/src/styles/mixin.scss @@ -0,0 +1,23 @@ +@mixin hidden-scrollbar { + &::-webkit-scrollbar { + display: none; + } + + -ms-overflow-style: none; + scrollbar-width: none; // For Firefox +} + +@mixin scrollbar-style { + ::-webkit-scrollbar, &::-webkit-scrollbar { + width: 4px; + height: 4px; + } + + &:hover { + + &::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: var(--scrollbar-thumb); + } + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/styles/template.css b/frontend/appflowy_web_app/src/styles/template.css index b6f7dd3361..82a597519f 100644 --- a/frontend/appflowy_web_app/src/styles/template.css +++ b/frontend/appflowy_web_app/src/styles/template.css @@ -48,3 +48,12 @@ th { @apply text-left font-normal; } +html { + font-size: 16px; +} + +@media (max-width: 600px) { + html { + font-size: 14px; + } +} \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/styles/variables/dark.variables.css b/frontend/appflowy_web_app/src/styles/variables/dark.variables.css index 6753969ca0..de8fcf9824 100644 --- a/frontend/appflowy_web_app/src/styles/variables/dark.variables.css +++ b/frontend/appflowy_web_app/src/styles/variables/dark.variables.css @@ -1,121 +1,58 @@ -/** -* Do not edit directly -* Generated on Thu, 09 May 2024 03:26:45 GMT -* Generated from $pnpm css:variables -*/ :root[data-dark-mode=true] { - --base-light-neutral-50: #f9fafd; - --base-light-neutral-100: #e5e5e5; - --base-light-neutral-200: #e2e4eb; - --base-light-neutral-300: #f2f2f2; - --base-light-neutral-400: #e0e0e0; - --base-light-neutral-500: #bdbdbd; - --base-light-neutral-600: #828282; - --base-light-neutral-700: #4f4f4f; - --base-light-neutral-800: #333333; - --base-light-neutral-900: #1f2329; - --base-light-neutral-1000: #000000; - --base-light-neutral-00: #ffffff; - --base-light-blue-50: #f2fcff; - --base-light-blue-100: #e0f8ff; - --base-light-blue-200: #a6ecff; - --base-light-blue-300: #52d1f4; - --base-light-blue-400: #00bcf0; - --base-light-blue-500: #05ade2; - --base-light-blue-600: #009fd1; - --base-light-color-deep-red: #fb006d; - --base-light-color-deep-yellow: #ffd667; - --base-light-color-deep-green: #66cf80; - --base-light-color-deep-blue: #00bcf0; - --base-light-color-light-purple: #e8e0ff; - --base-light-color-light-pink: #ffe7ee; - --base-light-color-light-orange: #ffefe3; - --base-light-color-light-yellow: #fff2cd; - --base-light-color-light-lime: #f5ffdc; - --base-light-color-light-green: #ddffd6; - --base-light-color-light-aqua: #defff1; - --base-light-color-light-blue: #e1fbff; - --base-light-color-light-red: #ffdddd; - --base-black-neutral-100: #252F41; - --base-black-neutral-200: #313c51; - --base-black-neutral-300: #3c4557; - --base-black-neutral-400: #525A69; - --base-black-neutral-500: #59647a; - --base-black-neutral-600: #87A0BF; - --base-black-neutral-700: #99a6b8; - --base-black-neutral-800: #e2e9f2; - --base-black-neutral-900: #eff4fb; - --base-black-neutral-1000: #ffffff; - --base-black-neutral-n50: #232b38; - --base-black-neutral-n00: #1a202c; - --base-black-blue-50: #232b38; - --base-black-blue-100: #005174; - --base-black-blue-200: #a6ecff; - --base-black-blue-300: #52d1f4; - --base-black-blue-400: #00bcf0; - --base-black-blue-500: #05ade2; - --base-black-blue-600: #009fd1; - --base-black-color-deep-red: #d32772; - --base-black-color-deep-yellow: #e9b320; - --base-black-color-deep-green: #3ba856; - --base-black-color-deep-blue: #2e9dbb; - --base-black-color-light-purple: #4D4078; - --base-black-color-light-blue: #2C3B58; - --base-black-color-light-green: #3C5133; - --base-black-color-light-yellow: #695E3E; - --base-black-color-light-pink: #5E3C5E; - --base-black-color-light-red: #56363F; - --base-black-color-light-aqua: #1B3849; - --base-black-color-light-lime: #394027; - --base-black-color-light-orange: #5E3C3C; - --base-else-brand: #2c144b; - --text-title: #e2e9f2; - --text-caption: #87A0BF; - --text-placeholder: #3c4557; - --text-link-default: #00bcf0; - --text-link-hover: #52d1f4; - --text-link-pressed: #009fd1; - --text-link-disabled: #005174; - --icon-primary: #e2e9f2; - --icon-secondary: #59647a; - --icon-disabled: #525A69; - --icon-on-toolbar: white; - --line-border: #59647a; - --line-divider: #252F41; - --line-on-toolbar: #99a6b8; - --fill-default: #00bcf0; - --fill-hover: #005174; - --fill-toolbar: #0F111C; - --fill-selector: #232b38; - --fill-list-active: #3c4557; - --fill-list-hover: #005174; - --content-blue-400: #00bcf0; - --content-blue-300: #52d1f4; - --content-blue-600: #009fd1; - --content-blue-100: #005174; - --content-on-fill: #1a202c; - --content-on-tag: #99a6b8; - --content-blue-50: #232b38; - --bg-body: #1a202c; - --bg-base: #232b38; - --bg-mask: rgba(0,0,0,0.7); - --bg-tips: #005174; - --bg-brand: #2c144b; - --function-error: #d32772; - --function-warning: #e9b320; - --function-success: #3ba856; - --function-info: #2e9dbb; - --tint-red: #56363F; - --tint-green: #3C5133; - --tint-purple: #4D4078; - --tint-blue: #2C3B58; - --tint-yellow: #695E3E; - --tint-pink: #5E3C5E; - --tint-lime: #394027; - --tint-aqua: #1B3849; - --tint-orange: #5E3C3C; - --shadow: 0px 0px 25px 0px rgba(0,0,0,0.3); - --scrollbar-track: #252F41; - --scrollbar-thumb: #3c4557; + --text-title: #e2e9f2; + --text-caption: #87A0BF; + --text-placeholder: #3c4557; + --text-link-default: #00bcf0; + --text-link-hover: #52d1f4; + --text-link-pressed: #009fd1; + --text-link-disabled: #005174; + --icon-primary: #e2e9f2; + --icon-secondary: #59647a; + --icon-disabled: #525A69; + --icon-on-toolbar: white; + --line-border: #59647a; + --line-divider: #252F41; + --line-on-toolbar: #99a6b8; + --fill-default: #00bcf0; + --fill-hover: #005174; + --fill-toolbar: #0F111C; + --fill-selector: #232b38; + --fill-list-active: #3c4557; + --fill-list-hover: #005174; + --content-blue-400: #00bcf0; + --content-blue-300: #52d1f4; + --content-blue-600: #009fd1; + --content-blue-100: #005174; + --content-on-fill: #1a202c; + --content-on-tag: #99a6b8; + --content-blue-50: #232b38; + --bg-body: #1a202c; + --bg-base: #232b38; + --bg-mask: rgba(0, 0, 0, 0.7); + --bg-tips: #005174; + --bg-brand: #2c144b; + --function-error: #d32772; + --function-warning: #e9b320; + --function-success: #3ba856; + --function-info: #2e9dbb; + --tint-red: #56363F; + --tint-green: #3C5133; + --tint-purple: #4D4078; + --tint-blue: #2C3B58; + --tint-yellow: #695E3E; + --tint-pink: #5E3C5E; + --tint-lime: #394027; + --tint-aqua: #1B3849; + --tint-orange: #5E3C3C; + --shadow: 0px 0px 25px 0px rgba(0, 0, 0, 0.3); + --scrollbar-track: #252F41; + --scrollbar-thumb: #3c4557; + --gradient1: linear-gradient(233deg, #34BDAF 0%, #B682D5 100%); + --gradient2: linear-gradient(180deg, #4CC2CC 0%, #E17570 100%); + --gradient3: linear-gradient(180deg, #AF70E1 0%, #ED7196 100%); + --gradient4: linear-gradient(180deg, #A348D6 0%, #45A7DF 100%); + --gradient5: linear-gradient(56.2deg, #5749CA 0%, #BB4A97 100%); + --gradient6: linear-gradient(180deg, #036FFA 0%, #00B8E5 100%); + --gradient7: linear-gradient(38.2deg, #F0C6CF 0%, #DECCE2 40.4754%, #CAD3F9 100%); } \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/styles/variables/light.variables.css b/frontend/appflowy_web_app/src/styles/variables/light.variables.css index b1494114bd..cd4ffee0f6 100644 --- a/frontend/appflowy_web_app/src/styles/variables/light.variables.css +++ b/frontend/appflowy_web_app/src/styles/variables/light.variables.css @@ -1,124 +1,61 @@ -/** -* Do not edit directly -* Generated on Thu, 09 May 2024 03:26:45 GMT -* Generated from $pnpm css:variables -*/ :root { - --base-light-neutral-50: #f9fafd; - --base-light-neutral-100: #e5e5e5; - --base-light-neutral-200: #e2e4eb; - --base-light-neutral-300: #f2f2f2; - --base-light-neutral-400: #e0e0e0; - --base-light-neutral-500: #bdbdbd; - --base-light-neutral-600: #828282; - --base-light-neutral-700: #4f4f4f; - --base-light-neutral-800: #333333; - --base-light-neutral-900: #1f2329; - --base-light-neutral-1000: #000000; - --base-light-neutral-00: #ffffff; - --base-light-blue-50: #f2fcff; - --base-light-blue-100: #e0f8ff; - --base-light-blue-200: #a6ecff; - --base-light-blue-300: #52d1f4; - --base-light-blue-400: #00bcf0; - --base-light-blue-500: #05ade2; - --base-light-blue-600: #009fd1; - --base-light-color-deep-red: #fb006d; - --base-light-color-deep-yellow: #ffd667; - --base-light-color-deep-green: #66cf80; - --base-light-color-deep-blue: #00bcf0; - --base-light-color-light-purple: #e8e0ff; - --base-light-color-light-pink: #ffe7ee; - --base-light-color-light-orange: #ffefe3; - --base-light-color-light-yellow: #fff2cd; - --base-light-color-light-lime: #f5ffdc; - --base-light-color-light-green: #ddffd6; - --base-light-color-light-aqua: #defff1; - --base-light-color-light-blue: #e1fbff; - --base-light-color-light-red: #ffdddd; - --base-black-neutral-100: #252F41; - --base-black-neutral-200: #313c51; - --base-black-neutral-300: #3c4557; - --base-black-neutral-400: #525A69; - --base-black-neutral-500: #59647a; - --base-black-neutral-600: #87A0BF; - --base-black-neutral-700: #99a6b8; - --base-black-neutral-800: #e2e9f2; - --base-black-neutral-900: #eff4fb; - --base-black-neutral-1000: #ffffff; - --base-black-neutral-n50: #232b38; - --base-black-neutral-n00: #1a202c; - --base-black-blue-50: #232b38; - --base-black-blue-100: #005174; - --base-black-blue-200: #a6ecff; - --base-black-blue-300: #52d1f4; - --base-black-blue-400: #00bcf0; - --base-black-blue-500: #05ade2; - --base-black-blue-600: #009fd1; - --base-black-color-deep-red: #d32772; - --base-black-color-deep-yellow: #e9b320; - --base-black-color-deep-green: #3ba856; - --base-black-color-deep-blue: #2e9dbb; - --base-black-color-light-purple: #4D4078; - --base-black-color-light-blue: #2C3B58; - --base-black-color-light-green: #3C5133; - --base-black-color-light-yellow: #695E3E; - --base-black-color-light-pink: #5E3C5E; - --base-black-color-light-red: #56363F; - --base-black-color-light-aqua: #1B3849; - --base-black-color-light-lime: #394027; - --base-black-color-light-orange: #5E3C3C; - --base-else-brand: #2c144b; - --text-title: #333333; - --text-caption: #828282; - --text-placeholder: #bdbdbd; - --text-disabled: #e0e0e0; - --text-link-default: #00bcf0; - --text-link-hover: #52d1f4; - --text-link-pressed: #009fd1; - --text-link-disabled: #e0f8ff; - --icon-primary: #333333; - --icon-secondary: #59647a; - --icon-disabled: #e0e0e0; - --icon-on-toolbar: #ffffff; - --line-border: #bdbdbd; - --line-divider: #e5e5e5; - --line-on-toolbar: #4f4f4f; - --fill-toolbar: #333333; - --fill-default: #00bcf0; - --fill-hover: #52d1f4; - --fill-pressed: #009fd1; - --fill-active: #e0f8ff; - --fill-list-hover: #e0f8ff; - --fill-list-active: #f9fafd; - --content-blue-400: #00bcf0; - --content-blue-300: #52d1f4; - --content-blue-600: #009fd1; - --content-blue-100: #e0f8ff; - --content-blue-50: #f2fcff; - --content-on-fill-hover: #00bcf0; - --content-on-fill: #ffffff; - --content-on-tag: #4f4f4f; - --bg-body: #ffffff; - --bg-base: #f9fafd; - --bg-mask: rgba(0,0,0,0.55); - --bg-tips: #e0f8ff; - --bg-brand: #2c144b; - --function-error: #fb006d; - --function-waring: #ffd667; - --function-success: #66cf80; - --function-info: #00bcf0; - --tint-purple: #e8e0ff; - --tint-pink: #ffe7ee; - --tint-red: #ffdddd; - --tint-lime: #f5ffdc; - --tint-green: #ddffd6; - --tint-aqua: #defff1; - --tint-blue: #e1fbff; - --tint-orange: #ffefe3; - --tint-yellow: #fff2cd; - --shadow: 0px 0px 10px 0px rgba(0,0,0,0.1); - --scrollbar-thumb: #bdbdbd; - --scrollbar-track: #e5e5e5; + --text-title: #333333; + --text-caption: #828282; + --text-placeholder: #bdbdbd; + --text-disabled: #e0e0e0; + --text-link-default: #00bcf0; + --text-link-hover: #52d1f4; + --text-link-pressed: #009fd1; + --text-link-disabled: #e0f8ff; + --icon-primary: #333333; + --icon-secondary: #59647a; + --icon-disabled: #e0e0e0; + --icon-on-toolbar: #ffffff; + --line-border: #bdbdbd; + --line-divider: #e5e5e5; + --line-on-toolbar: #4f4f4f; + --fill-toolbar: #333333; + --fill-default: #00bcf0; + --fill-hover: #52d1f4; + --fill-pressed: #009fd1; + --fill-active: #e0f8ff; + --fill-list-hover: #e0f8ff; + --fill-list-active: #f9fafd; + --content-blue-400: #00bcf0; + --content-blue-300: #52d1f4; + --content-blue-600: #009fd1; + --content-blue-100: #e0f8ff; + --content-blue-50: #f2fcff; + --content-on-fill-hover: #00bcf0; + --content-on-fill: #ffffff; + --content-on-tag: #4f4f4f; + --bg-body: #ffffff; + --bg-base: #f9fafd; + --bg-mask: rgba(0, 0, 0, 0.55); + --bg-tips: #e0f8ff; + --bg-brand: #2c144b; + --function-error: #fb006d; + --function-waring: #ffd667; + --function-success: #66cf80; + --function-info: #00bcf0; + --tint-purple: #e8e0ff; + --tint-pink: #ffe7ee; + --tint-red: #ffdddd; + --tint-lime: #f5ffdc; + --tint-green: #ddffd6; + --tint-aqua: #defff1; + --tint-blue: #e1fbff; + --tint-orange: #ffefe3; + --tint-yellow: #fff2cd; + --shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1); + --scrollbar-thumb: #bdbdbd; + --scrollbar-track: #e5e5e5; + --gradient1: linear-gradient(233deg, #34BDAF 0%, #B682D5 100%); + --gradient2: linear-gradient(180deg, #4CC2CC 0%, #E17570 100%); + --gradient3: linear-gradient(180deg, #AF70E1 0%, #ED7196 100%); + --gradient4: linear-gradient(180deg, #A348D6 0%, #45A7DF 100%); + --gradient5: linear-gradient(56.2deg, #5749CA 0%, #BB4A97 100%); + --gradient6: linear-gradient(180deg, #036FFA 0%, #00B8E5 100%); + --gradient7: linear-gradient(38.2deg, #F0C6CF 0%, #DECCE2 40.4754%, #CAD3F9 100%); } \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/utils/color.ts b/frontend/appflowy_web_app/src/utils/color.ts index 025c8c45ed..9de9da1dca 100644 --- a/frontend/appflowy_web_app/src/utils/color.ts +++ b/frontend/appflowy_web_app/src/utils/color.ts @@ -10,6 +10,16 @@ export enum ColorEnum { Blue = 'appflowy_them_color_tint9', } +export enum GradientEnum { + gradient1 = 'appflowy_them_color_gradient1', + gradient2 = 'appflowy_them_color_gradient2', + gradient3 = 'appflowy_them_color_gradient3', + gradient4 = 'appflowy_them_color_gradient4', + gradient5 = 'appflowy_them_color_gradient5', + gradient6 = 'appflowy_them_color_gradient6', + gradient7 = 'appflowy_them_color_gradient7', +} + export const colorMap = { [ColorEnum.Purple]: 'var(--tint-purple)', [ColorEnum.Pink]: 'var(--tint-pink)', @@ -22,6 +32,16 @@ export const colorMap = { [ColorEnum.Blue]: 'var(--tint-blue)', }; +export const gradientMap = { + [GradientEnum.gradient1]: 'var(--gradient1)', + [GradientEnum.gradient2]: 'var(--gradient2)', + [GradientEnum.gradient3]: 'var(--gradient3)', + [GradientEnum.gradient4]: 'var(--gradient4)', + [GradientEnum.gradient5]: 'var(--gradient5)', + [GradientEnum.gradient6]: 'var(--gradient6)', + [GradientEnum.gradient7]: 'var(--gradient7)', +}; + // Convert ARGB to RGBA // Flutter uses ARGB, but CSS uses RGBA function argbToRgba(color: string): string { @@ -46,5 +66,9 @@ export function renderColor(color: string) { return colorMap[color as ColorEnum]; } + if (gradientMap[color as GradientEnum]) { + return gradientMap[color as GradientEnum]; + } + return argbToRgba(color); } diff --git a/frontend/appflowy_web_app/src/utils/platform.ts b/frontend/appflowy_web_app/src/utils/platform.ts index 285e38bc73..fc3a538750 100644 --- a/frontend/appflowy_web_app/src/utils/platform.ts +++ b/frontend/appflowy_web_app/src/utils/platform.ts @@ -1,5 +1,6 @@ export function getPlatform() { return { isTauri: !!import.meta.env.TAURI_PLATFORM, + isMobile: window.navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i), }; } diff --git a/frontend/appflowy_web_app/style-dictionary/config.cjs b/frontend/appflowy_web_app/style-dictionary/config.cjs deleted file mode 100644 index 10d7084060..0000000000 --- a/frontend/appflowy_web_app/style-dictionary/config.cjs +++ /dev/null @@ -1,114 +0,0 @@ -const StyleDictionary = require('style-dictionary'); -const fs = require('fs'); -const path = require('path'); - -// Add comment header to generated files -StyleDictionary.registerFormat({ - name: 'css/variables', - formatter: function(dictionary, config) { - const header = `/**\n` + '* Do not edit directly\n' + `* Generated on ${new Date().toUTCString()}\n` + `* Generated from $pnpm css:variables \n` + `*/\n\n`; - const allProperties = dictionary.allProperties; - const properties = allProperties.map(prop => { - const { name, value } = prop; - return ` --${name}: ${value};` - }).join('\n'); - // generate tailwind config - generateTailwindConfig(allProperties); - return header + `:root${this.selector} {\n${properties}\n}` - } -}); - -// expand shadow tokens into a single string -StyleDictionary.registerTransform({ - name: 'shadow/spreadShadow', - type: 'value', - matcher: function (prop) { - return prop.type === 'boxShadow'; - }, - transformer: function (prop) { - // destructure shadow values from original token value - const { x, y, blur, spread, color } = prop.original.value; - - return `${x}px ${y}px ${blur}px ${spread}px ${color}`; - }, -}); - -const transforms = ['attribute/cti', 'name/cti/kebab', 'shadow/spreadShadow']; - -// Generate Light CSS variables -StyleDictionary.extend({ - source: ['./style-dictionary/tokens/base.json', './style-dictionary/tokens/light.json'], - platforms: { - css: { - transformGroup: 'css', - buildPath: './src/styles/variables/', - files: [ - { - format: 'css/variables', - destination: 'light.variables.css', - selector: '', - options: { - outputReferences: true - } - }, - ], - transforms, - }, - }, -}).buildAllPlatforms(); - -// Generate Dark CSS variables -StyleDictionary.extend({ - source: ['./style-dictionary/tokens/base.json', './style-dictionary/tokens/dark.json'], - platforms: { - css: { - transformGroup: 'css', - buildPath: './src/styles/variables/', - files: [ - { - format: 'css/variables', - destination: 'dark.variables.css', - selector: '[data-dark-mode=true]', - }, - ], - transforms, - }, - }, -}).buildAllPlatforms(); - - -function set(obj, path, value) { - const lastKey = path.pop(); - const lastObj = path.reduce((obj, key) => - obj[key] = obj[key] || {}, - obj); - lastObj[lastKey] = value; -} - -function writeFile (file, data) { - const header = `/**\n` + '* Do not edit directly\n' + `* Generated on ${new Date().toUTCString()}\n` + `* Generated from $pnpm css:variables \n` + `*/\n\n`; - const exportString = `module.exports = ${JSON.stringify(data, null, 2)}`; - fs.writeFileSync(path.join(__dirname, file), header + exportString); -} - -function generateTailwindConfig(allProperties) { - const tailwindColors = {}; - const tailwindBoxShadow = {}; - allProperties.forEach(prop => { - const { path, type, name, value } = prop; - if (path[0] === 'Base') { - return; - } - if (type === 'color') { - if (name.includes('fill')) { - console.log(prop); - } - set(tailwindColors, path, `var(--${name})`); - } - if (type === 'boxShadow') { - set(tailwindBoxShadow, ['md'], `var(--${name})`); - } - }); - writeFile('./tailwind/colors.cjs', tailwindColors); - writeFile('./tailwind/box-shadow.cjs', tailwindBoxShadow); -} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tokens/base.json b/frontend/appflowy_web_app/style-dictionary/tokens/base.json deleted file mode 100644 index f92d39267f..0000000000 --- a/frontend/appflowy_web_app/style-dictionary/tokens/base.json +++ /dev/null @@ -1,290 +0,0 @@ -{ - "Base": { - "Light": { - "neutral": { - "50": { - "value": "#f9fafd", - "type": "color" - }, - "100": { - "value": "#e5e5e5", - "type": "color" - }, - "200": { - "value": "#e2e4eb", - "type": "color" - }, - "300": { - "value": "#f2f2f2", - "type": "color" - }, - "400": { - "value": "#e0e0e0", - "type": "color" - }, - "500": { - "value": "#bdbdbd", - "type": "color" - }, - "600": { - "value": "#828282", - "type": "color" - }, - "700": { - "value": "#4f4f4f", - "type": "color" - }, - "800": { - "value": "#333333", - "type": "color" - }, - "900": { - "value": "#1f2329", - "type": "color" - }, - "1000": { - "value": "#000000", - "type": "color" - }, - "00": { - "value": "#ffffff", - "type": "color" - } - }, - "blue": { - "50": { - "value": "#f2fcff", - "type": "color" - }, - "100": { - "value": "#e0f8ff", - "type": "color" - }, - "200": { - "value": "#a6ecff", - "type": "color" - }, - "300": { - "value": "#52d1f4", - "type": "color" - }, - "400": { - "value": "#00bcf0", - "type": "color" - }, - "500": { - "value": "#05ade2", - "type": "color" - }, - "600": { - "value": "#009fd1", - "type": "color" - } - }, - "color": { - "deep": { - "red": { - "value": "#fb006d", - "type": "color" - }, - "yellow": { - "value": "#ffd667", - "type": "color" - }, - "green": { - "value": "#66cf80", - "type": "color" - }, - "blue": { - "value": "#00bcf0", - "type": "color" - } - }, - "light": { - "purple": { - "value": "#e8e0ff", - "type": "color" - }, - "pink": { - "value": "#ffe7ee", - "type": "color" - }, - "orange": { - "value": "#ffefe3", - "type": "color" - }, - "yellow": { - "value": "#fff2cd", - "type": "color" - }, - "lime": { - "value": "#f5ffdc", - "type": "color" - }, - "green": { - "value": "#ddffd6", - "type": "color" - }, - "aqua": { - "value": "#defff1", - "type": "color" - }, - "blue": { - "value": "#e1fbff", - "type": "color" - }, - "red": { - "value": "#ffdddd", - "type": "color" - } - } - } - }, - "black": { - "neutral": { - "100": { - "value": "#252F41", - "type": "color" - }, - "200": { - "value": "#313c51", - "type": "color" - }, - "300": { - "value": "#3c4557", - "type": "color" - }, - "400": { - "value": "#525A69", - "type": "color" - }, - "500": { - "value": "#59647a", - "type": "color" - }, - "600": { - "value": "#87A0BF", - "type": "color" - }, - "700": { - "value": "#99a6b8", - "type": "color" - }, - "800": { - "value": "#e2e9f2", - "type": "color" - }, - "900": { - "value": "#eff4fb", - "type": "color" - }, - "1000": { - "value": "#ffffff", - "type": "color" - }, - "N50": { - "value": "#232b38", - "type": "color" - }, - "N00": { - "value": "#1a202c", - "type": "color" - } - }, - "blue": { - "50": { - "value": "#232b38", - "type": "color" - }, - "100": { - "value": "#005174", - "type": "color" - }, - "200": { - "value": "#a6ecff", - "type": "color" - }, - "300": { - "value": "#52d1f4", - "type": "color" - }, - "400": { - "value": "#00bcf0", - "type": "color" - }, - "500": { - "value": "#05ade2", - "type": "color" - }, - "600": { - "value": "#009fd1", - "type": "color" - } - }, - "color": { - "deep": { - "red": { - "value": "#d32772", - "type": "color" - }, - "yellow": { - "value": "#e9b320", - "type": "color" - }, - "green": { - "value": "#3ba856", - "type": "color" - }, - "blue": { - "value": "#2e9dbb", - "type": "color" - } - }, - "light": { - "purple": { - "value": "#4D4078", - "type": "color" - }, - "blue": { - "value": "#2C3B58", - "type": "color" - }, - "green": { - "value": "#3C5133", - "type": "color" - }, - "yellow": { - "value": "#695E3E", - "type": "color" - }, - "pink": { - "value": "#5E3C5E", - "type": "color" - }, - "red": { - "value": "#56363F", - "type": "color" - }, - "aqua": { - "value": "#1B3849", - "type": "color" - }, - "lime": { - "value": "#394027", - "type": "color" - }, - "orange": { - "value": "#5E3C3C", - "type": "color" - } - } - } - }, - "else": { - "brand": { - "value": "#2c144b", - "type": "color" - } - } - } -} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tokens/dark.json b/frontend/appflowy_web_app/style-dictionary/tokens/dark.json deleted file mode 100644 index c67af7c9ec..0000000000 --- a/frontend/appflowy_web_app/style-dictionary/tokens/dark.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "text": { - "title": { - "value": "{Base.black.neutral.800}", - "type": "color" - }, - "caption": { - "value": "{Base.black.neutral.600}", - "type": "color" - }, - "placeholder": { - "value": "{Base.black.neutral.300}", - "type": "color" - }, - "link-default": { - "value": "{Base.black.blue.400}", - "type": "color" - }, - "link-hover": { - "value": "{Base.black.blue.300}", - "type": "color" - }, - "link-pressed": { - "value": "{Base.black.blue.600}", - "type": "color" - }, - "link-disabled": { - "value": "{Base.black.blue.100}", - "type": "color" - } - }, - "icon": { - "primary": { - "value": "{Base.black.neutral.800}", - "type": "color" - }, - "secondary": { - "value": "{Base.black.neutral.500}", - "type": "color" - }, - "disabled": { - "value": "{Base.black.neutral.400}", - "type": "color" - }, - "on-toolbar": { - "value": "white", - "type": "color" - } - }, - "line": { - "border": { - "value": "{Base.black.neutral.500}", - "type": "color" - }, - "divider": { - "value": "{Base.black.neutral.100}", - "type": "color" - }, - "on-toolbar": { - "value": "{Base.black.neutral.700}", - "type": "color" - } - }, - "fill": { - "default": { - "value": "{Base.black.blue.400}", - "type": "color" - }, - "hover": { - "value": "{Base.black.blue.100}", - "type": "color" - }, - "toolbar": { - "value": "#0F111C", - "type": "color" - }, - "selector": { - "value": "{Base.black.blue.50}", - "type": "color" - }, - "list": { - "active": { - "value": "{Base.black.neutral.300}", - "type": "color" - }, - "hover": { - "value": "{Base.black.blue.100}", - "type": "color" - } - } - }, - "content": { - "blue-400": { - "value": "{Base.black.blue.400}", - "type": "color" - }, - "blue-300": { - "value": "{Base.black.blue.300}", - "type": "color" - }, - "blue-600": { - "value": "{Base.black.blue.600}", - "type": "color" - }, - "blue-100": { - "value": "{Base.black.blue.100}", - "type": "color" - }, - "on-fill": { - "value": "{Base.black.neutral.N00}", - "type": "color" - }, - "on-tag": { - "value": "{Base.black.neutral.700}", - "type": "color" - }, - "blue-50": { - "value": "{Base.black.blue.50}", - "type": "color" - } - }, - "bg": { - "body": { - "value": "{Base.black.neutral.N00}", - "type": "color" - }, - "base": { - "value": "{Base.black.blue.50}", - "type": "color" - }, - "mask": { - "value": "rgba(0,0,0,0.7)", - "type": "color" - }, - "tips": { - "value": "{Base.black.blue.100}", - "type": "color" - }, - "brand": { - "value": "{Base.else.brand}", - "type": "color" - } - }, - "function": { - "error": { - "value": "{Base.black.color.deep.red}", - "type": "color" - }, - "warning": { - "value": "{Base.black.color.deep.yellow}", - "type": "color" - }, - "success": { - "value": "#3ba856", - "type": "color" - }, - "info": { - "value": "#2e9dbb", - "type": "color" - } - }, - "tint": { - "red": { - "value": "{Base.black.color.light.red}", - "type": "color" - }, - "green": { - "value": "{Base.black.color.light.green}", - "type": "color" - }, - "purple": { - "value": "{Base.black.color.light.purple}", - "type": "color" - }, - "blue": { - "value": "{Base.black.color.light.blue}", - "type": "color" - }, - "yellow": { - "value": "{Base.black.color.light.yellow}", - "type": "color" - }, - "pink": { - "value": "{Base.black.color.light.pink}", - "type": "color" - }, - "lime": { - "value": "{Base.black.color.light.lime}", - "type": "color" - }, - "aqua": { - "value": "{Base.black.color.light.aqua}", - "type": "color" - }, - "orange": { - "value": "{Base.black.color.light.orange}", - "type": "color" - } - }, - "shadow": { - "value": { - "x": "0", - "y": "0", - "blur": "25", - "spread": "0", - "color": "rgba(0,0,0,0.3)", - "type": "innerShadow" - }, - "type": "boxShadow" - }, - "scrollbar": { - "track": { - "value": "{Base.black.neutral.100}", - "type": "color" - }, - "thumb": { - "value": "{Base.black.neutral.300}", - "type": "color" - } - } -} \ No newline at end of file diff --git a/frontend/appflowy_web_app/style-dictionary/tokens/light.json b/frontend/appflowy_web_app/style-dictionary/tokens/light.json deleted file mode 100644 index 173f3d35aa..0000000000 --- a/frontend/appflowy_web_app/style-dictionary/tokens/light.json +++ /dev/null @@ -1,233 +0,0 @@ -{ - "text": { - "title": { - "value": "{Base.Light.neutral.800}", - "type": "color" - }, - "caption": { - "value": "{Base.Light.neutral.600}", - "type": "color" - }, - "placeholder": { - "value": "{Base.Light.neutral.500}", - "type": "color" - }, - "disabled": { - "value": "{Base.Light.neutral.400}", - "type": "color" - }, - "link-default": { - "value": "{Base.Light.blue.400}", - "type": "color" - }, - "link-hover": { - "value": "{Base.Light.blue.300}", - "type": "color" - }, - "link-pressed": { - "value": "{Base.Light.blue.600}", - "type": "color" - }, - "link-disabled": { - "value": "{Base.Light.blue.100}", - "type": "color" - } - }, - "icon": { - "primary": { - "value": "{Base.Light.neutral.800}", - "type": "color" - }, - "secondary": { - "value": "{Base.black.neutral.500}", - "type": "color" - }, - "disabled": { - "value": "{Base.Light.neutral.400}", - "type": "color" - }, - "on-toolbar": { - "value": "{Base.Light.neutral.00}", - "type": "color" - } - }, - "line": { - "border": { - "value": "{Base.Light.neutral.500}", - "type": "color" - }, - "divider": { - "value": "{Base.Light.neutral.100}", - "type": "color" - }, - "on-toolbar": { - "value": "{Base.Light.neutral.700}", - "type": "color" - } - }, - "fill": { - "toolbar": { - "value": "{Base.Light.neutral.800}", - "type": "color" - }, - "default": { - "value": "{Base.Light.blue.400}", - "type": "color" - }, - "hover": { - "value": "{Base.Light.blue.300}", - "type": "color" - }, - "pressed": { - "value": "{Base.Light.blue.600}", - "type": "color" - }, - "active": { - "value": "{Base.Light.blue.100}", - "type": "color" - }, - "list": { - "hover": { - "value": "{Base.Light.blue.100}", - "type": "color" - }, - "active": { - "value": "{Base.Light.neutral.100}", - "type": "color" - } - } - }, - "content": { - "blue-400": { - "value": "{Base.Light.blue.400}", - "type": "color" - }, - "blue-300": { - "value": "{Base.Light.blue.300}", - "type": "color" - }, - "blue-600": { - "value": "{Base.Light.blue.600}", - "type": "color" - }, - "blue-100": { - "value": "{Base.Light.blue.100}", - "type": "color" - }, - "blue-50": { - "value": "{Base.Light.blue.50}", - "type": "color" - }, - "on-fill-hover": { - "value": "{Base.Light.blue.400}", - "type": "color" - }, - "on-fill": { - "value": "{Base.Light.neutral.00}", - "type": "color" - }, - "on-tag": { - "value": "{Base.Light.neutral.700}", - "type": "color" - } - }, - "bg": { - "body": { - "value": "{Base.Light.neutral.00}", - "type": "color" - }, - "base": { - "value": "{Base.Light.neutral.50}", - "type": "color" - }, - "mask": { - "value": "rgba(0,0,0,0.55)", - "type": "color" - }, - "tips": { - "value": "{Base.Light.blue.100}", - "type": "color" - }, - "brand": { - "value": "{Base.else.brand}", - "type": "color" - } - }, - "function": { - "error": { - "value": "{Base.Light.color.deep.red}", - "type": "color" - }, - "waring": { - "value": "{Base.Light.color.deep.yellow}", - "type": "color" - }, - "success": { - "value": "{Base.Light.color.deep.green}", - "type": "color" - }, - "info": { - "value": "{Base.Light.color.deep.blue}", - "type": "color" - } - }, - "tint": { - "purple": { - "value": "{Base.Light.color.light.purple}", - "type": "color" - }, - "pink": { - "value": "{Base.Light.color.light.pink}", - "type": "color" - }, - "red": { - "value": "{Base.Light.color.light.red}", - "type": "color" - }, - "lime": { - "value": "{Base.Light.color.light.lime}", - "type": "color" - }, - "green": { - "value": "{Base.Light.color.light.green}", - "type": "color" - }, - "aqua": { - "value": "{Base.Light.color.light.aqua}", - "type": "color" - }, - "blue": { - "value": "{Base.Light.color.light.blue}", - "type": "color" - }, - "orange": { - "value": "{Base.Light.color.light.orange}", - "type": "color" - }, - "yellow": { - "value": "{Base.Light.color.light.yellow}", - "type": "color" - } - }, - "shadow": { - "value": { - "x": "0", - "y": "0", - "blur": "10", - "spread": "0", - "color": "rgba(0,0,0,0.1)", - "type": "dropShadow" - }, - "type": "boxShadow" - }, - "scrollbar": { - "thumb": { - "value": "{Base.Light.neutral.500}", - "type": "color" - }, - "track": { - "value": "{Base.Light.neutral.100}", - "type": "color" - } - } -} \ No newline at end of file diff --git a/frontend/appflowy_web_app/tailwind.config.cjs b/frontend/appflowy_web_app/tailwind.config.cjs index 06390d938f..8589a0f4b6 100644 --- a/frontend/appflowy_web_app/tailwind.config.cjs +++ b/frontend/appflowy_web_app/tailwind.config.cjs @@ -1,5 +1,5 @@ -const colors = require('./style-dictionary/tailwind/colors.cjs'); -const boxShadow = require('./style-dictionary/tailwind/box-shadow.cjs'); +const colors = require('./tailwind/colors.cjs'); +const boxShadow = require('./tailwind/box-shadow.cjs'); /** @type {import('tailwindcss').Config} */ module.exports = { diff --git a/frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs b/frontend/appflowy_web_app/tailwind/box-shadow.cjs similarity index 69% rename from frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs rename to frontend/appflowy_web_app/tailwind/box-shadow.cjs index 9de67fc1be..d72c255227 100644 --- a/frontend/appflowy_web_app/style-dictionary/tailwind/box-shadow.cjs +++ b/frontend/appflowy_web_app/tailwind/box-shadow.cjs @@ -1,9 +1,11 @@ + /** * Do not edit directly -* Generated on Thu, 09 May 2024 03:26:45 GMT +* Generated on Mon, 27 May 2024 06:26:20 GMT * Generated from $pnpm css:variables */ + module.exports = { "md": "var(--shadow)" -} \ No newline at end of file +}; diff --git a/frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs b/frontend/appflowy_web_app/tailwind/colors.cjs similarity index 73% rename from frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs rename to frontend/appflowy_web_app/tailwind/colors.cjs index 63e679a90a..27a3b07c30 100644 --- a/frontend/appflowy_web_app/style-dictionary/tailwind/colors.cjs +++ b/frontend/appflowy_web_app/tailwind/colors.cjs @@ -1,14 +1,17 @@ + /** * Do not edit directly -* Generated on Thu, 09 May 2024 03:26:45 GMT +* Generated on Mon, 27 May 2024 06:26:20 GMT * Generated from $pnpm css:variables */ + module.exports = { "text": { "title": "var(--text-title)", "caption": "var(--text-caption)", "placeholder": "var(--text-placeholder)", + "disabled": "var(--text-disabled)", "link-default": "var(--text-link-default)", "link-hover": "var(--text-link-hover)", "link-pressed": "var(--text-link-pressed)", @@ -26,50 +29,49 @@ module.exports = { "on-toolbar": "var(--line-on-toolbar)" }, "fill": { + "toolbar": "var(--fill-toolbar)", "default": "var(--fill-default)", "hover": "var(--fill-hover)", - "toolbar": "var(--fill-toolbar)", - "selector": "var(--fill-selector)", - "list": { - "active": "var(--fill-list-active)", - "hover": "var(--fill-list-hover)" - } + "pressed": "var(--fill-pressed)", + "active": "var(--fill-active)", + "list-hover": "var(--fill-list-hover)", + "list-active": "var(--fill-list-active)" }, "content": { "blue-400": "var(--content-blue-400)", "blue-300": "var(--content-blue-300)", "blue-600": "var(--content-blue-600)", "blue-100": "var(--content-blue-100)", + "blue-50": "var(--content-blue-50)", + "on-fill-hover": "var(--content-on-fill-hover)", "on-fill": "var(--content-on-fill)", - "on-tag": "var(--content-on-tag)", - "blue-50": "var(--content-blue-50)" + "on-tag": "var(--content-on-tag)" }, "bg": { "body": "var(--bg-body)", "base": "var(--bg-base)", - "mask": "var(--bg-mask)", "tips": "var(--bg-tips)", "brand": "var(--bg-brand)" }, "function": { "error": "var(--function-error)", - "warning": "var(--function-warning)", + "waring": "var(--function-waring)", "success": "var(--function-success)", "info": "var(--function-info)" }, "tint": { - "red": "var(--tint-red)", - "green": "var(--tint-green)", "purple": "var(--tint-purple)", - "blue": "var(--tint-blue)", - "yellow": "var(--tint-yellow)", "pink": "var(--tint-pink)", + "red": "var(--tint-red)", "lime": "var(--tint-lime)", + "green": "var(--tint-green)", "aqua": "var(--tint-aqua)", - "orange": "var(--tint-orange)" + "blue": "var(--tint-blue)", + "orange": "var(--tint-orange)", + "yellow": "var(--tint-yellow)" }, "scrollbar": { - "track": "var(--scrollbar-track)", - "thumb": "var(--scrollbar-thumb)" + "thumb": "var(--scrollbar-thumb)", + "track": "var(--scrollbar-track)" } -} \ No newline at end of file +}; diff --git a/frontend/appflowy_web_app/tsconfig.json b/frontend/appflowy_web_app/tsconfig.json index 05dcd8d587..875f06f3e5 100644 --- a/frontend/appflowy_web_app/tsconfig.json +++ b/frontend/appflowy_web_app/tsconfig.json @@ -50,7 +50,9 @@ "cypress" ], "exclude": [ - "node_modules" + "node_modules", + "dist", + "coverage" ], "references": [ { diff --git a/frontend/appflowy_web_app/tsconfig.node.json b/frontend/appflowy_web_app/tsconfig.node.json index b8afcc8fa2..20f2adefab 100644 --- a/frontend/appflowy_web_app/tsconfig.node.json +++ b/frontend/appflowy_web_app/tsconfig.node.json @@ -7,5 +7,10 @@ }, "include": [ "vite.config.ts" + ], + "exclude": [ + "node_modules", + "dist", + "coverage" ] } diff --git a/frontend/appflowy_web_app/tsconfig.web.json b/frontend/appflowy_web_app/tsconfig.web.json index 5e0cdd176d..90f704a38f 100644 --- a/frontend/appflowy_web_app/tsconfig.web.json +++ b/frontend/appflowy_web_app/tsconfig.web.json @@ -3,7 +3,9 @@ "exclude": [ "node_modules", "src/application/services/tauri-services", - "**/*.cy.tsx" + "**/*.cy.tsx", + "dist", + "coverage" ], "references": [ { diff --git a/frontend/appflowy_web_app/vite.config.ts b/frontend/appflowy_web_app/vite.config.ts index 87a5e284bf..aeadc4e8fa 100644 --- a/frontend/appflowy_web_app/vite.config.ts +++ b/frontend/appflowy_web_app/vite.config.ts @@ -6,6 +6,7 @@ import { visualizer } from 'rollup-plugin-visualizer'; import usePluginImport from 'vite-plugin-importer'; import { totalBundleSize } from 'vite-plugin-total-bundle-size'; import path from 'path'; +import istanbul from 'vite-plugin-istanbul'; const resourcesPath = path.resolve(__dirname, '../resources'); const isDev = process.env.NODE_ENV === 'development'; @@ -40,6 +41,10 @@ export default defineConfig({ }, }, }), + istanbul({ + cypress: true, + requireEnv: false, + }), usePluginImport({ libraryName: '@mui/icons-material', libraryDirectory: '', @@ -66,13 +71,13 @@ export default defineConfig({ port: !!process.env.TAURI_PLATFORM ? 5173 : process.env.PORT ? parseInt(process.env.PORT) : 3000, strictPort: true, watch: { - ignored: ['**/__tests__/**'], + ignored: ['**/__tests__/**', '**/cypress/**', 'node_modules', '**/*.cy.tsx', '**/*.cy.ts', 'cypress'], }, cors: false, }, envPrefix: ['AF', 'TAURI_'], esbuild: { - drop: isDev ? [] : ['console', 'debugger'], + pure: !isDev ? ['console.log', 'console.debug', 'console.info', 'console.trace'] : [], }, build: !!process.env.TAURI_PLATFORM ? { @@ -125,6 +130,6 @@ export default defineConfig({ }, optimizeDeps: { - include: ['@mui/material/Tooltip'], + include: ['react', 'react-dom', '@mui/icons-material/ErrorOutline', '@mui/icons-material/CheckCircleOutline'], }, }); diff --git a/frontend/resources/flowy_icons/16x/board.svg b/frontend/resources/flowy_icons/16x/board.svg index 550d045178..bde3149c31 100644 --- a/frontend/resources/flowy_icons/16x/board.svg +++ b/frontend/resources/flowy_icons/16x/board.svg @@ -1,6 +1,4 @@ -<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12.8 2H3.2C2.53726 2 2 2.55964 2 3.25V5.75C2 6.44036 2.53726 7 3.2 7H12.8C13.4627 7 14 6.44036 14 5.75V3.25C14 2.55964 13.4627 2 12.8 2Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> -<path d="M12.8 9H3.2C2.53726 9 2 9.55964 2 10.25V12.75C2 13.4404 2.53726 14 3.2 14H12.8C13.4627 14 14 13.4404 14 12.75V10.25C14 9.55964 13.4627 9 12.8 9Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> -<circle cx="4.5" cy="4.5" r="0.5" fill="#333333"/> -<circle cx="4.5" cy="11.5" r="0.5" fill="#333333"/> +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M7.90313 14.7769V3.22312C7.90313 2.12625 7.43513 1.6875 6.27244 1.6875H3.31819C2.1555 1.6875 1.6875 2.12625 1.6875 3.22312V14.7769C1.6875 15.8737 2.1555 16.3125 3.31819 16.3125H6.27244C7.43513 16.3125 7.90313 15.8737 7.90313 14.7769Z" stroke="#171717" stroke-opacity="0.7" stroke-width="1.09687" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M16.3133 9.65812V3.22312C16.3133 2.12625 15.8453 1.6875 14.6826 1.6875H11.7283C10.5657 1.6875 10.0977 2.12625 10.0977 3.22312V9.65812C10.0977 10.755 10.5657 11.1937 11.7283 11.1937H14.6826C15.8453 11.1937 16.3133 10.755 16.3133 9.65812Z" stroke="#171717" stroke-opacity="0.7" stroke-width="1.09687" stroke-linecap="round" stroke-linejoin="round"/> </svg> diff --git a/frontend/resources/flowy_icons/16x/calendar.svg b/frontend/resources/flowy_icons/16x/calendar.svg new file mode 100644 index 0000000000..34f184b4d2 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/calendar.svg @@ -0,0 +1,6 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M5.83008 1.125V3.5" stroke="#171717" stroke-opacity="0.7" stroke-width="1.125" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M12.1699 1.125V3.5" stroke="#171717" stroke-opacity="0.7" stroke-width="1.125" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M2.26758 6.73877H15.7259" stroke="#171717" stroke-opacity="0.7" stroke-width="1.125" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<rect x="2.0625" y="2.4375" width="13.875" height="13.875" rx="2.4375" stroke="#171717" stroke-opacity="0.7" stroke-width="1.125"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/chat_ai_page.svg b/frontend/resources/flowy_icons/16x/chat_ai_page.svg new file mode 100644 index 0000000000..e39815f94f --- /dev/null +++ b/frontend/resources/flowy_icons/16x/chat_ai_page.svg @@ -0,0 +1,4 @@ +<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M17 3.33782C15.5291 2.48697 13.8214 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22C17.5228 22 22 17.5228 22 12C22 10.1786 21.513 8.47087 20.6622 7" stroke="#171717" stroke-opacity="0.7" stroke-width="1.125" stroke-linecap="round"/> + <path d="M8 12H8.009M11.991 12H12M15.991 12H16" stroke="#171717" stroke-opacity="0.7" stroke-width="1.05" stroke-linecap="round" stroke-linejoin="round"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/document.svg b/frontend/resources/flowy_icons/16x/document.svg index abb59d5c14..d73738329c 100644 --- a/frontend/resources/flowy_icons/16x/document.svg +++ b/frontend/resources/flowy_icons/16x/document.svg @@ -1,3 +1,4 @@ -<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 2C3.67157 2 3 2.67157 3 3.5V12.5C3 13.3284 3.67157 14 4.5 14H11.5C12.3284 14 13 13.3284 13 12.5V7.16667C13 6.62574 12.8246 6.09941 12.5 5.66667L10.5 3C10.0279 2.37049 9.28689 2 8.5 2H4.5ZM4 3.5C4 3.22386 4.22386 3 4.5 3H8.5V6C8.5 6.82843 9.17157 7.5 10 7.5H12V12.5C12 12.7761 11.7761 13 11.5 13H4.5C4.22386 13 4 12.7761 4 12.5V3.5ZM11.8437 6.5C11.8032 6.41843 11.7552 6.34029 11.7 6.26667L9.7 3.6C9.64012 3.52016 9.57303 3.44726 9.5 3.38194V6C9.5 6.27614 9.72386 6.5 10 6.5H11.8437Z" fill="#333333"/> +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M3.11523 4.5C3.11523 3.15381 4.20654 2.0625 5.55273 2.0625H9.96357C10.1512 2.0625 10.3292 2.14513 10.4504 2.28838L12.3569 4.5432L14.7021 7.6626C14.8242 7.82503 14.8902 8.02274 14.8902 8.22596V13.5C14.8902 14.8462 13.7989 15.9375 12.4527 15.9375H5.55274C4.20654 15.9375 3.11523 14.8462 3.11523 13.5V4.5Z" stroke="#171717" stroke-opacity="0.7" stroke-width="1.125"/> +<path d="M10.0527 2.25V6.525C10.0527 7.35343 10.7243 8.025 11.5527 8.025H14.9277" stroke="#171717" stroke-opacity="0.7" stroke-width="1.05"/> </svg> diff --git a/frontend/resources/flowy_icons/16x/dot.svg b/frontend/resources/flowy_icons/16x/dot.svg new file mode 100644 index 0000000000..70d26f3988 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/dot.svg @@ -0,0 +1,3 @@ +<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg"> +<circle opacity="0.4" cx="4" cy="4" r="1" fill="#171717"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/flowy_ai_chat_logo.svg b/frontend/resources/flowy_icons/16x/flowy_ai_chat_logo.svg new file mode 100644 index 0000000000..a719222956 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/flowy_ai_chat_logo.svg @@ -0,0 +1,13 @@ +<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_214_2)"> +<path d="M15.9881 9.7645C15.9849 9.37128 15.8725 8.98667 15.6633 8.65368C15.5916 8.5528 15.5001 8.46754 15.3945 8.40307C15.2888 8.33861 15.1711 8.29629 15.0486 8.27868C13.9636 8.09182 12.0538 9.31863 10.1517 10.6717L9.8811 10.8637C9.80636 10.9166 9.73033 10.9733 9.65816 11.0338C8.45713 12.0209 7.66332 13.8019 8.47517 14.9578C8.68981 15.2616 8.97311 15.5106 9.30204 15.6843C9.63097 15.8581 9.99626 15.9518 10.3682 15.9578C10.3943 15.9671 10.4217 15.9719 10.4494 15.972H14.9481C15.0858 15.9756 15.2227 15.9516 15.3509 15.9014C15.4792 15.8512 15.596 15.7759 15.6946 15.6798C15.7933 15.5837 15.8716 15.4688 15.9251 15.3419C15.9786 15.215 16.0061 15.0787 16.0061 14.9411V9.84053C16.0035 9.8145 15.9974 9.78893 15.9881 9.7645ZM14.9481 15.414H12.4829C12.8152 15.241 13.1355 15.046 13.4417 14.8302C13.4816 14.8006 13.5216 14.7722 13.5628 14.74C14.3846 14.0944 15.0307 13.2524 15.4417 12.2916V14.9346C15.4419 14.9988 15.4291 15.0624 15.4042 15.1216C15.3793 15.1808 15.3427 15.2344 15.2967 15.2791C15.2506 15.3238 15.196 15.3588 15.1361 15.382C15.0762 15.4052 15.0123 15.4161 14.9481 15.414ZM10.4739 11.1266C11.4649 10.4217 13.7226 8.81734 14.8025 8.81734C14.853 8.81711 14.9034 8.82099 14.9533 8.82894C15.0042 8.83319 15.0536 8.84841 15.0981 8.87355C15.1425 8.89868 15.1811 8.93314 15.211 8.97456C15.8759 9.92043 15.1633 12.8496 13.2303 14.2954C13.1955 14.3225 13.162 14.347 13.1272 14.3702C11.2948 15.6588 9.72775 15.7581 8.93909 14.6279C8.32955 13.7619 9.0061 12.2877 10.0203 11.4539C10.0821 11.4024 10.1491 11.3547 10.2084 11.3109L10.4739 11.1266Z" fill="black"/> +<path d="M5.52315 0.172868C4.63269 0.172868 3.63656 0.559466 2.55924 1.31591C2.51671 1.34555 2.47547 1.37519 2.44197 1.40225C0.359495 2.95508 -0.537412 6.25276 0.331144 7.48859C0.40288 7.58938 0.494582 7.67435 0.60055 7.73819C0.706519 7.80204 0.824488 7.84341 0.947124 7.85972C1.02378 7.87243 1.10139 7.87847 1.17908 7.87776C2.29248 7.87776 4.07341 6.7257 5.8479 5.4641L6.11465 5.2824C6.18939 5.22957 6.26284 5.17416 6.3363 5.11359C7.53991 4.12261 8.33372 2.34168 7.52058 1.18447C7.29845 0.862617 6.99932 0.601456 6.65045 0.42477C6.30158 0.248084 5.91405 0.161487 5.52315 0.172868ZM5.98192 4.68318C5.92006 4.73472 5.85305 4.78112 5.79377 4.82622L5.52444 5.01694C4.48449 5.75663 2.04506 7.49246 1.0412 7.3172C0.990214 7.3132 0.940726 7.29809 0.896203 7.27293C0.85168 7.24778 0.8132 7.21318 0.783464 7.17158C0.128825 6.22184 0.836299 3.29529 2.77315 1.84426L2.87496 1.76952C3.84145 1.09039 4.75511 0.730858 5.51671 0.730858C5.81859 0.719971 6.11837 0.785059 6.38856 0.920152C6.65874 1.05524 6.89068 1.25602 7.0631 1.50405C7.67264 2.37132 6.99609 3.84555 5.98063 4.67673L5.98192 4.68318Z" fill="black"/> +<path d="M10.897 6.1209C10.9317 6.16858 10.9665 6.21626 11.0026 6.26265C11.6341 7.07451 12.8132 7.86059 13.8969 7.86059C14.2875 7.86618 14.6701 7.74948 14.991 7.52683C16.0503 6.78198 16.598 5.12348 14.9601 2.7008C14.9279 2.65441 14.8957 2.60673 14.8622 2.56033C14.1637 1.56291 13.0155 0.740747 11.6985 0.301314C10.4601 -0.112346 9.30674 -0.0994591 8.6869 0.336108C8.58553 0.407326 8.49993 0.498659 8.43541 0.604414C8.37089 0.71017 8.32885 0.828081 8.3119 0.950799C8.12504 2.03585 9.35056 3.94564 10.7037 5.84771L10.897 6.1209ZM8.86216 1.04616C8.86616 0.995178 8.88127 0.94569 8.90642 0.901167C8.93158 0.856644 8.96617 0.818164 9.00778 0.788428C9.23329 0.629922 9.57865 0.551314 9.9936 0.551314C10.5146 0.563122 11.0305 0.657508 11.522 0.830953C12.723 1.23302 13.7732 1.97915 14.406 2.87992C14.4382 2.92503 14.4678 2.96884 14.4975 3.00879C15.6959 4.7807 15.7604 6.29745 14.6701 7.0642C13.7823 7.6892 12.2565 6.96111 11.4485 5.91472C11.4163 5.87477 11.3866 5.83353 11.3583 5.79487C11.3029 5.71369 11.2372 5.62219 11.1637 5.52039C10.4189 4.4843 8.68948 2.05131 8.86216 1.04616Z" fill="black"/> +<path d="M5.09906 10.0211C5.06427 9.9734 5.02947 9.92572 4.99339 9.87933C4.13514 8.77752 2.27174 7.73113 1.00499 8.61773C-0.0555802 9.36257 -0.603261 11.0237 1.04236 13.4515L1.05138 13.4631C1.07844 13.503 1.1055 13.5443 1.13385 13.5829C2.27432 15.2066 4.42509 16.1487 5.98308 16.1487C6.51658 16.1487 6.9805 16.0378 7.30911 15.8072C7.41048 15.7359 7.49608 15.6446 7.5606 15.5389C7.62512 15.4331 7.66716 15.3152 7.68411 15.1925C7.86968 14.1074 6.64416 12.1963 5.29107 10.2956L5.09906 10.0211ZM7.13385 15.0971C7.12985 15.1481 7.11474 15.1976 7.08959 15.2421C7.06443 15.2866 7.02984 15.3251 6.98823 15.3548C6.02045 16.034 2.99339 15.2582 1.58875 13.2659L1.50628 13.1461L1.49854 13.1345C0.298801 11.3561 0.234368 9.84067 1.32586 9.07391C2.21504 8.44891 3.73952 9.17701 4.54751 10.2221C4.57973 10.2621 4.60937 10.3033 4.63772 10.3432L4.83102 10.6152C5.57457 11.6551 7.30653 14.0907 7.13385 15.0971Z" fill="black"/> +</g> +<defs> +<clipPath id="clip0_214_2"> +<rect width="16" height="16.1495" fill="white"/> +</clipPath> +</defs> +</svg> \ No newline at end of file diff --git a/frontend/resources/flowy_icons/16x/grid.svg b/frontend/resources/flowy_icons/16x/grid.svg index 8164b24e6a..e1b7c1f148 100644 --- a/frontend/resources/flowy_icons/16x/grid.svg +++ b/frontend/resources/flowy_icons/16x/grid.svg @@ -1,6 +1,6 @@ -<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M6 2H3C2.44772 2 2 2.44772 2 3V6C2 6.55228 2.44772 7 3 7H6C6.55228 7 7 6.55228 7 6V3C7 2.44772 6.55228 2 6 2Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> -<path d="M13 2H10C9.44772 2 9 2.44772 9 3V6C9 6.55228 9.44772 7 10 7H13C13.5523 7 14 6.55228 14 6V3C14 2.44772 13.5523 2 13 2Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> -<path d="M13 9H10C9.44772 9 9 9.44772 9 10V13C9 13.5523 9.44772 14 10 14H13C13.5523 14 14 13.5523 14 13V10C14 9.44772 13.5523 9 13 9Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> -<path d="M6 9H3C2.44772 9 2 9.44772 2 10V13C2 13.5523 2.44772 14 3 14H6C6.55228 14 7 13.5523 7 13V10C7 9.44772 6.55228 9 6 9Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect x="2.03571" y="2.03571" width="13.9286" height="13.9286" rx="2.32143" stroke="#171717" stroke-opacity="0.7" stroke-width="1.07143"/> +<path d="M6.64453 2.03564V15.9642" stroke="#171717" stroke-opacity="0.7" stroke-width="1.07143" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M2.57227 6.50146H15.4294" stroke="#171717" stroke-opacity="0.7" stroke-width="1.07143" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M2.57227 11.501H15.4294" stroke="#171717" stroke-opacity="0.7" stroke-width="1.07143" stroke-linecap="round" stroke-linejoin="round"/> </svg> diff --git a/frontend/resources/flowy_icons/16x/m_add_block_video.svg b/frontend/resources/flowy_icons/16x/m_add_block_video.svg new file mode 100644 index 0000000000..5bd19d0a3e --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_add_block_video.svg @@ -0,0 +1,2 @@ + +<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="m384-312 264-168-264-168v336ZM168-192q-29.7 0-50.85-21.16Q96-234.32 96-264.04v-432.24Q96-726 117.15-747T168-768h624q29.7 0 50.85 21.16Q864-725.68 864-695.96v432.24Q864-234 842.85-213T792-192H168Zm0-72h624v-432H168v432Zm0 0v-432 432Z"/></svg> \ No newline at end of file diff --git a/frontend/resources/flowy_icons/16x/m_collapse.svg b/frontend/resources/flowy_icons/16x/m_collapse.svg new file mode 100644 index 0000000000..bf88470d69 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_collapse.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M10.9667 7.59993C11.2333 7.79993 11.2333 8.19993 10.9667 8.39993L6.3 11.8999C5.97038 12.1471 5.5 11.912 5.5 11.4999L5.5 4.49993C5.5 4.08791 5.97038 3.85272 6.3 4.09993L10.9667 7.59993Z" fill="#8F959E"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/m_expand.svg b/frontend/resources/flowy_icons/16x/m_expand.svg new file mode 100644 index 0000000000..48c7bc5ebd --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_expand.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8.39909 10.9667C8.19909 11.2333 7.79909 11.2333 7.59909 10.9667L4.09909 6.3C3.85188 5.97038 4.08707 5.5 4.49909 5.5L11.4991 5.5C11.9111 5.5 12.1463 5.97038 11.8991 6.3L8.39909 10.9667Z" fill="#8F959E"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/m_space_add.svg b/frontend/resources/flowy_icons/16x/m_space_add.svg new file mode 100644 index 0000000000..dcab9d1eb5 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_space_add.svg @@ -0,0 +1,6 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g opacity="0.5"> +<rect x="2.25" y="8.3252" width="13.5" height="1.35" rx="0.675" fill="#171717"/> +<rect x="8.32422" y="15.75" width="13.5" height="1.35" rx="0.675" transform="rotate(-90 8.32422 15.75)" fill="#171717"/> +</g> +</svg> diff --git a/frontend/resources/flowy_icons/16x/m_space_more.svg b/frontend/resources/flowy_icons/16x/m_space_more.svg new file mode 100644 index 0000000000..ea557e960c --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_space_more.svg @@ -0,0 +1,7 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g opacity="0.5"> +<path d="M4.76211 9.0002C4.76211 9.68365 4.20806 10.2377 3.52461 10.2377C2.84116 10.2377 2.28711 9.68365 2.28711 9.0002C2.28711 8.31674 2.84116 7.7627 3.52461 7.7627C4.20806 7.7627 4.76211 8.31674 4.76211 9.0002Z" fill="#171717"/> +<path d="M10.2367 9.0002C10.2367 9.68365 9.68267 10.2377 8.99922 10.2377C8.31577 10.2377 7.76172 9.68365 7.76172 9.0002C7.76172 8.31674 8.31577 7.7627 8.99922 7.7627C9.68267 7.7627 10.2367 8.31674 10.2367 9.0002Z" fill="#171717"/> +<path d="M15.7113 9.0002C15.7113 9.68365 15.1573 10.2377 14.4738 10.2377C13.7904 10.2377 13.2363 9.68365 13.2363 9.0002C13.2363 8.31674 13.7904 7.7627 14.4738 7.7627C15.1573 7.7627 15.7113 8.31674 15.7113 9.0002Z" fill="#171717"/> +</g> +</svg> diff --git a/frontend/resources/flowy_icons/16x/m_spaces_expand.svg b/frontend/resources/flowy_icons/16x/m_spaces_expand.svg new file mode 100644 index 0000000000..af15050d18 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/m_spaces_expand.svg @@ -0,0 +1,8 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<mask id="path-2-outside-1_136_3860" maskUnits="userSpaceOnUse" x="4" y="7" width="10" height="6" fill="black"> +<rect fill="white" x="4" y="7" width="10" height="6"/> +<path d="M5.14645 7.64645C5.34171 7.45118 5.65829 7.45118 5.85355 7.64645L9 10.7929L12.1464 7.64645C12.3417 7.45118 12.6583 7.45118 12.8536 7.64645C13.0488 7.84171 13.0488 8.15829 12.8536 8.35355L9.35355 11.8536C9.25979 11.9473 9.13261 12 9 12C8.86739 12 8.74021 11.9473 8.64645 11.8536L5.14645 8.35355C4.95118 8.15829 4.95118 7.84171 5.14645 7.64645Z"/> +</mask> +<path d="M5.14645 7.64645C5.34171 7.45118 5.65829 7.45118 5.85355 7.64645L9 10.7929L12.1464 7.64645C12.3417 7.45118 12.6583 7.45118 12.8536 7.64645C13.0488 7.84171 13.0488 8.15829 12.8536 8.35355L9.35355 11.8536C9.25979 11.9473 9.13261 12 9 12C8.86739 12 8.74021 11.9473 8.64645 11.8536L5.14645 8.35355C4.95118 8.15829 4.95118 7.84171 5.14645 7.64645Z" fill="#171717"/> +<path d="M5.85355 7.64645L5.78284 7.71716H5.78284L5.85355 7.64645ZM5.14645 7.64645L5.21716 7.71716L5.14645 7.64645ZM9 10.7929L9.07071 10.8636C9.05196 10.8824 9.02652 10.8929 9 10.8929C8.97348 10.8929 8.94804 10.8824 8.92929 10.8636L9 10.7929ZM12.1464 7.64645L12.2172 7.71716L12.1464 7.64645ZM12.8536 7.64645L12.7828 7.71716L12.8536 7.64645ZM12.8536 8.35355L12.7828 8.28284L12.8536 8.35355ZM9.35355 11.8536L9.42426 11.9243V11.9243L9.35355 11.8536ZM8.64645 11.8536L8.71716 11.7828V11.7828L8.64645 11.8536ZM5.14645 8.35355L5.07574 8.42426H5.07574L5.14645 8.35355ZM5.78284 7.71716C5.62663 7.56095 5.37337 7.56095 5.21716 7.71716L5.07574 7.57574C5.31005 7.34142 5.68995 7.34142 5.92426 7.57574L5.78284 7.71716ZM8.92929 10.8636L5.78284 7.71716L5.92426 7.57574L9.07071 10.7222L8.92929 10.8636ZM12.2172 7.71716L9.07071 10.8636L8.92929 10.7222L12.0757 7.57574L12.2172 7.71716ZM12.7828 7.71716C12.6266 7.56095 12.3734 7.56095 12.2172 7.71716L12.0757 7.57574C12.3101 7.34142 12.6899 7.34142 12.9243 7.57574L12.7828 7.71716ZM12.7828 8.28284C12.9391 8.12663 12.9391 7.87337 12.7828 7.71716L12.9243 7.57574C13.1586 7.81005 13.1586 8.18995 12.9243 8.42426L12.7828 8.28284ZM9.28284 11.7828L12.7828 8.28284L12.9243 8.42426L9.42426 11.9243L9.28284 11.7828ZM9 11.9C9.10609 11.9 9.20783 11.8579 9.28284 11.7828L9.42426 11.9243C9.31174 12.0368 9.15913 12.1 9 12.1V11.9ZM8.71716 11.7828C8.79217 11.8579 8.89391 11.9 9 11.9V12.1C8.84087 12.1 8.68826 12.0368 8.57574 11.9243L8.71716 11.7828ZM5.21716 8.28284L8.71716 11.7828L8.57574 11.9243L5.07574 8.42426L5.21716 8.28284ZM5.21716 7.71716C5.06095 7.87337 5.06095 8.12663 5.21716 8.28284L5.07574 8.42426C4.84142 8.18995 4.84142 7.81005 5.07574 7.57574L5.21716 7.71716Z" fill="#171717" fill-opacity="0.8" mask="url(#path-2-outside-1_136_3860)"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/remove_from_recent.svg b/frontend/resources/flowy_icons/16x/remove_from_recent.svg new file mode 100644 index 0000000000..b12c8054aa --- /dev/null +++ b/frontend/resources/flowy_icons/16x/remove_from_recent.svg @@ -0,0 +1,4 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8.93945 16.5C13.0645 16.5 16.4395 13.125 16.4395 9C16.4395 4.875 13.0645 1.5 8.93945 1.5C4.81445 1.5 1.43945 4.875 1.43945 9C1.43945 13.125 4.81445 16.5 8.93945 16.5Z" stroke="#171717" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M5.93945 9H11.9395" stroke="#171717" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"/> +</svg> diff --git a/frontend/resources/flowy_icons/16x/show_menu.svg b/frontend/resources/flowy_icons/16x/show_menu.svg index 8baf55bffd..67edfc4d17 100644 --- a/frontend/resources/flowy_icons/16x/show_menu.svg +++ b/frontend/resources/flowy_icons/16x/show_menu.svg @@ -1,6 +1,4 @@ -<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M10 5L13 8L10 11" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/> -<rect x="3" y="5" width="4" height="1" rx="0.5" fill="#333333"/> -<rect x="3" y="7.5" width="6" height="1" rx="0.5" fill="#333333"/> -<rect x="3" y="10" width="4" height="1" rx="0.5" fill="#333333"/> +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M9.75 14.25L15 9L9.75 3.75" stroke="#171717" stroke-width="1.2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M3.5625 14.25L8.8125 9L3.5625 3.75" stroke="#171717" stroke-width="1.2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> </svg> diff --git a/frontend/resources/flowy_icons/16x/success.svg b/frontend/resources/flowy_icons/16x/success.svg new file mode 100644 index 0000000000..771d8d7f5c --- /dev/null +++ b/frontend/resources/flowy_icons/16x/success.svg @@ -0,0 +1,4 @@ +<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M10.5013 18.3334C15.1037 18.3334 18.8346 14.6025 18.8346 10.0001C18.8346 5.39771 15.1037 1.66675 10.5013 1.66675C5.89893 1.66675 2.16797 5.39771 2.16797 10.0001C2.16797 14.6025 5.89893 18.3334 10.5013 18.3334Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M6.75 10.625L9.58883 13.4524L15.0833 7.5" stroke="white" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/> +</svg> diff --git a/frontend/resources/flowy_icons/24x/m_home_add.svg b/frontend/resources/flowy_icons/24x/m_home_add.svg new file mode 100644 index 0000000000..bf93cf5e68 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_home_add.svg @@ -0,0 +1,5 @@ +<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12.333 22C17.833 22 22.333 17.5 22.333 12C22.333 6.5 17.833 2 12.333 2C6.83301 2 2.33301 6.5 2.33301 12C2.33301 17.5 6.83301 22 12.333 22Z" stroke="#171717" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M8.33301 12H16.333" stroke="#171717" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M12.333 16V8" stroke="#171717" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> +</svg> diff --git a/frontend/resources/flowy_icons/24x/m_home_notification.svg b/frontend/resources/flowy_icons/24x/m_home_notification.svg new file mode 100644 index 0000000000..6d4b883701 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_home_notification.svg @@ -0,0 +1,5 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12.0196 2.91016C8.7096 2.91016 6.0196 5.60016 6.0196 8.91016V11.8002C6.0196 12.4102 5.7596 13.3402 5.4496 13.8602L4.2996 15.7702C3.5896 16.9502 4.0796 18.2602 5.3796 18.7002C9.6896 20.1402 14.3396 20.1402 18.6496 18.7002C19.8596 18.3002 20.3896 16.8702 19.7296 15.7702L18.5796 13.8602C18.2796 13.3402 18.0196 12.4102 18.0196 11.8002V8.91016C18.0196 5.61016 15.3196 2.91016 12.0196 2.91016Z" stroke="#171717" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/> +<path d="M13.8699 3.19994C13.5599 3.10994 13.2399 3.03994 12.9099 2.99994C11.9499 2.87994 11.0299 2.94994 10.1699 3.19994C10.4599 2.45994 11.1799 1.93994 12.0199 1.93994C12.8599 1.93994 13.5799 2.45994 13.8699 3.19994Z" stroke="#171717" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M15.0195 19.0601C15.0195 20.7101 13.6695 22.0601 12.0195 22.0601C11.1995 22.0601 10.4395 21.7201 9.89953 21.1801C9.35953 20.6401 9.01953 19.8801 9.01953 19.0601" stroke="#171717" stroke-width="1.5" stroke-miterlimit="10"/> +</svg> diff --git a/frontend/resources/flowy_icons/24x/m_home_selected.svg b/frontend/resources/flowy_icons/24x/m_home_selected.svg new file mode 100644 index 0000000000..b92efcd453 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_home_selected.svg @@ -0,0 +1,6 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M7.24 2H5.34C3.15 2 2 3.15 2 5.33V7.23C2 9.41 3.15 10.56 5.33 10.56H7.23C9.41 10.56 10.56 9.41 10.56 7.23V5.33C10.57 3.15 9.42 2 7.24 2Z" fill="#00C8FF"/> +<path d="M18.6704 2H16.7704C14.5904 2 13.4404 3.15 13.4404 5.33V7.23C13.4404 9.41 14.5904 10.56 16.7704 10.56H18.6704C20.8504 10.56 22.0004 9.41 22.0004 7.23V5.33C22.0004 3.15 20.8504 2 18.6704 2Z" fill="#00C8FF"/> +<path d="M18.6704 13.4302H16.7704C14.5904 13.4302 13.4404 14.5802 13.4404 16.7602V18.6602C13.4404 20.8402 14.5904 21.9902 16.7704 21.9902H18.6704C20.8504 21.9902 22.0004 20.8402 22.0004 18.6602V16.7602C22.0004 14.5802 20.8504 13.4302 18.6704 13.4302Z" fill="#00C8FF"/> +<path d="M7.24 13.4302H5.34C3.15 13.4302 2 14.5802 2 16.7602V18.6602C2 20.8502 3.15 22.0002 5.33 22.0002H7.23C9.41 22.0002 10.56 20.8502 10.56 18.6702V16.7702C10.57 14.5802 9.42 13.4302 7.24 13.4302Z" fill="#00C8FF"/> +</svg> diff --git a/frontend/resources/flowy_icons/24x/m_home_unselected.svg b/frontend/resources/flowy_icons/24x/m_home_unselected.svg new file mode 100644 index 0000000000..495c73923c --- /dev/null +++ b/frontend/resources/flowy_icons/24x/m_home_unselected.svg @@ -0,0 +1,6 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M5.7 10.2H7.5C9.3 10.2 10.2 9.3 10.2 7.5V5.7C10.2 3.9 9.3 3 7.5 3H5.7C3.9 3 3 3.9 3 5.7V7.5C3 9.3 3.9 10.2 5.7 10.2Z" stroke="#171717" stroke-width="1.35" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M16.5008 10.2H18.3008C20.1008 10.2 21.0008 9.3 21.0008 7.5V5.7C21.0008 3.9 20.1008 3 18.3008 3H16.5008C14.7008 3 13.8008 3.9 13.8008 5.7V7.5C13.8008 9.3 14.7008 10.2 16.5008 10.2Z" stroke="#171717" stroke-width="1.35" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M16.5008 20.9998H18.3008C20.1008 20.9998 21.0008 20.0998 21.0008 18.2998V16.4998C21.0008 14.6998 20.1008 13.7998 18.3008 13.7998H16.5008C14.7008 13.7998 13.8008 14.6998 13.8008 16.4998V18.2998C13.8008 20.0998 14.7008 20.9998 16.5008 20.9998Z" stroke="#171717" stroke-width="1.35" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M5.7 20.9998H7.5C9.3 20.9998 10.2 20.0998 10.2 18.2998V16.4998C10.2 14.6998 9.3 13.7998 7.5 13.7998H5.7C3.9 13.7998 3 14.6998 3 16.4998V18.2998C3 20.0998 3.9 20.9998 5.7 20.9998Z" stroke="#171717" stroke-width="1.35" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +</svg> diff --git a/frontend/resources/flowy_icons/24x/m_setting.svg b/frontend/resources/flowy_icons/24x/m_setting.svg index d8be6a36b7..a32f3bc7b3 100644 --- a/frontend/resources/flowy_icons/24x/m_setting.svg +++ b/frontend/resources/flowy_icons/24x/m_setting.svg @@ -1,3 +1,6 @@ -<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M8.96704 2.45522C7.54904 2.90522 6.32605 3.63923 5.24805 4.64323C4.91505 4.95323 4.81305 5.46123 5.02905 5.86123C5.83005 7.34223 4.99204 8.92723 3.18504 9.01823C2.74304 9.04023 2.35205 9.36823 2.24805 9.79923C2.06905 10.5442 1.99805 11.1682 1.99805 11.9862C1.99805 12.6732 2.07204 13.4512 2.21704 14.1432C2.30704 14.5752 2.68305 14.8862 3.12305 14.9242C4.94105 15.0812 5.84105 16.4682 5.02905 18.2362C4.84905 18.6292 4.93105 19.0992 5.24805 19.3932C6.31005 20.3752 7.53004 21.0682 8.96704 21.5182C9.37704 21.6462 9.84004 21.4912 10.092 21.1432C11.204 19.6042 12.817 19.5992 13.873 21.1432C14.122 21.5062 14.578 21.6812 14.998 21.5492C16.385 21.1122 17.677 20.3692 18.748 19.3932C19.078 19.0922 19.165 18.6052 18.967 18.2052C18.135 16.5262 19.0921 14.9852 20.8101 14.9552C21.2661 14.9472 21.6721 14.6482 21.7791 14.2052C21.9521 13.4882 21.998 12.8642 21.998 11.9862C21.998 11.2322 21.909 10.4892 21.748 9.76823C21.646 9.31123 21.2471 8.98723 20.7791 8.98623C19.0881 8.98323 18.14 7.32123 18.967 5.86123C19.197 5.45523 19.1251 4.95723 18.7791 4.64323C17.6891 3.65323 16.36 2.87922 14.967 2.45522C14.539 2.32522 14.084 2.48523 13.842 2.86123C12.876 4.36223 11.072 4.38823 10.123 2.89323C9.88005 2.50923 9.39904 2.31822 8.96704 2.45522ZM15.045 4.57923C15.728 4.86523 16.267 5.16423 16.886 5.63323C16.16 7.93023 17.391 10.3162 19.941 10.8972C20.004 11.3102 19.998 11.5602 19.998 11.9862C19.998 12.4952 20.0051 12.6742 19.9471 13.0422C17.4081 13.5682 16.152 15.8872 16.859 18.3382C16.251 18.7792 15.816 19.0852 15.053 19.3802C13.261 17.5562 10.7731 17.4762 8.94305 19.3922C8.22905 19.0782 7.68006 18.7992 7.12506 18.3302C7.81306 15.8412 6.65005 13.6922 4.06805 13.0402C3.95305 12.5842 3.99905 11.2962 4.06505 10.9052C6.73505 10.2652 7.78705 7.90223 7.12405 5.62623C7.71005 5.18523 8.23706 4.86423 8.92206 4.58623C10.6471 6.34123 13.237 6.51623 15.045 4.57923ZM11.998 7.98623C9.78905 7.98623 7.99805 9.77723 7.99805 11.9862C7.99805 14.1962 9.78905 15.9862 11.998 15.9862C14.207 15.9862 15.998 14.1962 15.998 11.9862C15.998 9.77723 14.207 7.98623 11.998 7.98623ZM11.998 9.98623C13.103 9.98623 13.998 10.8822 13.998 11.9862C13.998 13.0912 13.103 13.9862 11.998 13.9862C10.893 13.9862 9.99805 13.0912 9.99805 11.9862C9.99805 10.8822 10.893 9.98623 11.998 9.98623Z" fill="#2F3030"/> +<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g opacity="0.7"> +<path d="M10 12.5C11.3807 12.5 12.5 11.3807 12.5 10C12.5 8.61929 11.3807 7.5 10 7.5C8.61929 7.5 7.5 8.61929 7.5 10C7.5 11.3807 8.61929 12.5 10 12.5Z" stroke="#171717" stroke-width="1.25" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M1.66602 10.7334V9.26669C1.66602 8.40003 2.37435 7.68336 3.24935 7.68336C4.75768 7.68336 5.37435 6.6167 4.61602 5.30836C4.18268 4.55836 4.44102 3.58336 5.19935 3.15003L6.64102 2.32503C7.29935 1.93336 8.14935 2.1667 8.54102 2.82503L8.63268 2.98336C9.38268 4.2917 10.616 4.2917 11.3743 2.98336L11.466 2.82503C11.8577 2.1667 12.7077 1.93336 13.366 2.32503L14.8077 3.15003C15.566 3.58336 15.8243 4.55836 15.391 5.30836C14.6327 6.6167 15.2493 7.68336 16.7577 7.68336C17.6243 7.68336 18.341 8.39169 18.341 9.26669V10.7334C18.341 11.6 17.6327 12.3167 16.7577 12.3167C15.2493 12.3167 14.6327 13.3834 15.391 14.6917C15.8243 15.45 15.566 16.4167 14.8077 16.85L13.366 17.675C12.7077 18.0667 11.8577 17.8334 11.466 17.175L11.3743 17.0167C10.6243 15.7084 9.39102 15.7084 8.63268 17.0167L8.54102 17.175C8.14935 17.8334 7.29935 18.0667 6.64102 17.675L5.19935 16.85C4.44102 16.4167 4.18268 15.4417 4.61602 14.6917C5.37435 13.3834 4.75768 12.3167 3.24935 12.3167C2.37435 12.3167 1.66602 11.6 1.66602 10.7334Z" stroke="#171717" stroke-width="1.25" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +</g> </svg> diff --git a/frontend/resources/flowy_icons/40x/m_empty_page.svg b/frontend/resources/flowy_icons/40x/m_empty_page.svg new file mode 100644 index 0000000000..c64507dd0a --- /dev/null +++ b/frontend/resources/flowy_icons/40x/m_empty_page.svg @@ -0,0 +1,6 @@ +<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g opacity="0.4"> +<path d="M18 44H30C40 44 44 40 44 30V18C44 8 40 4 30 4H18C8 4 4 8 4 18V30C4 40 8 44 18 44Z" stroke="#171717" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M4 26.0005H11.52C13.04 26.0005 14.42 26.8605 15.1 28.2205L16.88 31.8005C18 34.0005 20 34.0005 20.48 34.0005H27.54C29.06 34.0005 30.44 33.1405 31.12 31.7805L32.9 28.2005C33.58 26.8405 34.96 25.9805 36.48 25.9805H43.96" stroke="#171717" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> +</g> +</svg> diff --git a/frontend/resources/translations/de-DE.json b/frontend/resources/translations/de-DE.json index 3f4732539b..f0c08ca52e 100644 --- a/frontend/resources/translations/de-DE.json +++ b/frontend/resources/translations/de-DE.json @@ -47,6 +47,7 @@ "unmatchedPasswordError": "Passwörter stimmen nicht überein", "syncPromptMessage": "Synchronisation kann ein paar Minuten dauern. Diese Seite bitte nicht schließen", "or": "ODER", + "signInWith": "Anmeldeoptionen:", "signInWithGoogle": "Mit Google anmelden", "signInWithGithub": "Mit Github anmelden", "signInWithDiscord": "Mit Discord anmelden", @@ -64,15 +65,13 @@ "alreadyHaveAnAccount": "Du hast bereits ein Konto?", "logIn": "Anmeldung", "generalError": "Etwas ist schiefgelaufen. Bitte versuche es später noch einmal", - "limitRateError": "Aus Sicherheitsgründen kannst du nur alle 60 Sekunden einen Authentifizierungslink anfordern", - "LogInWithGoogle": "Mit Google-Account anmelden", - "LogInWithGithub": "Mit GitHub-Account anmelden", - "LogInWithDiscord": "Mit Discord-Account anmelden" + "limitRateError": "Aus Sicherheitsgründen kannst du nur alle 60 Sekunden einen Authentifizierungslink anfordern" }, "workspace": { "chooseWorkspace": "Arbeitsbereich wählen", "create": "Arbeitsbereich erstellen", "reset": "Arbeitsbereich zurücksetzen", + "renameWorkspace": "Arbeitsbereich umbenennen", "resetWorkspacePrompt": "Das Zurücksetzen des Arbeitsbereiches löscht alle enthaltenen Seiten und Daten. Bist du sicher, dass du den Arbeitsbereich zurücksetzen möchtest? ", "hint": "Arbeitsbereich", "notFoundError": "Arbeitsbereich nicht gefunden", @@ -139,7 +138,9 @@ "openNewTab": "In einem neuen Tab öffnen", "moveTo": "Verschieben nach", "addToFavorites": "Zu Favoriten hinzufügen", - "copyLink": "Link kopieren" + "copyLink": "Link kopieren", + "changeIcon": "Symbol ändern", + "collapseAllPages": "Alle Seiten einklappen" }, "blankPageTitle": "Leere Seite", "newPageText": "Neue Seite", @@ -245,6 +246,9 @@ "addAPageToPrivate": "Eine Seite zum privaten Bereich hinzufügen.", "addAPageToWorkspace": "Eine Seite zum Arbeitsbereich hinzufügen", "recent": "Zuletzt", + "today": "Heute", + "thisWeek": "Diese Woche", + "others": "Andere", "public": "Öffentlich", "clickToHidePublic": "Hier klicken, um den öffentlichen Bereich auszublenden.\nHier erstellte Seiten sind für jedes Mitglied sichtbar.", "addAPageToPublic": "Eine Seite zum öffentlichen Bereich hinzufügen." @@ -302,7 +306,8 @@ "back": "Zurück", "signInGoogle": "Mit einem Google Benutzerkonto anmelden", "signInGithub": "Mit einem Github Benutzerkonto anmelden", - "signInDiscord": "Mit einem Discord Benutzerkonto anmelden" + "signInDiscord": "Mit einem Discord Benutzerkonto anmelden", + "more": "Mehr" }, "label": { "welcome": "Willkommen!", @@ -1276,7 +1281,13 @@ "today": "Heute", "jumpToday": "Springe zu Heute", "previousMonth": "Vorheriger Monat", - "nextMonth": "Nächster Monat" + "nextMonth": "Nächster Monat", + "views": { + "day": "Tag", + "week": "Woche", + "month": "Monat", + "year": "Jahr" + } }, "mobileEventScreen": { "emptyTitle": "Noch keine Events", @@ -1296,7 +1307,8 @@ }, "unscheduledEventsTitle": "Ungeplante Events", "clickToAdd": "Klicken Sie, um es zum Kalender hinzuzufügen", - "name": "Kalendereinstellungen" + "name": "Kalendereinstellungen", + "clickToOpen": "Hier klicken, um den Eintrag zu öffnen" }, "referencedCalendarPrefix": "Sicht von", "quickJumpYear": "Spring zu", @@ -1587,7 +1599,9 @@ }, "favorite": { "noFavorite": "Leere Favoritenseite", - "noFavoriteHintText": "Nach links wischen, um es den Favoriten hinzuzufügen" + "noFavoriteHintText": "Nach links wischen, um es den Favoriten hinzuzufügen", + "removeFromSidebar": "Aus der Seitenleiste entfernen", + "addToSidebar": "An Seitenleiste anheften" }, "cardDetails": { "notesPlaceholder": "'/'-Taste, um einen Block einzufügen oder Text eingeben" @@ -1640,6 +1654,7 @@ "workplaceIconSubtitle": "Lade ein Bild hoch oder verwende ein Emoji für deinen Arbeitsbereich. Das Symbol wird in deiner Seitenleiste und in deinen Benachrichtigungen angezeigt.", "renameError": "Umbenennen des Arbeitsbereiches fehlgeschlagen", "updateIconError": "Symbol konnte nicht aktualisiert werden", + "chooseAnIcon": "Symbol auswählen", "appearance": { "name": "Aussehen", "themeMode": { diff --git a/frontend/resources/translations/el-GR.json b/frontend/resources/translations/el-GR.json index 0ee0bc10cd..633a4adf65 100644 --- a/frontend/resources/translations/el-GR.json +++ b/frontend/resources/translations/el-GR.json @@ -201,8 +201,8 @@ "addBlockBelow": "Add a block below" }, "sideBar": { - "closeSidebar": "Close side bar", - "openSidebar": "Open side bar", + "closeSidebar": "Close sidebar", + "openSidebar": "Open sidebar", "personal": "Personal", "favorites": "Favorites", "clickToHidePersonal": "Click to hide personal section", diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 377ba93c0c..d617770c09 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -138,8 +138,8 @@ "moveTo": "Move to", "addToFavorites": "Add to Favorites", "copyLink": "Copy Link", - "changeIcon":"Change icon", - "collapseAllPages": "Collapse all pages" + "changeIcon": "Change icon", + "collapseAllPages": "Collapse all subpages" }, "blankPageTitle": "Blank page", "newPageText": "New page", @@ -147,6 +147,17 @@ "newGridText": "New grid", "newCalendarText": "New calendar", "newBoardText": "New board", + "chat": { + "newChat": "New chat", + "inputMessageHint": "Message AppFlowy AI", + "unsupportedCloudPrompt": "This feature is only available when using AppFlowy Cloud", + "relatedQuestion": "Related", + "serverUnavailable": "Service Temporarily Unavailable. Please try again later.", + "aiServerUnavailable": "There was an error generating a response.", + "clickToRetry": "Click to retry", + "regenerateAnswer": "Regenerate", + "aiMistakePrompt": "AI can make mistakes. Check important info." + }, "trash": { "text": "Trash", "restoreAll": "Restore All", @@ -229,8 +240,8 @@ "genSummary": "Generate summary" }, "sideBar": { - "closeSidebar": "Close side bar", - "openSidebar": "Open side bar", + "closeSidebar": "Close sidebar", + "openSidebar": "Open sidebar", "personal": "Personal", "private": "Private", "workspace": "Workspace", @@ -245,7 +256,20 @@ "recent": "Recent", "today": "Today", "thisWeek": "This week", - "others": "Others" + "others": "Others", + "justNow": "just now", + "minutesAgo": "{count} minutes ago", + "lastViewed": "Last viewed", + "favoriteAt": "Favorited at", + "emptyRecent": "No Recent Documents", + "emptyRecentDescription": "As you view documents, they will appear here for easy retrieval", + "emptyFavorite": "No Favorite Documents", + "emptyFavoriteDescription": "Start exploring and mark documents as favorites. They’ll be listed here for quick access!", + "removePageFromRecent": "Remove this page from the Recent?", + "removeSuccess": "Removed successfully", + "favoriteSpace": "Favorites", + "RecentSpace": "Recent", + "Spaces": "Spaces" }, "notifications": { "export": { @@ -284,6 +308,7 @@ "update": "Update", "share": "Share", "removeFromFavorites": "Remove from favorites", + "removeFromRecent": "Remove from recent", "addToFavorites": "Add to favorites", "rename": "Rename", "helpCenter": "Help Center", @@ -428,7 +453,7 @@ "manageDataPage": { "menuLabel": "Manage data", "title": "Manage data", - "description": "Manage data local storage or Import your existing data into @:appName. You can secure your data with end to end encryption.", + "description": "Manage data local storage or Import your existing data into @:appName.", "dataStorage": { "title": "File storage location", "tooltip": "The location where your files are stored", @@ -647,6 +672,10 @@ "enableNotifications": { "label": "Enable notifications", "hint": "Turn off to stop local notifications from appearing." + }, + "showNotificationsIcon": { + "label": "Show notifications icon", + "hint": "Toggle off to hide the notification icon in the sidebar." } }, "appearance": { @@ -1235,7 +1264,17 @@ "newDatabase": "New Database", "linkToDatabase": "Link to Database" }, - "date": "Date" + "date": "Date", + "video": { + "label": "Video", + "emptyLabel": "Add a video", + "placeholder": "Paste the video link", + "copiedToPasteBoard": "The video link has been copied to the clipboard", + "insertVideo": "Add video", + "invalidVideoUrl": "The source URL is not supported yet.", + "invalidVideoUrlYouTube": "YouTube is not supported yet.", + "supportedFormats": "Supported formats: MP4, WebM, MOV, AVI, FLV, MPEG/M4V, H.264" + } }, "outlineBlock": { "placeholder": "Table of Contents" diff --git a/frontend/resources/translations/es-VE.json b/frontend/resources/translations/es-VE.json index 57cabeb120..6177cd5377 100644 --- a/frontend/resources/translations/es-VE.json +++ b/frontend/resources/translations/es-VE.json @@ -42,7 +42,7 @@ "emailHint": "Correo", "passwordHint": "Contraseña", "dontHaveAnAccount": "¿No posee credenciales?", - "createAccount": "Crear cuenta", + "createAccount": "Crear una cuenta", "repeatPasswordEmptyError": "La contraseña no puede estar en blanco", "unmatchedPasswordError": "Las contraseñas no coinciden", "syncPromptMessage": "La sincronización de los datos puede tardar un poco. Por favor no cierres esta página", @@ -64,12 +64,7 @@ "alreadyHaveAnAccount": "¿Ya tienes cuenta?", "logIn": "Iniciar sesión", "generalError": "Algo ha salido mal. Por favor, inténtalo más tarde", - "limitRateError": "Por razones de seguridad, solo puedes solicitar un enlace mágico cada 60 segundos", - "LogInWithGoogle": "Iniciar sesión con Google", - "LogInWithGithub": "Iniciar sesión con Github", - "LogInWithDiscord": "Iniciar sesión con Discord", - "loginAsGuestButtonText": "Empezar", - "logInWithMagicLink": "Iniciar sesión con Enlace Mágico" + "limitRateError": "Por razones de seguridad, solo puedes solicitar un enlace mágico cada 60 segundos" }, "workspace": { "chooseWorkspace": "Elige tu espacio de trabajo", @@ -425,7 +420,7 @@ "dark": "Modo Oscuro", "system": "Adapt to System" }, - "fontScaleFactor": "Escala de la fuente", + "fontScaleFactor": "Factor de escala de fuente", "documentSettings": { "cursorColor": "Color del cursor del documento", "selectionColor": "Color de selección de documento", @@ -483,7 +478,7 @@ "enableRTLToolbarItems": "Habilitar elementos de la barra de herramientas RTL", "members": { "title": "Configuración de miembros", - "inviteMembers": "Invitar miembros", + "inviteMembers": "Invitar a los miembros", "sendInvite": "Enviar invitación", "copyInviteLink": "Copiar enlace de invitación", "label": "Miembros", @@ -494,8 +489,7 @@ "guest": "Invitado", "member": "Miembro", "memberHintText": "Un miembro puede leer, comentar y editar páginas. Invitar a miembros e invitados.", - "guestHintText": "Un Invitado puede leer, reaccionar, comentar y editar ciertas páginas con permiso.", - "emailInvalidError": "Email no válido, compruébalo y vuelve a intentarlo.", + "emailInvalidError": "Correo electrónico no válido, compruébalo y vuelve a intentarlo.", "emailSent": "Email enviado, por favor revisa la bandeja de entrada", "members": "miembros", "membersCount": { @@ -577,7 +571,6 @@ "codeBlockOutdentLines": "Eliminar dos espacios al inicio de la línea en el bloque de código", "codeBlockAddTwoSpaces": "Insertar dos espacios en la posición del cursor en el bloque de código", "codeBlockSelectAll": "Seleccionar todo el contenido dentro de un bloque de código", - "codeBlockPasteText": "Pegar texto en bloque de código", "textAlignLeft": "Alinear texto a la izquierda", "textAlignCenter": "Alinear el texto al centro", "textAlignRight": "Alinear el texto a la derecha" @@ -595,7 +588,7 @@ "userAgreement": "Acuerdo del Usuario", "termsAndConditions": "Términos y condiciones", "userprofileError": "No se pudo cargar el perfil de usuario", - "userprofileErrorDescription": "Intenta cerrar sesión y volver a entrar para comprobar si el problema persiste.", + "userprofileErrorDescription": "Intente cerrar sesión y volver a iniciarla para comprobar si el problema persiste.", "selectLayout": "Seleccionar diseño", "selectStartingDay": "Seleccione el día de inicio", "version": "Versión" @@ -678,8 +671,8 @@ "choicechipPrefix": { "before": "Antes", "after": "Después", - "onOrBefore": "En o antes de", - "onOrAfter": "En o después de", + "onOrBefore": "En o antes", + "onOrAfter": "Sobre o después", "isEmpty": "Está vacio", "isNotEmpty": "No está vacío" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 581f1fd642..92e8286256 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -156,14 +156,14 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "anyhow", "bincode", @@ -181,15 +181,63 @@ dependencies = [ ] [[package]] -name = "appflowy-cloud-billing-client" +name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=1d5297d2cfc8813b7f6a97cc74cb4ebef78c4b30#1d5297d2cfc8813b7f6a97cc74cb4ebef78c4b30" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ - "client-api", + "anyhow", + "bincode", + "getrandom 0.2.10", "reqwest", "serde", "serde_json", - "shared-entity", + "serde_repr", + "thiserror", + "tokio", + "tsify", + "url", + "uuid", + "wasm-bindgen", +] + +[[package]] +name = "appflowy-ai-client" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" +dependencies = [ + "anyhow", + "bytes", + "futures", + "serde", + "serde_json", + "serde_repr", + "thiserror", +] + +[[package]] +name = "appflowy-ai-client" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "bytes", + "futures", + "serde", + "serde_json", + "serde_repr", + "thiserror", +] + +[[package]] +name = "appflowy-cloud-billing-client" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=13d00e3a63e7f6eb19f5372539a6c49c22ca5f8c#13d00e3a63e7f6eb19f5372539a6c49c22ca5f8c" +dependencies = [ + "client-api 0.2.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "reqwest", + "serde", + "serde_json", + "shared-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", "tokio", "yrs", ] @@ -544,9 +592,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] @@ -664,27 +712,70 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "again", "anyhow", - "app-error", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "async-trait", + "bincode", + "bytes", + "chrono", + "client-websocket 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "collab-entity", + "collab-rt-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "collab-rt-protocol 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "database-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "futures-core", + "futures-util", + "getrandom 0.2.10", + "gotrue 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "gotrue-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "mime", + "parking_lot 0.12.1", + "prost", + "reqwest", + "semver", + "serde", + "serde_json", + "serde_repr", + "serde_urlencoded", + "shared-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tokio-util", + "tracing", + "url", + "uuid", + "wasm-bindgen-futures", +] + +[[package]] +name = "client-api" +version = "0.2.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "again", + "anyhow", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "async-trait", "bincode", "brotli", "bytes", "chrono", - "client-websocket", + "client-websocket 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "collab", "collab-entity", - "collab-rt-entity", - "collab-rt-protocol", - "database-entity", + "collab-rt-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "collab-rt-protocol 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "database-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "futures-core", "futures-util", "getrandom 0.2.10", - "gotrue", - "gotrue-entity", + "gotrue 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "gotrue-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "mime", "parking_lot 0.12.1", "prost", @@ -694,7 +785,8 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "shared-entity", + "serde_urlencoded", + "shared-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "thiserror", "tokio", "tokio-retry", @@ -710,7 +802,25 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "percent-encoding", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "client-websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "futures-channel", "futures-util", @@ -753,7 +863,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -777,7 +887,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-trait", @@ -807,7 +917,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -826,7 +936,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "bytes", @@ -841,7 +951,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "chrono", @@ -879,7 +989,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "async-stream", @@ -918,17 +1028,42 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "anyhow", "bincode", "bytes", "chrono", - "client-websocket", + "client-websocket 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", "collab", "collab-entity", - "collab-rt-protocol", - "database-entity", + "collab-rt-protocol 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "database-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "prost", + "prost-build", + "protoc-bin-vendored", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio-tungstenite", + "yrs", +] + +[[package]] +name = "collab-rt-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "chrono", + "client-websocket 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "collab", + "collab-entity", + "collab-rt-protocol 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "database-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "prost", "prost-build", "protoc-bin-vendored", @@ -943,7 +1078,24 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "collab", + "collab-entity", + "serde", + "thiserror", + "tokio", + "tracing", + "yrs", +] + +[[package]] +name = "collab-rt-protocol" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "async-trait", @@ -960,7 +1112,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0b52164#0b521646f5d609abe11a213ab063402c32496e9b" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" dependencies = [ "anyhow", "collab", @@ -1163,7 +1315,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1263,10 +1415,29 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "anyhow", - "app-error", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "bincode", + "chrono", + "collab-entity", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "database-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "bincode", "chrono", "collab-entity", @@ -1354,6 +1525,7 @@ dependencies = [ "diesel_derives", "libsqlite3-sys", "r2d2", + "serde_json", "time", ] @@ -1501,6 +1673,8 @@ dependencies = [ "collab-folder", "collab-plugins", "dotenv", + "flowy-chat", + "flowy-chat-pub", "flowy-core", "flowy-database-pub", "flowy-database2", @@ -1643,6 +1817,39 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "flowy-chat" +version = "0.1.0" +dependencies = [ + "bytes", + "dashmap", + "flowy-chat-pub", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-notification", + "flowy-sqlite", + "futures", + "lib-dispatch", + "lib-infra", + "protobuf", + "strum_macros 0.21.1", + "tokio", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "flowy-chat-pub" +version = "0.1.0" +dependencies = [ + "client-api 0.2.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "flowy-error", + "futures", + "lib-infra", +] + [[package]] name = "flowy-codegen" version = "0.1.0" @@ -1688,13 +1895,15 @@ dependencies = [ "anyhow", "base64 0.21.5", "bytes", - "client-api", + "client-api 0.2.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "collab", "collab-entity", "collab-integrate", "collab-plugins", "console-subscriber", "diesel", + "flowy-chat", + "flowy-chat-pub", "flowy-config", "flowy-database-pub", "flowy-database2", @@ -1887,7 +2096,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bytes", - "client-api", + "client-api 0.2.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "collab-database", "collab-document", "collab-folder", @@ -2025,13 +2234,14 @@ dependencies = [ "assert-json-diff", "bytes", "chrono", - "client-api", + "client-api 0.2.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "collab", "collab-document", "collab-entity", "collab-folder", "collab-plugins", "dotenv", + "flowy-chat-pub", "flowy-database-pub", "flowy-document-pub", "flowy-encrypt", @@ -2479,13 +2689,30 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "anyhow", "futures-util", "getrandom 0.2.10", - "gotrue-entity", - "infra", + "gotrue-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "infra 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "reqwest", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "gotrue" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "futures-util", + "getrandom 0.2.10", + "gotrue-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "infra 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "reqwest", "serde", "serde_json", @@ -2496,10 +2723,24 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "anyhow", - "app-error", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "chrono", + "jsonwebtoken", + "lazy_static", + "serde", + "serde_json", +] + +[[package]] +name = "gotrue-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "chrono", "jsonwebtoken", "lazy_static", @@ -2861,7 +3102,19 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" +dependencies = [ + "anyhow", + "reqwest", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "infra" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" dependencies = [ "anyhow", "reqwest", @@ -3736,7 +3989,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "phf_macros 0.8.0", + "phf_macros", "phf_shared 0.8.0", "proc-macro-hack", ] @@ -3756,7 +4009,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", "phf_shared 0.11.2", ] @@ -3824,19 +4076,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.47", -] - [[package]] name = "phf_shared" version = "0.8.0" @@ -4040,7 +4279,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.11.0", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -4061,7 +4300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.47", @@ -4824,18 +5063,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", @@ -4958,14 +5197,37 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f#6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96#45bfcc0a31e84996157c69a60c8458eeb98b5f96" dependencies = [ "anyhow", - "app-error", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "appflowy-ai-client 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", "chrono", "collab-entity", - "database-entity", - "gotrue-entity", + "database-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "futures", + "gotrue-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=45bfcc0a31e84996157c69a60c8458eeb98b5f96)", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "uuid", +] + +[[package]] +name = "shared-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +dependencies = [ + "anyhow", + "app-error 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "appflowy-ai-client 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "chrono", + "collab-entity", + "database-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", + "futures", + "gotrue-entity 0.1.0 (git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a)", "reqwest", "serde", "serde_json", @@ -5469,18 +5731,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 1c51d68a70..afcfdf70ae 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -29,6 +29,7 @@ members = [ "build-tool/flowy-codegen", "build-tool/flowy-derive", "flowy-search-pub", + "flowy-chat", "flowy-chat-pub", ] resolver = "2" @@ -61,13 +62,15 @@ flowy-search = { workspace = true, path = "flowy-search" } flowy-search-pub = { workspace = true, path = "flowy-search-pub" } collab-integrate = { workspace = true, path = "collab-integrate" } flowy-date = { workspace = true, path = "flowy-date" } +flowy-chat = { workspace = true, path = "flowy-chat" } +flowy-chat-pub = { workspace = true, path = "flowy-chat-pub" } anyhow = "1.0" tracing = "0.1.40" bytes = "1.5.0" serde_json = "1.0.108" serde = "1.0.194" protobuf = { version = "2.28.0" } -diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } +diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2", "serde_json"] } uuid = { version = "1.5.0", features = ["serde", "v4", "v5"] } serde_repr = "0.1" parking_lot = "0.12" @@ -91,7 +94,7 @@ yrs = "0.18.8" # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ client-api = { version = "0.2" } -appflowy-cloud-billing-client = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client", rev = "1d5297d2cfc8813b7f6a97cc74cb4ebef78c4b30" } +appflowy-cloud-billing-client = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client", rev = "13d00e3a63e7f6eb19f5372539a6c49c22ca5f8c" } [profile.dev] opt-level = 1 @@ -118,7 +121,7 @@ lto = false incremental = false [patch.crates-io] -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6cc46e3779f7174284a0b52cbc87fb1cf98b0b9f" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } # TODO(Lucas.Xu) Upgrade to the latest version of RocksDB once PR(https://github.com/rust-rocksdb/rust-rocksdb/pull/869) is merged. # Currently, using the following revision id. This commit is patched to fix the 32-bit build issue and it's checked out from 0.21.0, not 0.22.0. @@ -132,10 +135,10 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0b52164" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index e17ede23e5..bca0489e7b 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -32,8 +32,8 @@ lib-dispatch = { workspace = true } # Core #flowy-core = { workspace = true, features = ["profiling"] } -flowy-core = { workspace = true, features = ["verbose_log"] } -#flowy-core = { workspace = true } +#flowy-core = { workspace = true, features = ["verbose_log"] } +flowy-core = { workspace = true } flowy-notification = { workspace = true, features = ["dart"] } flowy-document = { workspace = true, features = ["dart"] } diff --git a/frontend/rust-lib/dart-ffi/src/lib.rs b/frontend/rust-lib/dart-ffi/src/lib.rs index a7f3e2ee19..aecd9bef28 100644 --- a/frontend/rust-lib/dart-ffi/src/lib.rs +++ b/frontend/rust-lib/dart-ffi/src/lib.rs @@ -169,12 +169,6 @@ pub extern "C" fn set_stream_port(notification_port: i64) -> i32 { pub extern "C" fn set_log_stream_port(port: i64) -> i32 { *LOG_STREAM_ISOLATE.lock() = Some(Isolate::new(port)); - LOG_STREAM_ISOLATE - .lock() - .as_ref() - .unwrap() - .post("hello log".to_string().as_bytes().to_vec()); - 0 } diff --git a/frontend/rust-lib/event-integration-test/Cargo.toml b/frontend/rust-lib/event-integration-test/Cargo.toml index d427a8f16c..aca158bfaf 100644 --- a/frontend/rust-lib/event-integration-test/Cargo.toml +++ b/frontend/rust-lib/event-integration-test/Cargo.toml @@ -16,6 +16,7 @@ flowy-database-pub = { workspace = true } flowy-document = { path = "../flowy-document" } flowy-document-pub = { workspace = true } flowy-encrypt = { workspace = true } +flowy-chat = { workspace = true } lib-dispatch = { workspace = true } lib-infra = { workspace = true } flowy-server = { path = "../flowy-server" } @@ -56,6 +57,7 @@ chrono = "0.4.31" zip = "0.6.6" walkdir = "2.5.0" futures = "0.3.30" +flowy-chat-pub = { workspace = true } [features] default = ["supabase_cloud_test"] diff --git a/frontend/rust-lib/event-integration-test/src/chat_event.rs b/frontend/rust-lib/event-integration-test/src/chat_event.rs new file mode 100644 index 0000000000..ca2c4911f3 --- /dev/null +++ b/frontend/rust-lib/event-integration-test/src/chat_event.rs @@ -0,0 +1,89 @@ +use crate::event_builder::EventBuilder; +use crate::EventIntegrationTest; +use flowy_chat::entities::{ + ChatMessageListPB, ChatMessageTypePB, LoadNextChatMessagePB, LoadPrevChatMessagePB, + SendChatPayloadPB, +}; +use flowy_chat::event_map::ChatEvent; +use flowy_folder::entities::{CreateViewPayloadPB, ViewLayoutPB, ViewPB}; +use flowy_folder::event_map::FolderEvent; + +impl EventIntegrationTest { + pub async fn create_chat(&self, parent_id: &str) -> ViewPB { + let payload = CreateViewPayloadPB { + parent_view_id: parent_id.to_string(), + name: "chat".to_string(), + desc: "".to_string(), + thumbnail: None, + layout: ViewLayoutPB::Chat, + initial_data: vec![], + meta: Default::default(), + set_as_current: true, + index: None, + section: None, + }; + EventBuilder::new(self.clone()) + .event(FolderEvent::CreateView) + .payload(payload) + .async_send() + .await + .parse::<ViewPB>() + } + + pub async fn send_message( + &self, + chat_id: &str, + message: impl ToString, + message_type: ChatMessageTypePB, + ) { + let payload = SendChatPayloadPB { + chat_id: chat_id.to_string(), + message: message.to_string(), + message_type, + }; + + EventBuilder::new(self.clone()) + .event(ChatEvent::SendMessage) + .payload(payload) + .async_send() + .await; + } + + pub async fn load_prev_message( + &self, + chat_id: &str, + limit: i64, + before_message_id: Option<i64>, + ) -> ChatMessageListPB { + let payload = LoadPrevChatMessagePB { + chat_id: chat_id.to_string(), + limit, + before_message_id, + }; + EventBuilder::new(self.clone()) + .event(ChatEvent::LoadPrevMessage) + .payload(payload) + .async_send() + .await + .parse::<ChatMessageListPB>() + } + + pub async fn load_next_message( + &self, + chat_id: &str, + limit: i64, + after_message_id: Option<i64>, + ) -> ChatMessageListPB { + let payload = LoadNextChatMessagePB { + chat_id: chat_id.to_string(), + limit, + after_message_id, + }; + EventBuilder::new(self.clone()) + .event(ChatEvent::LoadNextMessage) + .payload(payload) + .async_send() + .await + .parse::<ChatMessageListPB>() + } +} diff --git a/frontend/rust-lib/event-integration-test/src/lib.rs b/frontend/rust-lib/event-integration-test/src/lib.rs index cddd304dde..2ae16c74b3 100644 --- a/frontend/rust-lib/event-integration-test/src/lib.rs +++ b/frontend/rust-lib/event-integration-test/src/lib.rs @@ -24,6 +24,7 @@ use lib_dispatch::runtime::AFPluginRuntime; use crate::user_event::TestNotificationSender; +mod chat_event; pub mod database_event; pub mod document; pub mod document_event; diff --git a/frontend/rust-lib/event-integration-test/src/user_event.rs b/frontend/rust-lib/event-integration-test/src/user_event.rs index a2e4dda7c5..40e8044806 100644 --- a/frontend/rust-lib/event-integration-test/src/user_event.rs +++ b/frontend/rust-lib/event-integration-test/src/user_event.rs @@ -378,6 +378,26 @@ impl TestNotificationSender { rx } + pub fn subscribe_without_payload( + &self, + id: &str, + ty: impl Into<i32> + Send, + ) -> tokio::sync::mpsc::Receiver<()> { + let id = id.to_string(); + let (tx, rx) = tokio::sync::mpsc::channel::<()>(10); + let mut receiver = self.sender.subscribe(); + let ty = ty.into(); + af_spawn(async move { + // DatabaseNotification::DidUpdateDatabaseSnapshotState + while let Ok(value) = receiver.recv().await { + if value.id == id && value.ty == ty { + let _ = tx.send(()).await; + } + } + }); + rx + } + pub fn subscribe_with_condition<T, F>(&self, id: &str, when: F) -> tokio::sync::mpsc::Receiver<T> where T: TryFrom<Bytes, Error = ProtobufError> + Send + 'static, diff --git a/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs b/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs new file mode 100644 index 0000000000..1efe4c77d0 --- /dev/null +++ b/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs @@ -0,0 +1,161 @@ +use crate::util::receive_with_timeout; +use event_integration_test::user_event::user_localhost_af_cloud; +use event_integration_test::EventIntegrationTest; +use flowy_chat::entities::{ChatMessageListPB, ChatMessageTypePB}; +use flowy_chat::notification::ChatNotification; + +use flowy_chat_pub::cloud::ChatMessageType; +use futures_util::StreamExt; +use std::time::Duration; + +#[tokio::test] +async fn af_cloud_create_chat_message_test() { + user_localhost_af_cloud().await; + let test = EventIntegrationTest::new().await; + test.af_cloud_sign_up().await; + + let current_workspace = test.get_current_workspace().await; + let view = test.create_chat(¤t_workspace.id).await; + let chat_id = view.id.clone(); + let chat_service = test.server_provider.get_server().unwrap().chat_service(); + for i in 0..10 { + let mut stream = chat_service + .send_chat_message( + ¤t_workspace.id, + &chat_id, + &format!("hello world {}", i), + ChatMessageType::System, + ) + .await + .unwrap(); + while let Some(message) = stream.next().await { + message.unwrap(); + } + } + let rx = test + .notification_sender + .subscribe::<ChatMessageListPB>(&chat_id, ChatNotification::DidLoadLatestChatMessage); + let _ = test.load_next_message(&chat_id, 10, None).await; + let all = receive_with_timeout(rx, Duration::from_secs(30)) + .await + .unwrap(); + assert_eq!(all.messages.len(), 10); + // in desc order + assert_eq!(all.messages[4].content, "hello world 5"); + assert_eq!(all.messages[5].content, "hello world 4"); + + let list = test + .load_next_message(&chat_id, 5, Some(all.messages[4].message_id)) + .await; + assert_eq!(list.messages.len(), 4); + assert_eq!(list.messages[0].content, "hello world 9"); + assert_eq!(list.messages[1].content, "hello world 8"); + assert_eq!(list.messages[2].content, "hello world 7"); + assert_eq!(list.messages[3].content, "hello world 6"); + + assert_eq!(all.messages[6].content, "hello world 3"); + + // Load from local + let list = test + .load_prev_message(&chat_id, 5, Some(all.messages[6].message_id)) + .await; + assert_eq!(list.messages.len(), 3); + assert_eq!(list.messages[0].content, "hello world 2"); + assert_eq!(list.messages[1].content, "hello world 1"); + assert_eq!(list.messages[2].content, "hello world 0"); +} + +#[tokio::test] +async fn af_cloud_load_remote_system_message_test() { + user_localhost_af_cloud().await; + let test = EventIntegrationTest::new().await; + test.af_cloud_sign_up().await; + + let current_workspace = test.get_current_workspace().await; + let view = test.create_chat(¤t_workspace.id).await; + let chat_id = view.id.clone(); + + let chat_service = test.server_provider.get_server().unwrap().chat_service(); + for i in 0..10 { + let mut stream = chat_service + .send_chat_message( + ¤t_workspace.id, + &chat_id, + &format!("hello server {}", i), + ChatMessageType::System, + ) + .await + .unwrap(); + while let Some(message) = stream.next().await { + message.unwrap(); + } + } + + let rx = test + .notification_sender + .subscribe::<ChatMessageListPB>(&chat_id, ChatNotification::DidLoadLatestChatMessage); + + // Previous messages were created by the server, so there are no messages in the local cache. + // It will try to load messages in the background. + let all = test.load_next_message(&chat_id, 5, None).await; + assert!(all.messages.is_empty()); + + // Wait for the messages to be loaded. + let next_back_five = receive_with_timeout(rx, Duration::from_secs(60)) + .await + .unwrap(); + assert_eq!(next_back_five.messages.len(), 5); + assert!(next_back_five.has_more); + assert_eq!(next_back_five.total, 10); + assert_eq!(next_back_five.messages[0].content, "hello server 9"); + assert_eq!(next_back_five.messages[1].content, "hello server 8"); + assert_eq!(next_back_five.messages[2].content, "hello server 7"); + assert_eq!(next_back_five.messages[3].content, "hello server 6"); + assert_eq!(next_back_five.messages[4].content, "hello server 5"); + + // Load first five messages + let rx = test + .notification_sender + .subscribe::<ChatMessageListPB>(&chat_id, ChatNotification::DidLoadPrevChatMessage); + test + .load_prev_message(&chat_id, 5, Some(next_back_five.messages[4].message_id)) + .await; + let first_five_messages = receive_with_timeout(rx, Duration::from_secs(60)) + .await + .unwrap(); + assert!(!first_five_messages.has_more); + assert_eq!(first_five_messages.messages[0].content, "hello server 4"); + assert_eq!(first_five_messages.messages[1].content, "hello server 3"); + assert_eq!(first_five_messages.messages[2].content, "hello server 2"); + assert_eq!(first_five_messages.messages[3].content, "hello server 1"); + assert_eq!(first_five_messages.messages[4].content, "hello server 0"); +} + +#[tokio::test] +async fn af_cloud_load_remote_user_message_test() { + user_localhost_af_cloud().await; + let test = EventIntegrationTest::new().await; + test.af_cloud_sign_up().await; + + let current_workspace = test.get_current_workspace().await; + let view = test.create_chat(¤t_workspace.id).await; + let chat_id = view.id.clone(); + let rx = test + .notification_sender + .subscribe_without_payload(&chat_id, ChatNotification::FinishAnswerQuestion); + test + .send_message(&chat_id, "hello world", ChatMessageTypePB::User) + .await; + let _ = receive_with_timeout(rx, Duration::from_secs(60)) + .await + .unwrap(); + + let all = test.load_next_message(&chat_id, 5, None).await; + assert_eq!(all.messages.len(), 2); + // 3 means AI + assert_eq!(all.messages[0].author_type, 3); + // 2 means User + assert_eq!(all.messages[1].author_type, 1); + // The message ID is incremented by 1. + assert_eq!(all.messages[1].message_id + 1, all.messages[0].message_id); +} diff --git a/frontend/rust-lib/event-integration-test/tests/chat/mod.rs b/frontend/rust-lib/event-integration-test/tests/chat/mod.rs new file mode 100644 index 0000000000..773bdab81f --- /dev/null +++ b/frontend/rust-lib/event-integration-test/tests/chat/mod.rs @@ -0,0 +1 @@ +mod chat_message_test; diff --git a/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs b/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs index 0a2f34ca0a..fe55ad1bd2 100644 --- a/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs +++ b/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs @@ -158,7 +158,9 @@ impl FolderTest { assert_eq!(self.child_view, view, "View not equal"); }, FolderScript::ReadView(view_id) => { - let view = read_view(sdk, &view_id).await; + let mut view = read_view(sdk, &view_id).await; + // Ignore the last edited time + view.last_edited = 0; self.child_view = view; }, FolderScript::UpdateView { diff --git a/frontend/rust-lib/event-integration-test/tests/main.rs b/frontend/rust-lib/event-integration-test/tests/main.rs index 05d0797473..05f19e9b75 100644 --- a/frontend/rust-lib/event-integration-test/tests/main.rs +++ b/frontend/rust-lib/event-integration-test/tests/main.rs @@ -6,3 +6,5 @@ mod folder; // mod search; mod user; pub mod util; + +mod chat; diff --git a/frontend/rust-lib/flowy-chat-pub/Cargo.toml b/frontend/rust-lib/flowy-chat-pub/Cargo.toml new file mode 100644 index 0000000000..0cfdae0ec9 --- /dev/null +++ b/frontend/rust-lib/flowy-chat-pub/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "flowy-chat-pub" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lib-infra = { workspace = true } +flowy-error = { workspace = true } +client-api = { workspace = true } +futures.workspace = true \ No newline at end of file diff --git a/frontend/rust-lib/flowy-chat-pub/src/cloud.rs b/frontend/rust-lib/flowy-chat-pub/src/cloud.rs new file mode 100644 index 0000000000..51de79422a --- /dev/null +++ b/frontend/rust-lib/flowy-chat-pub/src/cloud.rs @@ -0,0 +1,50 @@ +pub use client_api::entity::ai_dto::{RelatedQuestion, RepeatedRelatedQuestion}; +pub use client_api::entity::{ + ChatAuthorType, ChatMessage, ChatMessageType, MessageCursor, QAChatMessage, RepeatedChatMessage, +}; +use client_api::error::AppResponseError; +use flowy_error::FlowyError; +use futures::stream::BoxStream; +use lib_infra::async_trait::async_trait; +use lib_infra::future::FutureResult; + +pub type ChatMessageStream = BoxStream<'static, Result<ChatMessage, AppResponseError>>; +#[async_trait] +pub trait ChatCloudService: Send + Sync + 'static { + fn create_chat( + &self, + uid: &i64, + workspace_id: &str, + chat_id: &str, + ) -> FutureResult<(), FlowyError>; + + async fn send_chat_message( + &self, + workspace_id: &str, + chat_id: &str, + message: &str, + message_type: ChatMessageType, + ) -> Result<ChatMessageStream, FlowyError>; + + fn get_chat_messages( + &self, + workspace_id: &str, + chat_id: &str, + offset: MessageCursor, + limit: u64, + ) -> FutureResult<RepeatedChatMessage, FlowyError>; + + fn get_related_message( + &self, + workspace_id: &str, + chat_id: &str, + message_id: i64, + ) -> FutureResult<RepeatedRelatedQuestion, FlowyError>; + + fn generate_answer( + &self, + workspace_id: &str, + chat_id: &str, + question_message_id: i64, + ) -> FutureResult<ChatMessage, FlowyError>; +} diff --git a/frontend/rust-lib/flowy-chat-pub/src/lib.rs b/frontend/rust-lib/flowy-chat-pub/src/lib.rs new file mode 100644 index 0000000000..1ede32218e --- /dev/null +++ b/frontend/rust-lib/flowy-chat-pub/src/lib.rs @@ -0,0 +1 @@ +pub mod cloud; diff --git a/frontend/rust-lib/flowy-chat/Cargo.toml b/frontend/rust-lib/flowy-chat/Cargo.toml new file mode 100644 index 0000000000..e1a7175442 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "flowy-chat" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +flowy-derive.workspace = true +flowy-notification = { workspace = true } +flowy-error = { path = "../flowy-error", features = [ + "impl_from_dispatch_error", + "impl_from_collab_folder", +] } +lib-dispatch = { workspace = true } +tracing.workspace = true +uuid.workspace = true +strum_macros = "0.21" +protobuf.workspace = true +bytes.workspace = true +validator = { version = "0.16.0", features = ["derive"] } +lib-infra = { workspace = true } +flowy-chat-pub.workspace = true +dashmap = "5.5" +flowy-sqlite = { workspace = true } +tokio.workspace = true +futures.workspace = true + +[build-dependencies] +flowy-codegen.workspace = true + +[features] +dart = ["flowy-codegen/dart", "flowy-notification/dart"] +tauri_ts = ["flowy-codegen/ts", "flowy-notification/tauri_ts"] +web_ts = ["flowy-codegen/ts", "flowy-notification/web_ts"] diff --git a/frontend/rust-lib/flowy-chat/Flowy.toml b/frontend/rust-lib/flowy-chat/Flowy.toml new file mode 100644 index 0000000000..1410c5951e --- /dev/null +++ b/frontend/rust-lib/flowy-chat/Flowy.toml @@ -0,0 +1,3 @@ +# Check out the FlowyConfig (located in flowy_toml.rs) for more details. +proto_input = ["src/entities.rs", "src/event_map.rs", "src/notification.rs"] +event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-chat/build.rs b/frontend/rust-lib/flowy-chat/build.rs new file mode 100644 index 0000000000..fac4cc65ae --- /dev/null +++ b/frontend/rust-lib/flowy-chat/build.rs @@ -0,0 +1,40 @@ +fn main() { + #[cfg(feature = "dart")] + { + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME")); + } + + #[cfg(feature = "tauri_ts")] + { + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Tauri, + ); + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::TauriApp, + ); + } + + #[cfg(feature = "web_ts")] + { + flowy_codegen::ts_event::gen( + "folder", + flowy_codegen::Project::Web { + relative_path: "../../".to_string(), + }, + ); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + "folder", + flowy_codegen::Project::Web { + relative_path: "../../".to_string(), + }, + ); + } +} diff --git a/frontend/rust-lib/flowy-chat/src/chat.rs b/frontend/rust-lib/flowy-chat/src/chat.rs new file mode 100644 index 0000000000..712caad91a --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/chat.rs @@ -0,0 +1,471 @@ +use crate::entities::{ + ChatMessageErrorPB, ChatMessageListPB, ChatMessagePB, RepeatedRelatedQuestionPB, +}; +use crate::manager::ChatUserService; +use crate::notification::{send_notification, ChatNotification}; +use crate::persistence::{ + insert_answer_message, insert_chat_messages, select_chat_messages, ChatMessageTable, +}; +use flowy_chat_pub::cloud::{ + ChatAuthorType, ChatCloudService, ChatMessage, ChatMessageType, MessageCursor, +}; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sqlite::DBConnection; +use futures::StreamExt; +use std::sync::atomic::AtomicI64; +use std::sync::Arc; +use tokio::sync::RwLock; +use tracing::{error, instrument, trace}; + +enum PrevMessageState { + HasMore, + NoMore, + Loading, +} + +pub struct Chat { + chat_id: String, + uid: i64, + user_service: Arc<dyn ChatUserService>, + cloud_service: Arc<dyn ChatCloudService>, + prev_message_state: Arc<RwLock<PrevMessageState>>, + latest_message_id: Arc<AtomicI64>, +} + +impl Chat { + pub fn new( + uid: i64, + chat_id: String, + user_service: Arc<dyn ChatUserService>, + cloud_service: Arc<dyn ChatCloudService>, + ) -> Chat { + Chat { + uid, + chat_id, + cloud_service, + user_service, + prev_message_state: Arc::new(RwLock::new(PrevMessageState::HasMore)), + latest_message_id: Default::default(), + } + } + + pub fn close(&self) {} + + #[allow(dead_code)] + pub async fn pull_latest_message(&self, limit: i64) { + let latest_message_id = self + .latest_message_id + .load(std::sync::atomic::Ordering::Relaxed); + if latest_message_id > 0 { + let _ = self + .load_remote_chat_messages(limit, None, Some(latest_message_id)) + .await; + } + } + + #[instrument(level = "info", skip_all, err)] + pub async fn send_chat_message( + &self, + message: &str, + message_type: ChatMessageType, + ) -> Result<(), FlowyError> { + if message.len() > 2000 { + return Err(FlowyError::text_too_long().with_context("Exceeds maximum message 2000 length")); + } + + let uid = self.user_service.user_id()?; + let workspace_id = self.user_service.workspace_id()?; + stream_send_chat_messages( + uid, + workspace_id, + self.chat_id.clone(), + message.to_string(), + message_type, + self.cloud_service.clone(), + self.user_service.clone(), + ); + + Ok(()) + } + + /// Load chat messages for a given `chat_id`. + /// + /// 1. When opening a chat: + /// - Loads local chat messages. + /// - `after_message_id` and `before_message_id` are `None`. + /// - Spawns a task to load messages from the remote server, notifying the user when the remote messages are loaded. + /// + /// 2. Loading more messages in an existing chat with `after_message_id`: + /// - `after_message_id` is the last message ID in the current chat messages. + /// + /// 3. Loading more messages in an existing chat with `before_message_id`: + /// - `before_message_id` is the first message ID in the current chat messages. + pub async fn load_prev_chat_messages( + &self, + limit: i64, + before_message_id: Option<i64>, + ) -> Result<ChatMessageListPB, FlowyError> { + trace!( + "Loading old messages: chat_id={}, limit={}, before_message_id={:?}", + self.chat_id, + limit, + before_message_id + ); + let messages = self + .load_local_chat_messages(limit, None, before_message_id) + .await?; + + // If the number of messages equals the limit, then no need to load more messages from remote + let has_more = !messages.is_empty(); + if messages.len() == limit as usize { + return Ok(ChatMessageListPB { + messages, + has_more, + total: 0, + }); + } + + if matches!( + *self.prev_message_state.read().await, + PrevMessageState::HasMore + ) { + *self.prev_message_state.write().await = PrevMessageState::Loading; + if let Err(err) = self + .load_remote_chat_messages(limit, before_message_id, None) + .await + { + error!("Failed to load previous chat messages: {}", err); + } + } + + Ok(ChatMessageListPB { + messages, + has_more, + total: 0, + }) + } + + pub async fn load_latest_chat_messages( + &self, + limit: i64, + after_message_id: Option<i64>, + ) -> Result<ChatMessageListPB, FlowyError> { + trace!( + "Loading new messages: chat_id={}, limit={}, after_message_id={:?}", + self.chat_id, + limit, + after_message_id, + ); + let messages = self + .load_local_chat_messages(limit, after_message_id, None) + .await?; + + trace!( + "Loaded local chat messages: chat_id={}, messages={}", + self.chat_id, + messages.len() + ); + + // If the number of messages equals the limit, then no need to load more messages from remote + let has_more = !messages.is_empty(); + let _ = self + .load_remote_chat_messages(limit, None, after_message_id) + .await; + Ok(ChatMessageListPB { + messages, + has_more, + total: 0, + }) + } + + async fn load_remote_chat_messages( + &self, + limit: i64, + before_message_id: Option<i64>, + after_message_id: Option<i64>, + ) -> FlowyResult<()> { + trace!( + "Loading chat messages from remote: chat_id={}, limit={}, before_message_id={:?}, after_message_id={:?}", + self.chat_id, + limit, + before_message_id, + after_message_id + ); + let workspace_id = self.user_service.workspace_id()?; + let chat_id = self.chat_id.clone(); + let cloud_service = self.cloud_service.clone(); + let user_service = self.user_service.clone(); + let uid = self.uid; + let prev_message_state = self.prev_message_state.clone(); + let latest_message_id = self.latest_message_id.clone(); + tokio::spawn(async move { + let cursor = match (before_message_id, after_message_id) { + (Some(bid), _) => MessageCursor::BeforeMessageId(bid), + (_, Some(aid)) => MessageCursor::AfterMessageId(aid), + _ => MessageCursor::NextBack, + }; + match cloud_service + .get_chat_messages(&workspace_id, &chat_id, cursor.clone(), limit as u64) + .await + { + Ok(resp) => { + // Save chat messages to local disk + if let Err(err) = save_chat_message( + user_service.sqlite_connection(uid)?, + &chat_id, + resp.messages.clone(), + ) { + error!("Failed to save chat:{} messages: {}", chat_id, err); + } + + // Update latest message ID + if !resp.messages.is_empty() { + latest_message_id.store( + resp.messages[0].message_id, + std::sync::atomic::Ordering::Relaxed, + ); + } + + let pb = ChatMessageListPB::from(resp); + trace!( + "Loaded chat messages from remote: chat_id={}, messages={}", + chat_id, + pb.messages.len() + ); + if matches!(cursor, MessageCursor::BeforeMessageId(_)) { + if pb.has_more { + *prev_message_state.write().await = PrevMessageState::HasMore; + } else { + *prev_message_state.write().await = PrevMessageState::NoMore; + } + send_notification(&chat_id, ChatNotification::DidLoadPrevChatMessage) + .payload(pb) + .send(); + } else { + send_notification(&chat_id, ChatNotification::DidLoadLatestChatMessage) + .payload(pb) + .send(); + } + }, + Err(err) => error!("Failed to load chat messages: {}", err), + } + Ok::<(), FlowyError>(()) + }); + Ok(()) + } + + pub async fn get_related_question( + &self, + message_id: i64, + ) -> Result<RepeatedRelatedQuestionPB, FlowyError> { + let workspace_id = self.user_service.workspace_id()?; + let resp = self + .cloud_service + .get_related_message(&workspace_id, &self.chat_id, message_id) + .await?; + + trace!( + "Related messages: chat_id={}, message_id={}, messages:{:?}", + self.chat_id, + message_id, + resp.items + ); + Ok(RepeatedRelatedQuestionPB::from(resp)) + } + + #[instrument(level = "debug", skip_all, err)] + pub async fn generate_answer(&self, question_message_id: i64) -> FlowyResult<ChatMessagePB> { + let workspace_id = self.user_service.workspace_id()?; + let resp = self + .cloud_service + .generate_answer(&workspace_id, &self.chat_id, question_message_id) + .await?; + + save_answer( + self.user_service.sqlite_connection(self.uid)?, + &self.chat_id, + resp.clone(), + question_message_id, + )?; + + let pb = ChatMessagePB::from(resp); + Ok(pb) + } + + async fn load_local_chat_messages( + &self, + limit: i64, + after_message_id: Option<i64>, + before_message_id: Option<i64>, + ) -> Result<Vec<ChatMessagePB>, FlowyError> { + let conn = self.user_service.sqlite_connection(self.uid)?; + let records = select_chat_messages( + conn, + &self.chat_id, + limit, + after_message_id, + before_message_id, + )?; + let messages = records + .into_iter() + .map(|record| ChatMessagePB { + message_id: record.message_id, + content: record.content, + created_at: record.created_at, + author_type: record.author_type, + author_id: record.author_id, + has_following: false, + reply_message_id: record.reply_message_id, + }) + .collect::<Vec<_>>(); + + Ok(messages) + } +} + +fn stream_send_chat_messages( + uid: i64, + workspace_id: String, + chat_id: String, + message_content: String, + message_type: ChatMessageType, + cloud_service: Arc<dyn ChatCloudService>, + user_service: Arc<dyn ChatUserService>, +) { + tokio::spawn(async move { + trace!( + "Sending chat message: chat_id={}, message={}, type={:?}", + chat_id, + message_content, + message_type + ); + + let mut messages = Vec::with_capacity(2); + let stream_result = cloud_service + .send_chat_message(&workspace_id, &chat_id, &message_content, message_type) + .await; + + // By default, stream only returns two messages: + // 1. user message + // 2. ai response message + match stream_result { + Ok(mut stream) => { + while let Some(result) = stream.next().await { + match result { + Ok(message) => { + let mut pb = ChatMessagePB::from(message.clone()); + if matches!(message.author.author_type, ChatAuthorType::Human) { + pb.has_following = true; + send_notification(&chat_id, ChatNotification::LastUserSentMessage) + .payload(pb.clone()) + .send(); + } + + // + send_notification(&chat_id, ChatNotification::DidReceiveChatMessage) + .payload(pb) + .send(); + messages.push(message); + }, + Err(err) => { + error!("Failed to send chat message: {}", err); + let pb = ChatMessageErrorPB { + chat_id: chat_id.clone(), + content: message_content.clone(), + error_message: "Service Temporarily Unavailable".to_string(), + }; + send_notification(&chat_id, ChatNotification::StreamChatMessageError) + .payload(pb) + .send(); + break; + }, + } + } + }, + Err(err) => { + error!("Failed to send chat message: {}", err); + let pb = ChatMessageErrorPB { + chat_id: chat_id.clone(), + content: message_content.clone(), + error_message: err.to_string(), + }; + send_notification(&chat_id, ChatNotification::StreamChatMessageError) + .payload(pb) + .send(); + return; + }, + } + + if messages.is_empty() { + return; + } + + trace!( + "Saving chat messages to local disk: chat_id={}, messages:{:?}", + chat_id, + messages + ); + + // Insert chat messages to local disk + if let Err(err) = user_service.sqlite_connection(uid).and_then(|conn| { + let records = messages + .into_iter() + .map(|message| ChatMessageTable { + message_id: message.message_id, + chat_id: chat_id.clone(), + content: message.content, + created_at: message.created_at.timestamp(), + author_type: message.author.author_type as i64, + author_id: message.author.author_id.to_string(), + reply_message_id: message.reply_message_id, + }) + .collect::<Vec<_>>(); + insert_chat_messages(conn, &records)?; + + // Mark chat as finished + send_notification(&chat_id, ChatNotification::FinishAnswerQuestion).send(); + Ok(()) + }) { + error!("Failed to save chat messages: {}", err); + } + }); +} + +fn save_chat_message( + conn: DBConnection, + chat_id: &str, + messages: Vec<ChatMessage>, +) -> FlowyResult<()> { + let records = messages + .into_iter() + .map(|message| ChatMessageTable { + message_id: message.message_id, + chat_id: chat_id.to_string(), + content: message.content, + created_at: message.created_at.timestamp(), + author_type: message.author.author_type as i64, + author_id: message.author.author_id.to_string(), + reply_message_id: message.reply_message_id, + }) + .collect::<Vec<_>>(); + insert_chat_messages(conn, &records)?; + Ok(()) +} +fn save_answer( + conn: DBConnection, + chat_id: &str, + message: ChatMessage, + question_message_id: i64, +) -> FlowyResult<()> { + let record = ChatMessageTable { + message_id: message.message_id, + chat_id: chat_id.to_string(), + content: message.content, + created_at: message.created_at.timestamp(), + author_type: message.author.author_type as i64, + author_id: message.author.author_id.to_string(), + reply_message_id: message.reply_message_id, + }; + insert_answer_message(conn, question_message_id, record)?; + Ok(()) +} diff --git a/frontend/rust-lib/flowy-chat/src/entities.rs b/frontend/rust-lib/flowy-chat/src/entities.rs new file mode 100644 index 0000000000..e01c2aaad1 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/entities.rs @@ -0,0 +1,190 @@ +use flowy_chat_pub::cloud::{ + ChatMessage, RelatedQuestion, RepeatedChatMessage, RepeatedRelatedQuestion, +}; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use lib_infra::validator_fn::required_not_empty_str; +use validator::Validate; + +#[derive(Default, ProtoBuf, Validate, Clone, Debug)] +pub struct SendChatPayloadPB { + #[pb(index = 1)] + #[validate(custom = "required_not_empty_str")] + pub chat_id: String, + + #[pb(index = 2)] + #[validate(custom = "required_not_empty_str")] + pub message: String, + + #[pb(index = 3)] + pub message_type: ChatMessageTypePB, +} + +#[derive(Debug, Default, Clone, ProtoBuf_Enum, PartialEq, Eq, Copy)] +pub enum ChatMessageTypePB { + #[default] + System = 0, + User = 1, +} + +#[derive(Default, ProtoBuf, Validate, Clone, Debug)] +pub struct LoadPrevChatMessagePB { + #[pb(index = 1)] + #[validate(custom = "required_not_empty_str")] + pub chat_id: String, + + #[pb(index = 2)] + pub limit: i64, + + #[pb(index = 4, one_of)] + pub before_message_id: Option<i64>, +} + +#[derive(Default, ProtoBuf, Validate, Clone, Debug)] +pub struct LoadNextChatMessagePB { + #[pb(index = 1)] + #[validate(custom = "required_not_empty_str")] + pub chat_id: String, + + #[pb(index = 2)] + pub limit: i64, + + #[pb(index = 4, one_of)] + pub after_message_id: Option<i64>, +} + +#[derive(Default, ProtoBuf, Validate, Clone, Debug)] +pub struct ChatMessageListPB { + #[pb(index = 1)] + pub has_more: bool, + + #[pb(index = 2)] + pub messages: Vec<ChatMessagePB>, + + /// If the total number of messages is 0, then the total number of messages is unknown. + #[pb(index = 3)] + pub total: i64, +} + +impl From<RepeatedChatMessage> for ChatMessageListPB { + fn from(repeated_chat_message: RepeatedChatMessage) -> Self { + let messages = repeated_chat_message + .messages + .into_iter() + .map(ChatMessagePB::from) + .collect(); + ChatMessageListPB { + has_more: repeated_chat_message.has_more, + messages, + total: repeated_chat_message.total, + } + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct ChatMessagePB { + #[pb(index = 1)] + pub message_id: i64, + + #[pb(index = 2)] + pub content: String, + + #[pb(index = 3)] + pub created_at: i64, + + #[pb(index = 4)] + pub author_type: i64, + + #[pb(index = 5)] + pub author_id: String, + + #[pb(index = 6)] + pub has_following: bool, + + #[pb(index = 7, one_of)] + pub reply_message_id: Option<i64>, +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct ChatMessageErrorPB { + #[pb(index = 1)] + pub chat_id: String, + + #[pb(index = 2)] + pub content: String, + + #[pb(index = 3)] + pub error_message: String, +} + +impl From<ChatMessage> for ChatMessagePB { + fn from(chat_message: ChatMessage) -> Self { + ChatMessagePB { + message_id: chat_message.message_id, + content: chat_message.content, + created_at: chat_message.created_at.timestamp(), + author_type: chat_message.author.author_type as i64, + author_id: chat_message.author.author_id.to_string(), + has_following: false, + reply_message_id: None, + } + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct RepeatedChatMessagePB { + #[pb(index = 1)] + items: Vec<ChatMessagePB>, +} + +impl From<Vec<ChatMessage>> for RepeatedChatMessagePB { + fn from(messages: Vec<ChatMessage>) -> Self { + RepeatedChatMessagePB { + items: messages.into_iter().map(ChatMessagePB::from).collect(), + } + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct ChatMessageIdPB { + #[pb(index = 1)] + pub chat_id: String, + + #[pb(index = 2)] + pub message_id: i64, +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct RelatedQuestionPB { + #[pb(index = 1)] + pub content: String, +} + +impl From<RelatedQuestion> for RelatedQuestionPB { + fn from(value: RelatedQuestion) -> Self { + RelatedQuestionPB { + content: value.content, + } + } +} + +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct RepeatedRelatedQuestionPB { + #[pb(index = 1)] + pub message_id: i64, + + #[pb(index = 2)] + pub items: Vec<RelatedQuestionPB>, +} + +impl From<RepeatedRelatedQuestion> for RepeatedRelatedQuestionPB { + fn from(value: RepeatedRelatedQuestion) -> Self { + RepeatedRelatedQuestionPB { + message_id: value.message_id, + items: value + .items + .into_iter() + .map(RelatedQuestionPB::from) + .collect(), + } + } +} diff --git a/frontend/rust-lib/flowy-chat/src/event_handler.rs b/frontend/rust-lib/flowy-chat/src/event_handler.rs new file mode 100644 index 0000000000..959c0398b4 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/event_handler.rs @@ -0,0 +1,93 @@ +use flowy_chat_pub::cloud::ChatMessageType; +use std::sync::{Arc, Weak}; +use validator::Validate; + +use flowy_error::{FlowyError, FlowyResult}; +use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; + +use crate::entities::*; +use crate::manager::ChatManager; + +fn upgrade_chat_manager( + chat_manager: AFPluginState<Weak<ChatManager>>, +) -> FlowyResult<Arc<ChatManager>> { + let chat_manager = chat_manager + .upgrade() + .ok_or(FlowyError::internal().with_context("The chat manager is already dropped"))?; + Ok(chat_manager) +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn send_chat_message_handler( + data: AFPluginData<SendChatPayloadPB>, + chat_manager: AFPluginState<Weak<ChatManager>>, +) -> Result<(), FlowyError> { + let chat_manager = upgrade_chat_manager(chat_manager)?; + let data = data.into_inner(); + data.validate()?; + + let message_type = match data.message_type { + ChatMessageTypePB::System => ChatMessageType::System, + ChatMessageTypePB::User => ChatMessageType::User, + }; + chat_manager + .send_chat_message(&data.chat_id, &data.message, message_type) + .await?; + Ok(()) +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn load_prev_message_handler( + data: AFPluginData<LoadPrevChatMessagePB>, + chat_manager: AFPluginState<Weak<ChatManager>>, +) -> DataResult<ChatMessageListPB, FlowyError> { + let chat_manager = upgrade_chat_manager(chat_manager)?; + let data = data.into_inner(); + data.validate()?; + + let messages = chat_manager + .load_prev_chat_messages(&data.chat_id, data.limit, data.before_message_id) + .await?; + data_result_ok(messages) +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn load_next_message_handler( + data: AFPluginData<LoadNextChatMessagePB>, + chat_manager: AFPluginState<Weak<ChatManager>>, +) -> DataResult<ChatMessageListPB, FlowyError> { + let chat_manager = upgrade_chat_manager(chat_manager)?; + let data = data.into_inner(); + data.validate()?; + + let messages = chat_manager + .load_latest_chat_messages(&data.chat_id, data.limit, data.after_message_id) + .await?; + data_result_ok(messages) +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn get_related_question_handler( + data: AFPluginData<ChatMessageIdPB>, + chat_manager: AFPluginState<Weak<ChatManager>>, +) -> DataResult<RepeatedRelatedQuestionPB, FlowyError> { + let chat_manager = upgrade_chat_manager(chat_manager)?; + let data = data.into_inner(); + let messages = chat_manager + .get_related_questions(&data.chat_id, data.message_id) + .await?; + data_result_ok(messages) +} + +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn get_answer_handler( + data: AFPluginData<ChatMessageIdPB>, + chat_manager: AFPluginState<Weak<ChatManager>>, +) -> DataResult<ChatMessagePB, FlowyError> { + let chat_manager = upgrade_chat_manager(chat_manager)?; + let data = data.into_inner(); + let message = chat_manager + .generate_answer(&data.chat_id, data.message_id) + .await?; + data_result_ok(message) +} diff --git a/frontend/rust-lib/flowy-chat/src/event_map.rs b/frontend/rust-lib/flowy-chat/src/event_map.rs new file mode 100644 index 0000000000..9fae853459 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/event_map.rs @@ -0,0 +1,40 @@ +use std::sync::Weak; + +use strum_macros::Display; + +use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; +use lib_dispatch::prelude::*; + +use crate::event_handler::*; +use crate::manager::ChatManager; + +pub fn init(chat_manager: Weak<ChatManager>) -> AFPlugin { + AFPlugin::new() + .name("Flowy-Chat") + .state(chat_manager) + .event(ChatEvent::SendMessage, send_chat_message_handler) + .event(ChatEvent::LoadPrevMessage, load_prev_message_handler) + .event(ChatEvent::LoadNextMessage, load_next_message_handler) + .event(ChatEvent::GetRelatedQuestion, get_related_question_handler) + .event(ChatEvent::GetAnswerForQuestion, get_answer_handler) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] +#[event_err = "FlowyError"] +pub enum ChatEvent { + /// Create a new workspace + #[event(input = "LoadPrevChatMessagePB", output = "ChatMessageListPB")] + LoadPrevMessage = 0, + + #[event(input = "LoadNextChatMessagePB", output = "ChatMessageListPB")] + LoadNextMessage = 1, + + #[event(input = "SendChatPayloadPB")] + SendMessage = 2, + + #[event(input = "ChatMessageIdPB", output = "RepeatedRelatedQuestionPB")] + GetRelatedQuestion = 3, + + #[event(input = "ChatMessageIdPB", output = "ChatMessagePB")] + GetAnswerForQuestion = 4, +} diff --git a/frontend/rust-lib/flowy-chat/src/lib.rs b/frontend/rust-lib/flowy-chat/src/lib.rs new file mode 100644 index 0000000000..2244af5802 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/lib.rs @@ -0,0 +1,9 @@ +mod event_handler; +pub mod event_map; + +mod chat; +pub mod entities; +pub mod manager; +pub mod notification; +mod persistence; +mod protobuf; diff --git a/frontend/rust-lib/flowy-chat/src/manager.rs b/frontend/rust-lib/flowy-chat/src/manager.rs new file mode 100644 index 0000000000..b2cc679eb2 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/manager.rs @@ -0,0 +1,182 @@ +use crate::chat::Chat; +use crate::entities::{ChatMessageListPB, ChatMessagePB, RepeatedRelatedQuestionPB}; +use crate::persistence::{insert_chat, ChatTable}; +use dashmap::DashMap; +use flowy_chat_pub::cloud::{ChatCloudService, ChatMessageType}; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sqlite::DBConnection; +use lib_infra::util::timestamp; +use std::sync::Arc; +use tracing::{instrument, trace}; + +pub trait ChatUserService: Send + Sync + 'static { + fn user_id(&self) -> Result<i64, FlowyError>; + fn device_id(&self) -> Result<String, FlowyError>; + fn workspace_id(&self) -> Result<String, FlowyError>; + fn sqlite_connection(&self, uid: i64) -> Result<DBConnection, FlowyError>; +} + +pub struct ChatManager { + cloud_service: Arc<dyn ChatCloudService>, + user_service: Arc<dyn ChatUserService>, + chats: Arc<DashMap<String, Arc<Chat>>>, +} + +impl ChatManager { + pub fn new( + cloud_service: Arc<dyn ChatCloudService>, + user_service: impl ChatUserService, + ) -> ChatManager { + let user_service = Arc::new(user_service); + + Self { + cloud_service, + user_service, + chats: Arc::new(DashMap::new()), + } + } + + pub async fn open_chat(&self, chat_id: &str) -> Result<(), FlowyError> { + trace!("open chat: {}", chat_id); + self.chats.entry(chat_id.to_string()).or_insert_with(|| { + Arc::new(Chat::new( + self.user_service.user_id().unwrap(), + chat_id.to_string(), + self.user_service.clone(), + self.cloud_service.clone(), + )) + }); + + Ok(()) + } + + pub async fn close_chat(&self, _chat_id: &str) -> Result<(), FlowyError> { + Ok(()) + } + + pub async fn delete_chat(&self, chat_id: &str) -> Result<(), FlowyError> { + if let Some((_, chat)) = self.chats.remove(chat_id) { + chat.close(); + } + Ok(()) + } + + pub async fn create_chat(&self, uid: &i64, chat_id: &str) -> Result<Arc<Chat>, FlowyError> { + let workspace_id = self.user_service.workspace_id()?; + self + .cloud_service + .create_chat(uid, &workspace_id, chat_id) + .await?; + save_chat(self.user_service.sqlite_connection(*uid)?, chat_id)?; + + let chat = Arc::new(Chat::new( + self.user_service.user_id().unwrap(), + chat_id.to_string(), + self.user_service.clone(), + self.cloud_service.clone(), + )); + self.chats.insert(chat_id.to_string(), chat.clone()); + Ok(chat) + } + + #[instrument(level = "info", skip_all, err)] + pub async fn send_chat_message( + &self, + chat_id: &str, + message: &str, + message_type: ChatMessageType, + ) -> Result<(), FlowyError> { + let chat = self.get_or_create_chat_instance(chat_id).await?; + chat.send_chat_message(message, message_type).await?; + Ok(()) + } + + pub async fn get_or_create_chat_instance(&self, chat_id: &str) -> Result<Arc<Chat>, FlowyError> { + let chat = self.chats.get(chat_id).as_deref().cloned(); + match chat { + None => { + let chat = Arc::new(Chat::new( + self.user_service.user_id().unwrap(), + chat_id.to_string(), + self.user_service.clone(), + self.cloud_service.clone(), + )); + self.chats.insert(chat_id.to_string(), chat.clone()); + Ok(chat) + }, + Some(chat) => Ok(chat), + } + } + + /// Load chat messages for a given `chat_id`. + /// + /// 1. When opening a chat: + /// - Loads local chat messages. + /// - `after_message_id` and `before_message_id` are `None`. + /// - Spawns a task to load messages from the remote server, notifying the user when the remote messages are loaded. + /// + /// 2. Loading more messages in an existing chat with `after_message_id`: + /// - `after_message_id` is the last message ID in the current chat messages. + /// + /// 3. Loading more messages in an existing chat with `before_message_id`: + /// - `before_message_id` is the first message ID in the current chat messages. + /// + /// 4. `after_message_id` and `before_message_id` cannot be specified at the same time. + + pub async fn load_prev_chat_messages( + &self, + chat_id: &str, + limit: i64, + before_message_id: Option<i64>, + ) -> Result<ChatMessageListPB, FlowyError> { + let chat = self.get_or_create_chat_instance(chat_id).await?; + let list = chat + .load_prev_chat_messages(limit, before_message_id) + .await?; + Ok(list) + } + + pub async fn load_latest_chat_messages( + &self, + chat_id: &str, + limit: i64, + after_message_id: Option<i64>, + ) -> Result<ChatMessageListPB, FlowyError> { + let chat = self.get_or_create_chat_instance(chat_id).await?; + let list = chat + .load_latest_chat_messages(limit, after_message_id) + .await?; + Ok(list) + } + + pub async fn get_related_questions( + &self, + chat_id: &str, + message_id: i64, + ) -> Result<RepeatedRelatedQuestionPB, FlowyError> { + let chat = self.get_or_create_chat_instance(chat_id).await?; + let resp = chat.get_related_question(message_id).await?; + Ok(resp) + } + + pub async fn generate_answer( + &self, + chat_id: &str, + question_message_id: i64, + ) -> Result<ChatMessagePB, FlowyError> { + let chat = self.get_or_create_chat_instance(chat_id).await?; + let resp = chat.generate_answer(question_message_id).await?; + Ok(resp) + } +} + +fn save_chat(conn: DBConnection, chat_id: &str) -> FlowyResult<()> { + let row = ChatTable { + chat_id: chat_id.to_string(), + created_at: timestamp(), + name: "".to_string(), + }; + + insert_chat(conn, &row)?; + Ok(()) +} diff --git a/frontend/rust-lib/flowy-chat/src/notification.rs b/frontend/rust-lib/flowy-chat/src/notification.rs new file mode 100644 index 0000000000..830c464a72 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/notification.rs @@ -0,0 +1,40 @@ +use flowy_derive::ProtoBuf_Enum; +use flowy_notification::NotificationBuilder; + +const CHAT_OBSERVABLE_SOURCE: &str = "Chat"; + +#[derive(ProtoBuf_Enum, Debug, Default)] +pub enum ChatNotification { + #[default] + Unknown = 0, + DidLoadLatestChatMessage = 1, + DidLoadPrevChatMessage = 2, + DidReceiveChatMessage = 3, + StreamChatMessageError = 4, + FinishAnswerQuestion = 5, + LastUserSentMessage = 6, +} + +impl std::convert::From<ChatNotification> for i32 { + fn from(notification: ChatNotification) -> Self { + notification as i32 + } +} +impl std::convert::From<i32> for ChatNotification { + fn from(notification: i32) -> Self { + match notification { + 1 => ChatNotification::DidLoadLatestChatMessage, + 2 => ChatNotification::DidLoadPrevChatMessage, + 3 => ChatNotification::DidReceiveChatMessage, + 4 => ChatNotification::StreamChatMessageError, + 5 => ChatNotification::FinishAnswerQuestion, + 6 => ChatNotification::LastUserSentMessage, + _ => ChatNotification::Unknown, + } + } +} + +#[tracing::instrument(level = "trace")] +pub(crate) fn send_notification(id: &str, ty: ChatNotification) -> NotificationBuilder { + NotificationBuilder::new(id, ty, CHAT_OBSERVABLE_SOURCE) +} diff --git a/frontend/rust-lib/flowy-chat/src/persistence/chat_message_sql.rs b/frontend/rust-lib/flowy-chat/src/persistence/chat_message_sql.rs new file mode 100644 index 0000000000..3e65123c27 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/persistence/chat_message_sql.rs @@ -0,0 +1,106 @@ +use flowy_error::{FlowyError, FlowyResult}; +use flowy_sqlite::upsert::excluded; +use flowy_sqlite::{ + diesel, insert_into, + query_dsl::*, + schema::{chat_message_table, chat_message_table::dsl}, + DBConnection, ExpressionMethods, Identifiable, Insertable, QueryResult, Queryable, +}; + +#[derive(Queryable, Insertable, Identifiable)] +#[diesel(table_name = chat_message_table)] +#[diesel(primary_key(message_id))] +pub struct ChatMessageTable { + pub message_id: i64, + pub chat_id: String, + pub content: String, + pub created_at: i64, + pub author_type: i64, + pub author_id: String, + pub reply_message_id: Option<i64>, +} + +pub fn insert_chat_messages( + mut conn: DBConnection, + new_messages: &[ChatMessageTable], +) -> FlowyResult<()> { + conn.immediate_transaction(|conn| { + for message in new_messages { + let _ = insert_into(chat_message_table::table) + .values(message) + .on_conflict(chat_message_table::message_id) + .do_update() + .set(( + chat_message_table::content.eq(excluded(chat_message_table::content)), + chat_message_table::created_at.eq(excluded(chat_message_table::created_at)), + chat_message_table::author_type.eq(excluded(chat_message_table::author_type)), + chat_message_table::author_id.eq(excluded(chat_message_table::author_id)), + chat_message_table::reply_message_id.eq(excluded(chat_message_table::reply_message_id)), + )) + .execute(conn)?; + } + Ok::<(), FlowyError>(()) + })?; + + Ok(()) +} + +pub fn insert_answer_message( + mut conn: DBConnection, + question_message_id: i64, + message: ChatMessageTable, +) -> FlowyResult<()> { + conn.immediate_transaction(|conn| { + // Step 1: Get the message with the given question_message_id + let question_message = dsl::chat_message_table + .filter(chat_message_table::message_id.eq(question_message_id)) + .first::<ChatMessageTable>(conn)?; + + // Step 2: Use reply_message_id from the retrieved message to delete the existing message + if let Some(reply_id) = question_message.reply_message_id { + diesel::delete(dsl::chat_message_table.filter(chat_message_table::message_id.eq(reply_id))) + .execute(conn)?; + } + + // Step 3: Insert the new message + let _ = insert_into(chat_message_table::table) + .values(message) + .on_conflict(chat_message_table::message_id) + .do_update() + .set(( + chat_message_table::content.eq(excluded(chat_message_table::content)), + chat_message_table::created_at.eq(excluded(chat_message_table::created_at)), + chat_message_table::author_type.eq(excluded(chat_message_table::author_type)), + chat_message_table::author_id.eq(excluded(chat_message_table::author_id)), + chat_message_table::reply_message_id.eq(excluded(chat_message_table::reply_message_id)), + )) + .execute(conn)?; + Ok::<(), FlowyError>(()) + })?; + + Ok(()) +} +pub fn select_chat_messages( + mut conn: DBConnection, + chat_id_val: &str, + limit_val: i64, + after_message_id: Option<i64>, + before_message_id: Option<i64>, +) -> QueryResult<Vec<ChatMessageTable>> { + let mut query = dsl::chat_message_table + .filter(chat_message_table::chat_id.eq(chat_id_val)) + .into_boxed(); + if let Some(after_message_id) = after_message_id { + query = query.filter(chat_message_table::message_id.gt(after_message_id)); + } + + if let Some(before_message_id) = before_message_id { + query = query.filter(chat_message_table::message_id.lt(before_message_id)); + } + query = query + .order((chat_message_table::message_id.desc(),)) + .limit(limit_val); + + let messages: Vec<ChatMessageTable> = query.load::<ChatMessageTable>(&mut *conn)?; + Ok(messages) +} diff --git a/frontend/rust-lib/flowy-chat/src/persistence/chat_sql.rs b/frontend/rust-lib/flowy-chat/src/persistence/chat_sql.rs new file mode 100644 index 0000000000..1fd0480c54 --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/persistence/chat_sql.rs @@ -0,0 +1,52 @@ +use flowy_sqlite::upsert::excluded; +use flowy_sqlite::{ + diesel, + query_dsl::*, + schema::{chat_table, chat_table::dsl}, + DBConnection, ExpressionMethods, Identifiable, Insertable, QueryResult, Queryable, +}; + +#[derive(Clone, Default, Queryable, Insertable, Identifiable)] +#[diesel(table_name = chat_table)] +#[diesel(primary_key(chat_id))] +pub struct ChatTable { + pub chat_id: String, + pub created_at: i64, + pub name: String, +} + +pub fn insert_chat(mut conn: DBConnection, new_chat: &ChatTable) -> QueryResult<usize> { + diesel::insert_into(chat_table::table) + .values(new_chat) + .on_conflict(chat_table::chat_id) + .do_update() + .set(( + chat_table::created_at.eq(excluded(chat_table::created_at)), + chat_table::name.eq(excluded(chat_table::name)), + )) + .execute(&mut *conn) +} + +#[allow(dead_code)] +pub fn read_chat(mut conn: DBConnection, chat_id_val: &str) -> QueryResult<ChatTable> { + let row = dsl::chat_table + .filter(chat_table::chat_id.eq(chat_id_val)) + .first::<ChatTable>(&mut *conn)?; + Ok(row) +} + +#[allow(dead_code)] +pub fn update_chat_name( + mut conn: DBConnection, + chat_id_val: &str, + new_name: &str, +) -> QueryResult<usize> { + diesel::update(dsl::chat_table.filter(chat_table::chat_id.eq(chat_id_val))) + .set(chat_table::name.eq(new_name)) + .execute(&mut *conn) +} + +#[allow(dead_code)] +pub fn delete_chat(mut conn: DBConnection, chat_id_val: &str) -> QueryResult<usize> { + diesel::delete(dsl::chat_table.filter(chat_table::chat_id.eq(chat_id_val))).execute(&mut *conn) +} diff --git a/frontend/rust-lib/flowy-chat/src/persistence/mod.rs b/frontend/rust-lib/flowy-chat/src/persistence/mod.rs new file mode 100644 index 0000000000..b21eb507ae --- /dev/null +++ b/frontend/rust-lib/flowy-chat/src/persistence/mod.rs @@ -0,0 +1,5 @@ +mod chat_message_sql; +mod chat_sql; + +pub use chat_message_sql::*; +pub use chat_sql::*; diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index 289b4751b0..0e5687ce2e 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -31,6 +31,8 @@ diesel.workspace = true uuid.workspace = true flowy-storage = { workspace = true } client-api.workspace = true +flowy-chat = { workspace = true } +flowy-chat-pub = { workspace = true } tracing.workspace = true futures-core = { version = "0.3", default-features = false } @@ -61,6 +63,7 @@ dart = [ "flowy-search/dart", "flowy-folder/dart", "flowy-database2/dart", + "flowy-chat/dart", ] ts = [ "flowy-user/tauri_ts", @@ -68,6 +71,7 @@ ts = [ "flowy-search/tauri_ts", "flowy-database2/ts", "flowy-config/tauri_ts", + "flowy-chat/tauri_ts", ] openssl_vendored = ["flowy-sqlite/openssl_vendored"] diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs new file mode 100644 index 0000000000..9ba1604182 --- /dev/null +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/chat_deps.rs @@ -0,0 +1,47 @@ +use flowy_chat::manager::{ChatManager, ChatUserService}; +use flowy_chat_pub::cloud::ChatCloudService; +use flowy_error::FlowyError; +use flowy_sqlite::DBConnection; +use flowy_user::services::authenticate_user::AuthenticateUser; +use std::sync::{Arc, Weak}; + +pub struct ChatDepsResolver; + +impl ChatDepsResolver { + pub fn resolve( + authenticate_user: Weak<AuthenticateUser>, + cloud_service: Arc<dyn ChatCloudService>, + ) -> Arc<ChatManager> { + let user_service = ChatUserServiceImpl(authenticate_user); + Arc::new(ChatManager::new(cloud_service, user_service)) + } +} + +struct ChatUserServiceImpl(Weak<AuthenticateUser>); +impl ChatUserServiceImpl { + fn upgrade_user(&self) -> Result<Arc<AuthenticateUser>, FlowyError> { + let user = self + .0 + .upgrade() + .ok_or(FlowyError::internal().with_context("Unexpected error: UserSession is None"))?; + Ok(user) + } +} + +impl ChatUserService for ChatUserServiceImpl { + fn user_id(&self) -> Result<i64, FlowyError> { + self.upgrade_user()?.user_id() + } + + fn device_id(&self) -> Result<String, FlowyError> { + self.upgrade_user()?.device_id() + } + + fn workspace_id(&self) -> Result<String, FlowyError> { + self.upgrade_user()?.workspace_id() + } + + fn sqlite_connection(&self, uid: i64) -> Result<DBConnection, FlowyError> { + self.upgrade_user()?.get_sqlite_connection(uid) + } +} diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 1a9fd4160e..92e09996d5 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -1,6 +1,7 @@ use bytes::Bytes; use collab_integrate::collab_builder::AppFlowyCollabBuilder; use collab_integrate::CollabKVDB; +use flowy_chat::manager::ChatManager; use flowy_database2::entities::DatabaseLayoutPB; use flowy_database2::services::share::csv::CSVFormat; use flowy_database2::template::{make_default_board, make_default_calendar, make_default_grid}; @@ -9,10 +10,11 @@ use flowy_document::entities::DocumentDataPB; use flowy_document::manager::DocumentManager; use flowy_document::parser::json::parser::JsonToDocumentParser; use flowy_error::FlowyError; -use flowy_folder::entities::ViewLayoutPB; use flowy_folder::manager::{FolderManager, FolderUser}; use flowy_folder::share::ImportType; -use flowy_folder::view_operation::{FolderOperationHandler, FolderOperationHandlers, View}; +use flowy_folder::view_operation::{ + FolderOperationHandler, FolderOperationHandlers, View, ViewData, +}; use flowy_folder::ViewLayout; use flowy_folder_pub::folder_builder::NestedViewBuilder; use flowy_search::folder::indexer::FolderIndexManagerImpl; @@ -35,12 +37,17 @@ impl FolderDepsResolver { collab_builder: Arc<AppFlowyCollabBuilder>, server_provider: Arc<ServerProvider>, folder_indexer: Arc<FolderIndexManagerImpl>, + chat_manager: &Arc<ChatManager>, ) -> Arc<FolderManager> { let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl { authenticate_user: authenticate_user.clone(), }); - let handlers = folder_operation_handlers(document_manager.clone(), database_manager.clone()); + let handlers = folder_operation_handlers( + document_manager.clone(), + database_manager.clone(), + chat_manager.clone(), + ); Arc::new( FolderManager::new( user.clone(), @@ -58,6 +65,7 @@ impl FolderDepsResolver { fn folder_operation_handlers( document_manager: Arc<DocumentManager>, database_manager: Arc<DatabaseManager>, + chat_manager: Arc<ChatManager>, ) -> FolderOperationHandlers { let mut map: HashMap<ViewLayout, Arc<dyn FolderOperationHandler + Send + Sync>> = HashMap::new(); @@ -65,9 +73,11 @@ fn folder_operation_handlers( map.insert(ViewLayout::Document, document_folder_operation); let database_folder_operation = Arc::new(DatabaseFolderOperation(database_manager)); + let chat_folder_operation = Arc::new(ChatFolderOperation(chat_manager)); map.insert(ViewLayout::Board, database_folder_operation.clone()); map.insert(ViewLayout::Grid, database_folder_operation.clone()); map.insert(ViewLayout::Calendar, database_folder_operation); + map.insert(ViewLayout::Chat, chat_folder_operation); Arc::new(map) } @@ -315,7 +325,15 @@ impl FolderOperationHandler for DatabaseFolderOperation { }, Some(params) => { let database_manager = self.0.clone(); - let layout = layout_type_from_view_layout(layout.into()); + + let layout = match layout { + ViewLayout::Board => DatabaseLayoutPB::Board, + ViewLayout::Calendar => DatabaseLayoutPB::Calendar, + ViewLayout::Grid => DatabaseLayoutPB::Grid, + ViewLayout::Document | ViewLayout::Chat => { + return FutureResult::new(async move { Err(FlowyError::not_support()) }); + }, + }; let name = name.to_string(); let database_view_id = view_id.to_string(); @@ -351,6 +369,10 @@ impl FolderOperationHandler for DatabaseFolderOperation { Err(FlowyError::internal().with_context(format!("Can't handle {:?} layout type", layout))) }); }, + ViewLayout::Chat => { + // TODO(nathan): AI + todo!("AI") + }, }; FutureResult::new(async move { let result = database_manager.create_database_with_params(data).await; @@ -413,7 +435,7 @@ impl FolderOperationHandler for DatabaseFolderOperation { fn did_update_view(&self, old: &View, new: &View) -> FutureResult<(), FlowyError> { let database_layout = match new.layout { - ViewLayout::Document => { + ViewLayout::Document | ViewLayout::Chat => { return FutureResult::new(async { Err(FlowyError::internal().with_context("Can't handle document layout type")) }); @@ -450,11 +472,83 @@ impl CreateDatabaseExtParams { } } -pub fn layout_type_from_view_layout(layout: ViewLayoutPB) -> DatabaseLayoutPB { - match layout { - ViewLayoutPB::Grid => DatabaseLayoutPB::Grid, - ViewLayoutPB::Board => DatabaseLayoutPB::Board, - ViewLayoutPB::Calendar => DatabaseLayoutPB::Calendar, - ViewLayoutPB::Document => DatabaseLayoutPB::Grid, +struct ChatFolderOperation(Arc<ChatManager>); +impl FolderOperationHandler for ChatFolderOperation { + fn open_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + manager.open_chat(&view_id).await?; + Ok(()) + }) + } + + fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + manager.close_chat(&view_id).await?; + Ok(()) + }) + } + + fn delete_view(&self, view_id: &str) -> FutureResult<(), FlowyError> { + let manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + manager.delete_chat(&view_id).await?; + Ok(()) + }) + } + + fn duplicate_view(&self, _view_id: &str) -> FutureResult<ViewData, FlowyError> { + FutureResult::new(async move { Err(FlowyError::not_support()) }) + } + + fn create_view_with_view_data( + &self, + _user_id: i64, + _view_id: &str, + _name: &str, + _data: Vec<u8>, + _layout: ViewLayout, + _meta: HashMap<String, String>, + ) -> FutureResult<(), FlowyError> { + FutureResult::new(async move { Err(FlowyError::not_support()) }) + } + + fn create_built_in_view( + &self, + user_id: i64, + view_id: &str, + _name: &str, + _layout: ViewLayout, + ) -> FutureResult<(), FlowyError> { + let manager = self.0.clone(); + let view_id = view_id.to_string(); + FutureResult::new(async move { + manager.create_chat(&user_id, &view_id).await?; + Ok(()) + }) + } + + fn import_from_bytes( + &self, + _uid: i64, + _view_id: &str, + _name: &str, + _import_type: ImportType, + _bytes: Vec<u8>, + ) -> FutureResult<(), FlowyError> { + FutureResult::new(async move { Err(FlowyError::not_support()) }) + } + + fn import_from_file_path( + &self, + _view_id: &str, + _name: &str, + _path: String, + ) -> FutureResult<(), FlowyError> { + FutureResult::new(async move { Err(FlowyError::not_support()) }) } } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs index a93530e519..a75589e89e 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/mod.rs @@ -1,3 +1,4 @@ +pub use chat_deps::*; pub use collab_deps::*; pub use database_deps::*; pub use document_deps::*; @@ -9,6 +10,7 @@ mod collab_deps; mod document_deps; mod folder_deps; +mod chat_deps; mod database_deps; mod search_deps; mod user_deps; diff --git a/frontend/rust-lib/flowy-core/src/integrate/log.rs b/frontend/rust-lib/flowy-core/src/integrate/log.rs index 66c37837d1..c855a557ac 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/log.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/log.rs @@ -52,6 +52,7 @@ pub fn create_log_filter(level: String, with_crates: Vec<String>, platform: Plat filters.push(format!("flowy_notification={}", "info")); filters.push(format!("lib_infra={}", level)); filters.push(format!("flowy_search={}", level)); + filters.push(format!("flowy_chat={}", level)); // Enable the frontend logs. DO NOT DISABLE. // These logs are essential for debugging and verifying frontend behavior. filters.push(format!("dart_ffi={}", level)); diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index a4c3638d41..2e672dec6c 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -3,8 +3,10 @@ use std::sync::Arc; use anyhow::Error; use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin}; - +use client_api::entity::ai_dto::RepeatedRelatedQuestion; +use client_api::entity::ChatMessageType; use collab::core::origin::{CollabClient, CollabOrigin}; + use collab::preclude::CollabPlugin; use collab_entity::CollabType; use collab_plugins::cloud_storage::postgres::SupabaseDBPlugin; @@ -14,6 +16,9 @@ use tracing::debug; use collab_integrate::collab_builder::{ CollabCloudPluginProvider, CollabPluginProviderContext, CollabPluginProviderType, }; +use flowy_chat_pub::cloud::{ + ChatCloudService, ChatMessage, ChatMessageStream, MessageCursor, RepeatedChatMessage, +}; use flowy_database_pub::cloud::{ CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, }; @@ -28,6 +33,7 @@ use flowy_server_pub::supabase_config::SupabaseConfiguration; use flowy_storage::ObjectValue; use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider}; use flowy_user_pub::entities::{Authenticator, UserTokenState}; +use lib_infra::async_trait::async_trait; use lib_infra::future::FutureResult; use crate::integrate::server::{Server, ServerProvider}; @@ -372,7 +378,12 @@ impl CollabCloudPluginProvider for ServerProvider { collab_object.uid, collab_object.device_id.clone(), )); - let sync_object = SyncObject::from(collab_object); + let sync_object = SyncObject::new( + &collab_object.object_id, + &collab_object.workspace_id, + collab_object.collab_type, + &collab_object.device_id, + ); let (sink, stream) = (channel.sink(), channel.stream()); let sink_config = SinkConfig::new().send_timeout(8); let sync_plugin = SyncPlugin::new( @@ -427,3 +438,93 @@ impl CollabCloudPluginProvider for ServerProvider { *self.user_enable_sync.read() } } + +#[async_trait] +impl ChatCloudService for ServerProvider { + fn create_chat( + &self, + uid: &i64, + workspace_id: &str, + chat_id: &str, + ) -> FutureResult<(), FlowyError> { + let workspace_id = workspace_id.to_string(); + let server = self.get_server(); + let chat_id = chat_id.to_string(); + let uid = *uid; + FutureResult::new(async move { + server? + .chat_service() + .create_chat(&uid, &workspace_id, &chat_id) + .await + }) + } + + async fn send_chat_message( + &self, + workspace_id: &str, + chat_id: &str, + message: &str, + message_type: ChatMessageType, + ) -> Result<ChatMessageStream, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let message = message.to_string(); + let server = self.get_server()?; + server + .chat_service() + .send_chat_message(&workspace_id, &chat_id, &message, message_type) + .await + } + + fn get_chat_messages( + &self, + workspace_id: &str, + chat_id: &str, + offset: MessageCursor, + limit: u64, + ) -> FutureResult<RepeatedChatMessage, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let server = self.get_server(); + FutureResult::new(async move { + server? + .chat_service() + .get_chat_messages(&workspace_id, &chat_id, offset, limit) + .await + }) + } + + fn get_related_message( + &self, + workspace_id: &str, + chat_id: &str, + message_id: i64, + ) -> FutureResult<RepeatedRelatedQuestion, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let server = self.get_server(); + FutureResult::new(async move { + server? + .chat_service() + .get_related_message(&workspace_id, &chat_id, message_id) + .await + }) + } + + fn generate_answer( + &self, + workspace_id: &str, + chat_id: &str, + question_message_id: i64, + ) -> FutureResult<ChatMessage, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let server = self.get_server(); + FutureResult::new(async move { + server? + .chat_service() + .generate_answer(&workspace_id, &chat_id, question_message_id) + .await + }) + } +} diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index 2ba29b83fd..80bb1213f5 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -10,6 +10,7 @@ use tokio::sync::RwLock; use tracing::{debug, error, event, info, instrument}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProviderType}; +use flowy_chat::manager::ChatManager; use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager; use flowy_error::{FlowyError, FlowyResult}; @@ -57,6 +58,7 @@ pub struct AppFlowyCore { pub task_dispatcher: Arc<RwLock<TaskDispatcher>>, pub store_preference: Arc<StorePreferences>, pub search_manager: Arc<SearchManager>, + pub chat_manager: Arc<ChatManager>, } impl AppFlowyCore { @@ -137,6 +139,7 @@ impl AppFlowyCore { document_manager, collab_builder, search_manager, + chat_manager, ) = async { /// The shared collab builder is used to build the [Collab] instance. The plugins will be loaded /// on demand based on the [CollabPluginConfig]. @@ -164,6 +167,8 @@ impl AppFlowyCore { Arc::downgrade(&(server_provider.clone() as Arc<dyn ObjectStorageService>)), ); + let chat_manager = + ChatDepsResolver::resolve(Arc::downgrade(&authenticate_user), server_provider.clone()); let folder_indexer = Arc::new(FolderIndexManagerImpl::new(None)); let folder_manager = FolderDepsResolver::resolve( Arc::downgrade(&authenticate_user), @@ -172,6 +177,7 @@ impl AppFlowyCore { collab_builder.clone(), server_provider.clone(), folder_indexer.clone(), + &chat_manager, ) .await; @@ -195,6 +201,7 @@ impl AppFlowyCore { document_manager, collab_builder, search_manager, + chat_manager, ) } .await; @@ -230,6 +237,7 @@ impl AppFlowyCore { Arc::downgrade(&user_manager), Arc::downgrade(&document_manager), Arc::downgrade(&search_manager), + Arc::downgrade(&chat_manager), ), )); @@ -244,6 +252,7 @@ impl AppFlowyCore { task_dispatcher, store_preference, search_manager, + chat_manager, } } diff --git a/frontend/rust-lib/flowy-core/src/module.rs b/frontend/rust-lib/flowy-core/src/module.rs index 8d021955ef..7077007915 100644 --- a/frontend/rust-lib/flowy-core/src/module.rs +++ b/frontend/rust-lib/flowy-core/src/module.rs @@ -1,3 +1,4 @@ +use flowy_chat::manager::ChatManager; use std::sync::Weak; use flowy_database2::DatabaseManager; @@ -13,6 +14,7 @@ pub fn make_plugins( user_session: Weak<UserManager>, document_manager2: Weak<DocumentManager2>, search_manager: Weak<SearchManager>, + chat_manager: Weak<ChatManager>, ) -> Vec<AFPlugin> { let store_preferences = user_session .upgrade() @@ -25,6 +27,7 @@ pub fn make_plugins( let config_plugin = flowy_config::event_map::init(store_preferences); let date_plugin = flowy_date::event_map::init(); let search_plugin = flowy_search::event_map::init(search_manager); + let chat_plugin = flowy_chat::event_map::init(chat_manager); vec![ user_plugin, folder_plugin, @@ -33,5 +36,6 @@ pub fn make_plugins( config_plugin, date_plugin, search_plugin, + chat_plugin, ] } diff --git a/frontend/rust-lib/flowy-document/src/event_handler.rs b/frontend/rust-lib/flowy-document/src/event_handler.rs index c87ed6ec79..029405c6cc 100644 --- a/frontend/rust-lib/flowy-document/src/event_handler.rs +++ b/frontend/rust-lib/flowy-document/src/event_handler.rs @@ -56,6 +56,8 @@ pub(crate) async fn open_document_handler( let manager = upgrade_document(manager)?; let params: OpenDocumentParams = data.into_inner().try_into()?; let doc_id = params.document_id; + manager.open_document(&doc_id).await?; + let document = manager.get_document(&doc_id).await?; let document_data = document.lock().get_document_data()?; data_result_ok(DocumentDataPB::from(document_data)) diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index 06639257d4..fb3b203b4e 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -77,7 +77,9 @@ impl DocumentManager { } pub async fn initialize(&self, _uid: i64) -> FlowyResult<()> { + trace!("initialize document manager"); self.documents.clear(); + self.removing_documents.clear(); Ok(()) } @@ -130,9 +132,6 @@ impl DocumentManager { } } - /// Returns Document for given object id - /// If the document does not exist in local disk, try get the doc state from the cloud. - /// If the document exists, open the document and cache it #[tracing::instrument(level = "info", skip(self), err)] pub async fn get_document(&self, doc_id: &str) -> FlowyResult<Arc<MutexDocument>> { if let Some(doc) = self.documents.get(doc_id).map(|item| item.value().clone()) { @@ -142,6 +141,17 @@ impl DocumentManager { if let Some(doc) = self.restore_document_from_removing(doc_id) { return Ok(doc); } + return Err(FlowyError::internal().with_context("Call open document first")); + } + + /// Returns Document for given object id + /// If the document does not exist in local disk, try get the doc state from the cloud. + /// If the document exists, open the document and cache it + #[tracing::instrument(level = "info", skip(self), err)] + async fn create_document_instance(&self, doc_id: &str) -> FlowyResult<Arc<MutexDocument>> { + if let Some(doc) = self.documents.get(doc_id).map(|item| item.value().clone()) { + return Ok(doc); + } let mut doc_state = DataSource::Disk; // If the document does not exist in local disk, try get the doc state from the cloud. This happens @@ -164,7 +174,12 @@ impl DocumentManager { } let uid = self.user_service.user_id()?; - event!(tracing::Level::DEBUG, "Initialize document: {}", doc_id); + event!( + tracing::Level::DEBUG, + "Initialize document: {}, workspace_id: {:?}", + doc_id, + self.user_service.workspace_id() + ); let collab = self .collab_for_document(uid, doc_id, doc_state, true) .await?; @@ -209,6 +224,8 @@ impl DocumentManager { if let Some(mutex_document) = self.restore_document_from_removing(doc_id) { mutex_document.start_init_sync(); } + + let _ = self.create_document_instance(doc_id).await?; Ok(()) } @@ -247,6 +264,7 @@ impl DocumentManager { Ok(()) } + #[instrument(level = "debug", skip_all, err)] pub async fn set_document_awareness_local_state( &self, doc_id: &str, diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 466d30d06d..d5945ccaa3 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -60,6 +60,18 @@ pub struct ViewPB { #[pb(index = 9, one_of)] pub extra: Option<String>, + + // user_id + #[pb(index = 10, one_of)] + pub created_by: Option<i64>, + + // timestamp + #[pb(index = 11)] + pub last_edited: i64, + + // user_id + #[pb(index = 12, one_of)] + pub last_edited_by: Option<i64>, } pub fn view_pb_without_child_views(view: View) -> ViewPB { @@ -73,6 +85,9 @@ pub fn view_pb_without_child_views(view: View) -> ViewPB { icon: view.icon.clone().map(|icon| icon.into()), is_favorite: view.is_favorite, extra: view.extra, + created_by: view.created_by, + last_edited: view.last_edited_time, + last_edited_by: view.last_edited_by, } } @@ -87,6 +102,9 @@ pub fn view_pb_without_child_views_from_arc(view: Arc<View>) -> ViewPB { icon: view.icon.clone().map(|icon| icon.into()), is_favorite: view.is_favorite, extra: view.extra.clone(), + created_by: view.created_by, + last_edited: view.last_edited_time, + last_edited_by: view.last_edited_by, } } @@ -105,6 +123,9 @@ pub fn view_pb_with_child_views(view: Arc<View>, child_views: Vec<Arc<View>>) -> icon: view.icon.clone().map(|icon| icon.into()), is_favorite: view.is_favorite, extra: view.extra.clone(), + created_by: view.created_by, + last_edited: view.last_edited_time, + last_edited_by: view.last_edited_by, } } @@ -115,6 +136,7 @@ pub enum ViewLayoutPB { Grid = 1, Board = 2, Calendar = 3, + Chat = 4, } impl ViewLayoutPB { @@ -133,6 +155,7 @@ impl std::convert::From<ViewLayout> for ViewLayoutPB { ViewLayout::Board => ViewLayoutPB::Board, ViewLayout::Document => ViewLayoutPB::Document, ViewLayout::Calendar => ViewLayoutPB::Calendar, + ViewLayout::Chat => ViewLayoutPB::Chat, } } } @@ -155,11 +178,17 @@ pub struct RepeatedViewPB { #[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)] pub struct RepeatedFavoriteViewPB { #[pb(index = 1)] - pub items: Vec<FavoriteViewPB>, + pub items: Vec<SectionViewPB>, } #[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)] -pub struct FavoriteViewPB { +pub struct RepeatedRecentViewPB { + #[pb(index = 1)] + pub items: Vec<SectionViewPB>, +} + +#[derive(Eq, PartialEq, Debug, Default, ProtoBuf, Clone)] +pub struct SectionViewPB { #[pb(index = 1)] pub item: ViewPB, #[pb(index = 2)] diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index 06daab5a2f..888c26d2a6 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -284,7 +284,7 @@ pub(crate) async fn read_favorites_handler( let mut views = vec![]; for item in favorite_items { if let Ok(view) = folder.get_view_pb(&item.id).await { - views.push(FavoriteViewPB { + views.push(SectionViewPB { item: view, timestamp: item.timestamp, }); @@ -296,16 +296,19 @@ pub(crate) async fn read_favorites_handler( #[tracing::instrument(level = "debug", skip(folder), err)] pub(crate) async fn read_recent_views_handler( folder: AFPluginState<Weak<FolderManager>>, -) -> DataResult<RepeatedViewPB, FlowyError> { +) -> DataResult<RepeatedRecentViewPB, FlowyError> { let folder = upgrade_folder(folder)?; let recent_items = folder.get_my_recent_sections().await; let mut views = vec![]; for item in recent_items { if let Ok(view) = folder.get_view_pb(&item.id).await { - views.push(view); + views.push(SectionViewPB { + item: view, + timestamp: item.timestamp, + }); } } - data_result_ok(RepeatedViewPB { items: views }) + data_result_ok(RepeatedRecentViewPB { items: views }) } #[tracing::instrument(level = "debug", skip(folder), err)] diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 2901d19a63..febfc49b5e 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -155,7 +155,7 @@ pub enum FolderEvent { #[event(input = "UpdateViewIconPayloadPB")] UpdateViewIcon = 35, - #[event(output = "RepeatedViewPB")] + #[event(output = "RepeatedRecentViewPB")] ReadRecentViews = 36, // used for add or remove recent views, like history diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 35d2ffc72b..b3a8f6a1f3 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -796,7 +796,10 @@ impl FolderManager { if let Some(view) = &view { let view_layout: ViewLayout = view.layout.clone().into(); if let Some(handle) = self.operation_handlers.get(&view_layout) { - let _ = handle.open_view(view_id).await; + info!("Open view: {}", view.id); + if let Err(err) = handle.open_view(view_id).await { + error!("Open view error: {:?}", err); + } } } diff --git a/frontend/rust-lib/flowy-folder/src/view_operation.rs b/frontend/rust-lib/flowy-folder/src/view_operation.rs index c5dfcf6007..10d173394c 100644 --- a/frontend/rust-lib/flowy-folder/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder/src/view_operation.rs @@ -115,6 +115,7 @@ impl From<ViewLayoutPB> for ViewLayout { ViewLayoutPB::Grid => ViewLayout::Grid, ViewLayoutPB::Board => ViewLayout::Board, ViewLayoutPB::Calendar => ViewLayout::Calendar, + ViewLayoutPB::Chat => ViewLayout::Chat, } } } diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml index b71776b02b..bb16b35cdb 100644 --- a/frontend/rust-lib/flowy-server/Cargo.toml +++ b/frontend/rust-lib/flowy-server/Cargo.toml @@ -42,6 +42,7 @@ flowy-error = { workspace = true, features = ["impl_from_serde", "impl_from_reqw flowy-server-pub = { workspace = true } flowy-encrypt = { workspace = true } flowy-storage = { workspace = true } +flowy-chat-pub = { workspace = true } mime_guess = "2.0" url = "2.4" tokio-util = "0.7" diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs new file mode 100644 index 0000000000..cc484a9346 --- /dev/null +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/chat.rs @@ -0,0 +1,128 @@ +use crate::af_cloud::AFServer; +use client_api::entity::ai_dto::RepeatedRelatedQuestion; +use client_api::entity::{ + CreateChatMessageParams, CreateChatParams, MessageCursor, RepeatedChatMessage, +}; +use flowy_chat_pub::cloud::{ChatCloudService, ChatMessage, ChatMessageStream, ChatMessageType}; +use flowy_error::FlowyError; +use futures_util::StreamExt; +use lib_infra::async_trait::async_trait; +use lib_infra::future::FutureResult; + +pub(crate) struct AFCloudChatCloudServiceImpl<T> { + pub inner: T, +} + +#[async_trait] +impl<T> ChatCloudService for AFCloudChatCloudServiceImpl<T> +where + T: AFServer, +{ + fn create_chat( + &self, + _uid: &i64, + workspace_id: &str, + chat_id: &str, + ) -> FutureResult<(), FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let try_get_client = self.inner.try_get_client(); + + FutureResult::new(async move { + let params = CreateChatParams { + chat_id, + name: "".to_string(), + rag_ids: vec![], + }; + try_get_client? + .create_chat(&workspace_id, params) + .await + .map_err(FlowyError::from)?; + + Ok(()) + }) + } + + async fn send_chat_message( + &self, + workspace_id: &str, + chat_id: &str, + message: &str, + message_type: ChatMessageType, + ) -> Result<ChatMessageStream, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let message = message.to_string(); + let try_get_client = self.inner.try_get_client(); + let params = CreateChatMessageParams { + content: message, + message_type, + }; + let stream = try_get_client? + .create_chat_message(&workspace_id, &chat_id, params) + .await + .map_err(FlowyError::from)?; + + Ok(stream.boxed()) + } + + fn get_chat_messages( + &self, + workspace_id: &str, + chat_id: &str, + offset: MessageCursor, + limit: u64, + ) -> FutureResult<RepeatedChatMessage, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let try_get_client = self.inner.try_get_client(); + + FutureResult::new(async move { + let resp = try_get_client? + .get_chat_messages(&workspace_id, &chat_id, offset, limit) + .await + .map_err(FlowyError::from)?; + + Ok(resp) + }) + } + + fn get_related_message( + &self, + workspace_id: &str, + chat_id: &str, + message_id: i64, + ) -> FutureResult<RepeatedRelatedQuestion, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let try_get_client = self.inner.try_get_client(); + + FutureResult::new(async move { + let resp = try_get_client? + .get_chat_related_question(&workspace_id, &chat_id, message_id) + .await + .map_err(FlowyError::from)?; + + Ok(resp) + }) + } + + fn generate_answer( + &self, + workspace_id: &str, + chat_id: &str, + question_message_id: i64, + ) -> FutureResult<ChatMessage, FlowyError> { + let workspace_id = workspace_id.to_string(); + let chat_id = chat_id.to_string(); + let try_get_client = self.inner.try_get_client(); + + FutureResult::new(async move { + let resp = try_get_client? + .generate_question_answer(&workspace_id, &chat_id, question_message_id) + .await + .map_err(FlowyError::from)?; + Ok(resp) + }) + } +} diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs index 6b2a67c67b..ea995b7b1e 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs @@ -42,10 +42,7 @@ where FutureResult::new(async move { let params = QueryCollabParams { workspace_id: workspace_id.clone(), - inner: QueryCollab { - object_id: object_id.clone(), - collab_type: collab_type.clone(), - }, + inner: QueryCollab::new(object_id.clone(), collab_type.clone()), }; match try_get_client?.get_collab(params).await { Ok(data) => { @@ -81,10 +78,7 @@ where let client = try_get_client?; let params = object_ids .into_iter() - .map(|object_id| QueryCollab { - object_id, - collab_type: object_ty.clone(), - }) + .map(|object_id| QueryCollab::new(object_id, object_ty.clone())) .collect(); let results = client.batch_get_collab(&workspace_id, params).await?; check_request_workspace_id_is_match( diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs index c5d88ba15c..98732aa521 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs @@ -37,10 +37,7 @@ where FutureResult::new(async move { let params = QueryCollabParams { workspace_id: workspace_id.clone(), - inner: QueryCollab { - object_id: document_id.to_string(), - collab_type: CollabType::Document, - }, + inner: QueryCollab::new(document_id.to_string(), CollabType::Document), }; let doc_state = try_get_client? .get_collab(params) @@ -82,10 +79,7 @@ where FutureResult::new(async move { let params = QueryCollabParams { workspace_id: workspace_id.clone(), - inner: QueryCollab { - object_id: document_id.clone(), - collab_type: CollabType::Document, - }, + inner: QueryCollab::new(document_id.clone(), CollabType::Document), }; let doc_state = try_get_client? .get_collab(params) diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs index c33569aea8..fe58f3fc16 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs @@ -93,10 +93,7 @@ where FutureResult::new(async move { let params = QueryCollabParams { workspace_id: workspace_id.clone(), - inner: QueryCollab { - object_id: workspace_id.clone(), - collab_type: CollabType::Folder, - }, + inner: QueryCollab::new(workspace_id.clone(), CollabType::Folder), }; let doc_state = try_get_client? .get_collab(params) @@ -140,10 +137,7 @@ where FutureResult::new(async move { let params = QueryCollabParams { workspace_id: workspace_id.clone(), - inner: QueryCollab { - object_id, - collab_type, - }, + inner: QueryCollab::new(object_id, collab_type), }; let doc_state = try_get_client? .get_collab(params) @@ -167,10 +161,12 @@ where FutureResult::new(async move { let params = objects .into_iter() - .map(|object| CollabParams { - object_id: object.object_id, - encoded_collab_v1: object.encoded_collab_v1, - collab_type: object.collab_type, + .map(|object| { + CollabParams::new( + object.object_id, + object.collab_type, + object.encoded_collab_v1, + ) }) .collect::<Vec<_>>(); try_get_client? diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/mod.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/mod.rs index 3ecd839109..37ad00781c 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/mod.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/mod.rs @@ -1,9 +1,11 @@ +pub(crate) use chat::*; pub(crate) use database::*; pub(crate) use document::*; pub(crate) use file_storage::*; pub(crate) use folder::*; pub(crate) use user::*; +mod chat; mod database; mod document; mod file_storage; diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index ff4e065bc3..aea737007d 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -353,10 +353,7 @@ where FutureResult::new(async move { let params = QueryCollabParams { workspace_id: workspace_id.clone(), - inner: QueryCollab { - object_id, - collab_type: CollabType::UserAwareness, - }, + inner: QueryCollab::new(object_id, CollabType::UserAwareness), }; let resp = try_get_client?.get_collab(params).await?; check_request_workspace_id_is_match( @@ -386,10 +383,10 @@ where FutureResult::new(async move { let client = try_get_client?; let params = CreateCollabParams { - workspace_id: collab_object.workspace_id.clone(), - object_id: collab_object.object_id.clone(), + workspace_id: collab_object.workspace_id, + object_id: collab_object.object_id, + collab_type: collab_object.collab_type, encoded_collab_v1: data, - collab_type: collab_object.collab_type.clone(), }; client.create_collab(params).await?; Ok(()) @@ -406,10 +403,12 @@ where FutureResult::new(async move { let params = objects .into_iter() - .map(|object| CollabParams { - object_id: object.object_id, - encoded_collab_v1: object.encoded_collab, - collab_type: object.collab_type, + .map(|object| { + CollabParams::new( + object.object_id, + u8::from(object.collab_type).into(), + object.encoded_collab, + ) }) .collect::<Vec<_>>(); try_get_client? diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs index c24ddbb51e..a33852dd53 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/dto.rs @@ -89,6 +89,7 @@ pub fn from_af_workspace_member(member: AFWorkspaceMember) -> WorkspaceMember { email: member.email, role: from_af_role(member.role), name: member.name, + avatar_url: member.avatar_url, } } diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index c758be253a..e5fb800039 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -10,6 +10,7 @@ use client_api::ws::{ ConnectState, WSClient, WSClientConfig, WSConnectStateReceiver, WebSocketChannel, }; use client_api::{Client, ClientConfiguration}; +use flowy_chat_pub::cloud::ChatCloudService; use flowy_storage::ObjectStorageService; use rand::Rng; use semver::Version; @@ -31,9 +32,10 @@ use flowy_user_pub::entities::UserTokenState; use lib_dispatch::prelude::af_spawn; use crate::af_cloud::impls::{ - AFCloudDatabaseCloudServiceImpl, AFCloudDocumentCloudServiceImpl, AFCloudFileStorageServiceImpl, - AFCloudFolderCloudServiceImpl, AFCloudUserAuthServiceImpl, + AFCloudChatCloudServiceImpl, AFCloudDatabaseCloudServiceImpl, AFCloudDocumentCloudServiceImpl, + AFCloudFileStorageServiceImpl, AFCloudFolderCloudServiceImpl, AFCloudUserAuthServiceImpl, }; + use crate::AppFlowyServer; pub(crate) type AFCloudClient = Client; @@ -214,6 +216,13 @@ impl AppFlowyServer for AppFlowyCloudServer { }) } + fn chat_service(&self) -> Arc<dyn ChatCloudService> { + let server = AFServerImpl { + client: self.get_client(), + }; + Arc::new(AFCloudChatCloudServiceImpl { inner: server }) + } + fn subscribe_ws_state(&self) -> Option<WSConnectStateReceiver> { Some(self.ws_client.subscribe_connect_state()) } diff --git a/frontend/rust-lib/flowy-server/src/default_impl.rs b/frontend/rust-lib/flowy-server/src/default_impl.rs new file mode 100644 index 0000000000..654bffcb1c --- /dev/null +++ b/frontend/rust-lib/flowy-server/src/default_impl.rs @@ -0,0 +1,66 @@ +use client_api::entity::ai_dto::RepeatedRelatedQuestion; +use client_api::entity::{ChatMessageType, MessageCursor, RepeatedChatMessage}; +use flowy_chat_pub::cloud::{ChatCloudService, ChatMessage, ChatMessageStream}; +use flowy_error::FlowyError; +use lib_infra::async_trait::async_trait; +use lib_infra::future::FutureResult; + +pub(crate) struct DefaultChatCloudServiceImpl; + +#[async_trait] +impl ChatCloudService for DefaultChatCloudServiceImpl { + fn create_chat( + &self, + _uid: &i64, + _workspace_id: &str, + _chat_id: &str, + ) -> FutureResult<(), FlowyError> { + FutureResult::new(async move { + Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) + }) + } + + async fn send_chat_message( + &self, + _workspace_id: &str, + _chat_id: &str, + _message: &str, + _message_type: ChatMessageType, + ) -> Result<ChatMessageStream, FlowyError> { + Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) + } + + fn get_chat_messages( + &self, + _workspace_id: &str, + _chat_id: &str, + _offset: MessageCursor, + _limit: u64, + ) -> FutureResult<RepeatedChatMessage, FlowyError> { + FutureResult::new(async move { + Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) + }) + } + + fn get_related_message( + &self, + _workspace_id: &str, + _chat_id: &str, + _message_id: i64, + ) -> FutureResult<RepeatedRelatedQuestion, FlowyError> { + FutureResult::new(async move { + Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) + }) + } + + fn generate_answer( + &self, + _workspace_id: &str, + _chat_id: &str, + _question_message_id: i64, + ) -> FutureResult<ChatMessage, FlowyError> { + FutureResult::new(async move { + Err(FlowyError::not_support().with_context("Chat is not supported in local server.")) + }) + } +} diff --git a/frontend/rust-lib/flowy-server/src/lib.rs b/frontend/rust-lib/flowy-server/src/lib.rs index 4e647f4210..704e9e0e49 100644 --- a/frontend/rust-lib/flowy-server/src/lib.rs +++ b/frontend/rust-lib/flowy-server/src/lib.rs @@ -8,4 +8,5 @@ mod server; #[cfg(feature = "enable_supabase")] pub mod supabase; +mod default_impl; pub mod util; diff --git a/frontend/rust-lib/flowy-server/src/server.rs b/frontend/rust-lib/flowy-server/src/server.rs index 679771d162..70a8e4b9a8 100644 --- a/frontend/rust-lib/flowy-server/src/server.rs +++ b/frontend/rust-lib/flowy-server/src/server.rs @@ -6,11 +6,13 @@ use std::sync::Arc; use anyhow::Error; use client_api::collab_sync::ServerCollabMessage; +use flowy_chat_pub::cloud::ChatCloudService; use parking_lot::RwLock; use tokio_stream::wrappers::WatchStream; #[cfg(feature = "enable_supabase")] use {collab_entity::CollabObject, collab_plugins::cloud_storage::RemoteCollabStorage}; +use crate::default_impl::DefaultChatCloudServiceImpl; use flowy_database_pub::cloud::DatabaseCloudService; use flowy_document_pub::cloud::DocumentCloudService; use flowy_folder_pub::cloud::FolderCloudService; @@ -94,6 +96,10 @@ pub trait AppFlowyServer: Send + Sync + 'static { /// An `Arc` wrapping the `DocumentCloudService` interface. fn document_service(&self) -> Arc<dyn DocumentCloudService>; + fn chat_service(&self) -> Arc<dyn ChatCloudService> { + Arc::new(DefaultChatCloudServiceImpl) + } + /// Manages collaborative objects within a remote storage system. This includes operations such as /// checking storage status, retrieving updates and snapshots, and dispatching updates. The service /// also provides subscription capabilities for real-time updates. diff --git a/frontend/rust-lib/flowy-sqlite/migrations/2024-05-23-061639_chat_message/down.sql b/frontend/rust-lib/flowy-sqlite/migrations/2024-05-23-061639_chat_message/down.sql new file mode 100644 index 0000000000..943e78adf2 --- /dev/null +++ b/frontend/rust-lib/flowy-sqlite/migrations/2024-05-23-061639_chat_message/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +drop table chat_table; +drop table chat_message_table; \ No newline at end of file diff --git a/frontend/rust-lib/flowy-sqlite/migrations/2024-05-23-061639_chat_message/up.sql b/frontend/rust-lib/flowy-sqlite/migrations/2024-05-23-061639_chat_message/up.sql new file mode 100644 index 0000000000..192e7cf763 --- /dev/null +++ b/frontend/rust-lib/flowy-sqlite/migrations/2024-05-23-061639_chat_message/up.sql @@ -0,0 +1,20 @@ +-- Create table for chat documents +CREATE TABLE chat_table +( + chat_id TEXT PRIMARY KEY NOT NULL, + created_at BIGINT NOT NULL, + name TEXT NOT NULL DEFAULT '' +); + +-- Create table for chat messages +CREATE TABLE chat_message_table +( + message_id BIGINT PRIMARY KEY NOT NULL, + chat_id TEXT NOT NULL, + content TEXT NOT NULL, + created_at BIGINT NOT NULL, + author_type BIGINT NOT NULL, + author_id TEXT NOT NULL, + reply_message_id BIGINT +); +CREATE INDEX idx_chat_messages_chat_id_message_id ON chat_message_table (chat_id, message_id); diff --git a/frontend/rust-lib/flowy-sqlite/src/schema.rs b/frontend/rust-lib/flowy-sqlite/src/schema.rs index 37c2ff8bbd..24290ea5d8 100644 --- a/frontend/rust-lib/flowy-sqlite/src/schema.rs +++ b/frontend/rust-lib/flowy-sqlite/src/schema.rs @@ -1,5 +1,25 @@ // @generated automatically by Diesel CLI. +diesel::table! { + chat_message_table (message_id) { + message_id -> BigInt, + chat_id -> Text, + content -> Text, + created_at -> BigInt, + author_type -> BigInt, + author_id -> Text, + reply_message_id -> Nullable<BigInt>, + } +} + +diesel::table! { + chat_table (chat_id) { + chat_id -> Text, + created_at -> BigInt, + name -> Text, + } +} + diesel::table! { collab_snapshot (id) { id -> Text, @@ -48,8 +68,10 @@ diesel::table! { } diesel::allow_tables_to_appear_in_same_query!( - collab_snapshot, - user_data_migration_records, - user_table, - user_workspace_table, + chat_message_table, + chat_table, + collab_snapshot, + user_data_migration_records, + user_table, + user_workspace_table, ); diff --git a/frontend/rust-lib/flowy-user-pub/src/entities.rs b/frontend/rust-lib/flowy-user-pub/src/entities.rs index 0d01f47eb5..b06e67c9da 100644 --- a/frontend/rust-lib/flowy-user-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-user-pub/src/entities.rs @@ -395,6 +395,7 @@ pub struct WorkspaceMember { pub email: String, pub role: Role, pub name: String, + pub avatar_url: Option<String>, } /// represent the user awareness object id for the workspace. diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index c6435531f3..cee388e77b 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -170,6 +170,7 @@ fn sync_view( } } }, + ViewLayout::Chat => {}, } tokio::task::yield_now().await; @@ -357,6 +358,7 @@ fn collab_type_from_view_layout(view_layout: &ViewLayout) -> CollabType { match view_layout { ViewLayout::Document => CollabType::Document, ViewLayout::Grid | ViewLayout::Board | ViewLayout::Calendar => CollabType::Database, + ViewLayout::Chat => CollabType::Unknown, } } diff --git a/frontend/rust-lib/flowy-user/src/entities/workspace.rs b/frontend/rust-lib/flowy-user/src/entities/workspace.rs index d410c2bb3c..5073dc9cc1 100644 --- a/frontend/rust-lib/flowy-user/src/entities/workspace.rs +++ b/frontend/rust-lib/flowy-user/src/entities/workspace.rs @@ -17,6 +17,9 @@ pub struct WorkspaceMemberPB { #[pb(index = 3)] pub role: AFRolePB, + + #[pb(index = 4, one_of)] + pub avatar_url: Option<String>, } impl From<WorkspaceMember> for WorkspaceMemberPB { @@ -25,6 +28,7 @@ impl From<WorkspaceMember> for WorkspaceMemberPB { email: value.email, name: value.name, role: value.role.into(), + avatar_url: value.avatar_url, } } } diff --git a/frontend/scripts/docker-buildfiles/Dockerfile b/frontend/scripts/docker-buildfiles/Dockerfile index 8aad410e94..8ebe5fc8ef 100644 --- a/frontend/scripts/docker-buildfiles/Dockerfile +++ b/frontend/scripts/docker-buildfiles/Dockerfile @@ -48,7 +48,7 @@ RUN dart pub global activate protoc_plugin 21.1.2 # Install build dependencies for AppFlowy RUN yay -S --noconfirm jemalloc4 cargo-make cargo-binstall -RUN sudo pacman -S --noconfirm git libkeybinder3 sqlite clang rsync libnotify rocksdb zstd +RUN sudo pacman -S --noconfirm git libkeybinder3 sqlite clang rsync libnotify rocksdb zstd mpv RUN sudo ln -s /usr/bin/sha1sum /usr/bin/shasum RUN source ~/.cargo/env && cargo binstall duckscript_cli -y diff --git a/frontend/scripts/install_dev_env/install_linux.sh b/frontend/scripts/install_dev_env/install_linux.sh index 22b491321b..b02b31d62c 100755 --- a/frontend/scripts/install_dev_env/install_linux.sh +++ b/frontend/scripts/install_dev_env/install_linux.sh @@ -78,7 +78,17 @@ if command apt-get &>/dev/null; then elif command dnf &>/dev/null; then sudo dnf install libnotify-dev else - echo 'Your system is not supported, please install libnotify manually.' + echo 'Your system is not supported, please install libnotify-dev manually.' +fi + +# For Video Block support +printMessage "Installing libmpv-dev mpv" +if command apt-get &>/dev/null; then + sudo apt-get install libmpv-dev mpv +elif command dnf &>/dev/null; then + sudo dnf install libmpv-dev mpv +else + echo 'Your system is not supported, please install libmpv-dev mpv manually.' fi # Add the githooks directory to your git configuration diff --git a/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml b/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml index c205814401..a0da34dec9 100644 --- a/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml +++ b/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml @@ -19,47 +19,56 @@ AppDir: exec_args: $@ apt: arch: - - amd64 + - amd64 allow_unauthenticated: true sources: - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy main restricted - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-updates main restricted - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy universe - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-updates universe - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy multiverse - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-updates multiverse - - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-backports main restricted - universe multiverse - - sourceline: deb http://security.ubuntu.com/ubuntu jammy-security main restricted - - sourceline: deb http://security.ubuntu.com/ubuntu jammy-security universe - - sourceline: deb http://security.ubuntu.com/ubuntu jammy-security multiverse - - sourceline: deb https://ppa.launchpadcontent.net/touchegg/stable/ubuntu/ jammy - main - - sourceline: deb https://packagecloud.io/slacktechnologies/slack/debian/ jessie - main - - sourceline: deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] - https://cli.github.com/packages stable main - - sourceline: deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x - jammy main - - sourceline: deb [arch=amd64,arm64,armhf] http://packages.microsoft.com/repos/code - stable main - - sourceline: deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable - main + - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy main restricted + - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-updates main restricted + - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy universe + - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-updates universe + - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy multiverse + - sourceline: deb http://id.archive.ubuntu.com/ubuntu/ jammy-updates multiverse + - sourceline: + deb http://id.archive.ubuntu.com/ubuntu/ jammy-backports main restricted + universe multiverse + - sourceline: deb http://security.ubuntu.com/ubuntu jammy-security main restricted + - sourceline: deb http://security.ubuntu.com/ubuntu jammy-security universe + - sourceline: deb http://security.ubuntu.com/ubuntu jammy-security multiverse + - sourceline: + deb https://ppa.launchpadcontent.net/touchegg/stable/ubuntu/ jammy + main + - sourceline: + deb https://packagecloud.io/slacktechnologies/slack/debian/ jessie + main + - sourceline: + deb [arch=amd64 signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] + https://cli.github.com/packages stable main + - sourceline: + deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x + jammy main + - sourceline: + deb [arch=amd64,arm64,armhf] http://packages.microsoft.com/repos/code + stable main + - sourceline: + deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable + main include: - - libc6:amd64 - - libnotify4:amd64 - - libkeybinder-3.0-0:amd64 - - libwayland-cursor0:amd64 - - libwayland-client0:amd64 - - libwayland-egl1:amd64 + - libc6:amd64 + - libnotify4:amd64 + - libkeybinder-3.0-0:amd64 + - libwayland-cursor0:amd64 + - libwayland-client0:amd64 + - libwayland-egl1:amd64 + - libmpv-dev:amd64 + - mpv:amd64 files: include: [] exclude: - - usr/share/man - - usr/share/doc/*/README.* - - usr/share/doc/*/changelog.* - - usr/share/doc/*/NEWS.* - - usr/share/doc/*/TODO.* + - usr/share/man + - usr/share/doc/*/README.* + - usr/share/doc/*/changelog.* + - usr/share/doc/*/NEWS.* + - usr/share/doc/*/TODO.* test: fedora-30: image: appimagecrafters/tests-env:fedora-30 @@ -78,4 +87,4 @@ AppDir: command: ./AppRun AppImage: arch: x86_64 - update-information: guess \ No newline at end of file + update-information: guess